Schleuder 5.0.0 安装指南:Debian 12 上的 apt 与 gem 双方案实测

在 Debian 12 双容器上完整实测 Schleuder 两条安装路线:apt 装发行版 4.0.3 与 gem 编译官方 5.0.0,覆盖初始化、systemd、API 探活,沉淀 IPv6 卡源、charlock_holmes、libcurl、eventmachine TLS 崩溃等 5 个真实坑的修复方案。

Schleuder邮件列表端到端加密Ruby隐私安全2026/10/26

Schleuder 5.0.0 安装指南:Debian 12 上的 apt 与 gem 双方案实测

目标:在同一台 Debian 12 环境上,把 Schleuder 的两条官方安装路线——Debian 仓库的 apt 包与 RubyGems 的官方 gem——各完整走一遍,记录真实命令、真实输出与真实踩坑,给出可直接复用的安装清单与排错方法。认知与选型背景见本专栏《Schleuder 5.0.0 介绍与选型指南》。

一、实测环境

两条路线各用一台干净的 Debian 12 容器完成,互不污染;另有一台 MailHog 容器充当测试邮件出口。所有命令与输出均为 2026-10-26 实测。

环境项apt 方案容器gem 方案容器
操作系统Debian 12.15(bookworm)Debian 12.15(bookworm)
Ruby由 apt 依赖自动安装ruby 3.1.2p20 / gem 3.3.15
安装方式apt-get install schleudergem install schleuder -v 5.0.0
安装版本4.0.3-7+deb12u15.0.0(2024-11-13 发布的最新版)
装后软件包总数227 个(apt 全依赖链)gem 12 个 + 手工构建依赖
网络独立 bridge 网络(10.89.60.0/24)同左
测试 MTAMailHog(SMTP 25 端口收信)同左

💡 版本差异是两条路线最本质的区别:Debian 12 仓库打的是 4.0.3(Debian 打包策略保守,追稳定),gem 源装的是 5.0.0(官方最新)。两个大版本之间的行为变更(如默认拒绝匿名邮件转发等)请先读官方 changes 文档再决定路线——需要 5.x 新行为就走 gem,需要发行版长期补丁就走 apt。

二、方案选择:apt 还是 gem

决策因素apt 方案gem 方案
版本4.0.3(Debian 12)5.0.0(官方最新)
升级方式随发行版安全更新gem update 或锁版本重装
系统集成自带 systemd unit、man 页,开箱即用无 systemd unit,需自建
依赖管理apt 全包托管,卸载干净手工装构建依赖,卸载靠 gem
编译负担零(发行版预编译)需 gcc/gpgme/icu/zlib/ssl 头文件
适合场景生产稳定优先、Debian 服务器需要 5.x 新特性、非 Debian 包可用环境

一句话结论:能接受 4.0.3 就用 apt,一行命令加一个 systemd unit 的事;必须要 5.0.0 就走 gem,但要把本文第四章的三个坑读完再动手。

三、方案一:apt 安装(Debian 官方源,schleuder 4.0.3)

3.1 安装命令

apt-get update
apt-get install -y schleuder

实测输出(节选):

Setting up schleuder (4.0.3-7+deb12u1) ...

Debian 会把 Ruby 解释器与全部 gem 依赖(mail、mail-gpg、gpgme、sinatra、thin、sqlite3 等约 90 个包)作为依赖一并装好,无需手工干预。

⚠️ 容器实测踩坑一:在部分容器/受限网络中,apt-get update 会卡死在 deb.debian.org——因为域名解析出 IPv6 地址而 IPv6 出口不通。解法是强制 apt 走 IPv4:

echo 'Acquire::ForceIPv4 "true";' > /etc/apt/apt.conf.d/99force-ipv4

实测踩坑二:某些镜像站走 HTTPS 时会报 Certificate verification failed: The certificate issuer is unknown(容器内 CA 链不完整),改用 http:// 协议的镜像源即可,或先 apt-get install --reinstall ca-certificates。

3.2 安装产物盘点

dpkg -L schleuder | grep -E 'bin/|systemd|\.yml'

实测关键文件:

/usr/bin/schleuder                  # 主 CLI(MTA 管道入口 + 本地管理命令)
/usr/bin/schleuder-api-daemon       # API 守护进程
/etc/schleuder/schleuder.yml        # 全局主配置
/etc/schleuder/list-defaults.yml    # 新建列表的默认值模板
/lib/systemd/system/schleuder-api-daemon.service   # systemd 单元
/usr/share/schleuder/locales/{en,de}.yml           # 文案

3.3 初始化:schleuder install

安装包只是把文件放好,数据库与 TLS 证书需要一条初始化命令生成:

schleuder install

实测输出:

Database '/var/lib/schleuder/db.sqlite' already exists
NOTE: The database was prepared using sqlite. ...
Private key written to: /etc/schleuder/schleuder-private-key.pem
Certificate written to: /etc/schleuder/schleuder-certificate.pem
Fingerprint of generated certificate: 6412f1448f4f4b3aee7911fbe1d12bc46e8f8be458410a0f653ea4d7a17d3815
Have this fingerprint included into the configuration-file of all clients that want to connect to your Schleuder API.

这条命令做了三件事:

  1. 建 SQLite 数据库 /var/lib/schleuder/db.sqlite(要换 MySQL/PostgreSQL,改 schleuder.yml 的 database 段后重跑本命令);
  2. 生成自签名 TLS 证书(API 是 HTTPS 服务,客户端必须校验该指纹);
  3. 提示权限:以 root 执行时它会警告——/var/lib/schleuder/ 下的数据库与列表目录必须对「实际跑 schleuder-api-daemon 和被 MTA 调用的 schleuder」的那个系统用户可读写(Debian 包默认以 schleuder 用户运行服务)。

3.4 启动 API 守护进程(systemd)

apt 包自带 systemd 单元,直接启用:

systemctl enable --now schleuder-api-daemon

实测确认:

$ systemctl is-active schleuder-api-daemon
active
$ ss -tlnp | grep 4443
LISTEN 0 100 127.0.0.1:4443 0.0.0.0:* users:(("ruby",pid=5137,fd=7))

注意监听地址默认是 127.0.0.1:4443(schleuder.yml 的 api.host 控制)。单机部署(CLI 与 daemon 同机)无需改动;若 schleuder-cli 要从别的机器连,需改 host 并配好防火墙与证书分发。

3.5 验证

两个层次的最小验证:

# 1) CLI 版本
schleuder version
# 实测输出:4.0.3

# 2) API 探活(先在 /etc/schleuder/schleuder.yml 的 valid_api_keys 下加一个 key 并重启服务)
curl -sk -H "X-API-Key: q1w2e3r4-QWERTY-key-0001" https://localhost:4443/status.json
# 实测输出:{"status":"ok"}

/status.json 返回 {"status":"ok"} 即代表「daemon 活着 + TLS 可用 + key 被接受」。至此 apt 方案完成。

四、方案二:gem 安装(官方最新,schleuder 5.0.0)

4.1 构建依赖(一次装齐,避开三个坑)

Schleuder gem 链上有三个原生扩展,缺头文件就会在安装或运行时暴雷。一次装齐以下包:

apt-get install -y ruby-dev build-essential libgpgme-dev libsqlite3-dev \
                   libicu-dev zlib1g-dev libssl-dev libcurl4 pkg-config

实测教训——三个坑对应关系如下:

坑现象缺的包
① charlock_holmes 编译失败gem install 中断,extconf failed, exit code 1,mkmf.log 指向 icu/zlib 检测失败libicu-dev、zlib1g-dev
② 运行时找不到 libcurlschleuder version 报 Could not open library 'libcurl'(typhoeus→ethon 走 FFI 加载 libcurl)libcurl4
③ API daemon 一收到 TLS 握手就崩daemon 能启动、能监听 4443,但首个 HTTPS 请求打来即 terminate called ... Encryption not available on this event-machinelibssl-dev(eventmachine 编译时没编入 OpenSSL 支持)

⚠️ 坑③最具迷惑性:gem install 全程无报错,daemon 启动日志也正常,直到 curl https://... 才崩溃退出。根因是 eventmachine 1.2.7 在没有 libssl-dev 的环境里编译时会得到一个「无 TLS 能力」的变体。修复方式:

apt-get install -y libssl-dev
gem uninstall eventmachine -a -x --force
gem install eventmachine --no-document   # 这次会带上 OpenSSL 支持重编译

4.2 安装 gem

gem install schleuder -v 5.0.0 --no-document

实测输出(依赖与本体共 12 个 gem):

Successfully installed schleuder-5.0.0
12 gems installed
To set up Schleuder on this system please run `schleuder install`.

可执行文件落在 gem 的执行目录(Debian 的系统 ruby 环境下是 /usr/local/bin/):

$ which schleuder schleuder-api-daemon
/usr/local/bin/schleuder
/usr/local/bin/schleuder-api-daemon
$ schleuder version
5.0.0

4.3 初始化(与 apt 方案完全相同)

schleuder install

实测输出与 3.3 节一致(生成 /var/lib/schleuder/db.sqlite 与 /etc/schleuder/schleuder-*.pem,并给出证书指纹与权限警告)。因为以 root 运行,实测还执行了一次属主修正:

chown -R schleuder:schleuder /var/lib/schleuder /etc/schleuder

(gem 方案没有预建 schleuder 系统用户,可以自建一个专用用户跑服务,或沿用 root 但生产环境不推荐。)

4.4 启动 API 守护进程(无 systemd 单元,两种起法)

gem 包不带 systemd unit。实测最小起法:

nohup schleuder-api-daemon > /var/log/schleuder-api.log 2>&1 &

实测启动日志:

== Sinatra (v3.1.0) has taken the stage on 4443 for production with backup from Thin
2026-10-26 14:01:36 +0000 Thin web server (v1.8.2 codename Ruby Razor)
2026-10-26 14:01:36 +0000 Listening on localhost:4443, CTRL+C to stop
127.0.0.1 - - [26/Oct/2026:14:01:36 +0000] "GET /status.json HTTP/1.1" 200 15 0.0131

生产环境建议自建 systemd 单元(参照 apt 包里那份 /lib/systemd/system/schleuder-api-daemon.service,把 ExecStart 改成 /usr/local/bin/schleuder-api-daemon、User 改成你的服务用户即可),要点:

[Service]
User=schleuder
ExecStart=/usr/local/bin/schleuder-api-daemon
Restart=on-failure

[Install]
WantedBy=multi-user.target

4.5 验证

$ curl -sk -H "X-API-Key: q1w2e3r4-QWERTY-key-0001" https://localhost:4443/status.json
{"status":"ok"}

与 apt 方案相同的探活判据。至此 gem 方案完成。

五、双方案实测数据对照

维度apt 方案实测gem 方案实测
命令数2 条(install + install 初始化)+ systemd2 条依赖 + 1 条 gem + 1 条初始化
版本4.0.3-7+deb12u15.0.0
原生编译无gpgme/sqlite3/charlock_holmes/eventmachine 4 处
服务管理systemd 单元自带无,需自建
实测故障数2(网络层:IPv6 卡死、HTTPS 镜像证书)3(构建/运行层:icu+zlib、libcurl、eventmachine-TLS)
卸载apt-get purge schleuder && apt-get autoremovegem uninstall schleuder + 手工清理 /etc/schleuder、/var/lib/schleuder

六、与 MTA 的衔接:安装之后还差什么

Schleuder 装完只是「中枢」就绪,收发邮件必须由系统 MTA(Postfix/Exim/OpenSMTPD)桥接:

  • 收信方向:MTA 收到发往 listname@list.example.org 的信后,通过 pipe 机制交给 schleuder work <listname>@<hostname> 处理(MTA 别名/传输配置在 D1 运维篇详述);
  • 发信方向:Schleuder 解密重加密后的信件交给 schleuder.yml 里 smtp_settings 指定的 SMTP 服务(默认 localhost:25)出站。

本系列实测环境用 MailHog 容器作为 smtp_settings.address 的对端(25 端口),只用于观察出站信件;生产环境请对接真实 MTA,并务必为列表域名配好 SPF/DKIM/DMARC,否则密文再安全也会死在投递信任上。完整的 MTA 接线与端到端加密收发实测见后续篇章。

七、常见问题排查(实测速查)

症状原因处置
apt-get update 长时间卡住无进度域名解析到 IPv6 且 IPv6 不通写入 Acquire::ForceIPv4 "true" 或换镜像
apt 换 HTTPS 镜像后 Certificate verification failed容器 CA 链不完整改 http 镜像或重装 ca-certificates
gem install 中断 extconf failed(charlock_holmes)缺 ICU/zlib 头apt install libicu-dev zlib1g-dev 后重跑
Could not open library 'libcurl'typhoeus 运行时 FFI 找不到 libcurlapt install libcurl4
daemon 启动正常但首个请求即崩 Encryption not available on this event-machineeventmachine 编译时缺 libssl-dev装头文件后重装 eventmachine(见 4.1 坑③)
schleuder install 警告文件权限以 root 初始化,服务却以专用用户跑chown -R <服务用户> /var/lib/schleuder /etc/schleuder
API 探活 401/403valid_api_keys 未配置或不匹配在 schleuder.yml 加 key 后重启 daemon

八、下一章

安装只是起点。下一篇《配置参数详解》逐项拆解 /etc/schleuder/schleuder.yml 与 list-defaults.yml 的每个参数——包括本文反复出现的 valid_api_keys、smtp_settings、api.tls_*——并给出最小安全基线配置。