Schleuder 5.0.0 常用 CLI 命令详解:schleuder-cli 实测手册
Schleuder 管理面实操手册:schleuder-cli 0.2.0 安装接线与 TLS 指纹校验,lists/subscriptions/keys 全命令实测回显,出站链路 MailHog 实证 -bounce 通知与 X-SET-FINGERPRINT 机制,附邮件关键词命令表与 API 直连排障法。
Schleuder 5.0.0 常用 CLI 命令详解:schleuder-cli 实测手册
目标:把 Schleuder 的管理面操作讲透——独立工具
schleuder-cli的安装接线、命令树全貌、每类命令的实测输出与易错点,以及「邮件关键词命令」与 CLI 的分工。全部 CLI 命令在 Debian 12 + Schleuder 5.0.0(gem 安装)+ schleuder-cli 0.2.0 环境实测,输出为真实回显;邮件关键词部分为官方语义并经出站实测印证。安装与配置基础见本专栏前两篇。
一、schleuder-cli:安装与接线
1.1 安装
schleuder-cli 是独立 gem 包(与主程序同仓库发布,当前版本 0.2.0):
gem install schleuder-cli --no-document
# 实测输出:
# Successfully installed base64-0.2.0
# Successfully installed schleuder-cli-0.2.0
# 2 gems installed
$ which schleuder-cli
/usr/local/bin/schleuder-cli
$ schleuder-cli version
0.2.0
Debian 用户也可 apt install schleuder-cli(同样走 API,与主程序版本解耦)。
1.2 连接配置(四个字段一个不能少)
CLI 通过 HTTPS API 操作 daemon(这就是 B1 篇 schleuder install 生成 TLS 证书、C1 篇 valid_api_keys 存在的原因)。配置文件写在运行 CLI 的用户的 ~/.schleuder-cli/schleuder-cli.yml:
host: localhost
port: 4443
tls_fingerprint: 6412f1448f4f4b3aee7911fbe1d12bc46e8f8be458410a0f653ea4d7a17d3815
api_key: q1w2e3r4-QWERTY-key-0001
| 字段 | 来源 | 说明 |
|---|---|---|
host / port | C1 篇 api.host / api.port | daemon 监听位置,默认 localhost:4443 |
tls_fingerprint | schleuder install 输出的证书指纹 | CLI 会校验自签名证书的指纹,不匹配即拒绝连接(防 MITM——对一个「自认中间人」的系统,管理通道反而必须防中间人) |
api_key | C1 篇 valid_api_keys 之一 | 认证凭据 |
实测验证接线成功的标志:
$ schleuder-cli lists list
(空行,退出码 0 —— 已连上,只是还没有列表)
⚠️ 指纹填错或 key 没配时,报错是
Error: Cannot connect to Schleuder API at localhost:4443, please check if it's running.(实测复现)——这条报错不区分「daemon 没起」与「证书/key 不对」,排查时先 curl 探活(见第八节)再查配置。
1.3 命令树总览
$ schleuder-cli help
Commands:
schleuder-cli keys ... # Manage OpenPGP-keys
schleuder-cli lists ... # Create and configure lists
schleuder-cli subscriptions ... # Create and manage subscriptions
schleuder-cli tree # Print a tree of all available commands
schleuder-cli version # Show version of schleuder-cli or Schleuder.
注意 version 带 -cli 后缀时显示 CLI 版本(0.2.0),命令会先连 API 再回显主程序版本。
二、列表管理(lists)
实测命令签名与回显:
schleuder-cli lists list
schleuder-cli lists new <list@hostname> <adminaddress> [</path/to/publickey>]
schleuder-cli lists show <list@hostname> <option>
schleuder-cli lists set <list@hostname> <option> <value>
schleuder-cli lists list-options
schleuder-cli lists send-list-key-to-subscriptions <list@hostname>
schleuder-cli lists delete <list@hostname> [--YES]
2.1 创建列表:lists new
$ schleuder-cli lists new testlist@localhost root@localhost
List testlist@localhost successfully created! Don't forget to hook it into your MTA.
root@localhost subscribed to testlist@localhost without setting a fingerprint.
$ schleuder-cli lists list
testlist@localhost
三个实测要点:
- 列表名必须全写
listname@hostname——列表邮件地址即列表身份; - 第二参数
adminaddress会被自动订阅为列表管理员(回显第二行),且默认无指纹("without setting a fingerprint"); - 提醒语 "Don't forget to hook it into your MTA" 印证 B1 篇结论:创建列表后必须给 MTA 加别名/传输规则,邮件才能进得了列表。
创建列表时系统还会自动为列表生成一对 OpenPGP 密钥(实测 keys list 里出现了 6876C3F6389C4366680490265213A8A8F5D7C1EA testlist@localhost,与订阅者密钥并列)——列表私钥是整个重加密模型的核心资产,务必随 lists_dir 一起备份。
2.2 读改属性:lists show / set(单属性粒度)
实测易错点:lists show 不带 option 会直接报错(不是打印全量配置):
$ schleuder-cli lists show testlist@localhost
ERROR: "schleuder-cli lists show" was called with arguments ["testlist@localhost"]
Usage: "schleuder-cli lists show <list@hostname> <option>"
正确用法是「一次一个属性」:
$ schleuder-cli lists show testlist@localhost send_encrypted_only
true
$ schleuder-cli lists set testlist@localhost subject_prefix "[testlist] "
$ schleuder-cli lists show testlist@localhost subject_prefix
[testlist]
可用属性清单用 lists list-options 拿(即 C1 篇 list-defaults.yml 的全集:send_encrypted_only、receive_authenticated_only、subject_prefix、max_message_size_kb……)。
2.3 删除列表:lists delete(带二次确认参数)
$ schleuder-cli lists delete testlist@localhost --YES
(无输出,退出码 0)
$ schleuder-cli lists list
(空)
--YES 就是二次确认本身;实测不带它删除会拒绝执行。删除会一并移除列表密钥环与订阅关系。
三、订阅管理(subscriptions)
schleuder-cli subscriptions new <list@hostname> <user@example.org> [<fingerprint>]
schleuder-cli subscriptions list <list@hostname>
schleuder-cli subscriptions show <list@hostname> <user@hostname> <option>
schleuder-cli subscriptions set <list@hostname> <user@hostname> <option> <value>
schleuder-cli subscriptions list-options
schleuder-cli subscriptions delete <list@hostname> <user@example.org>
实测过程:
$ schleuder-cli subscriptions new testlist@localhost alice@localhost
alice@localhost subscribed to testlist@localhost without setting a fingerprint.
$ schleuder-cli subscriptions list testlist@localhost
alice@localhost N/A
root@localhost N/A admin
subscriptions list 的列依次为:地址、指纹(无则 N/A)、是否管理员(admin)、备注。订阅级属性只有三个(subscriptions list-options 实测):
| 属性 | 含义 |
|---|---|
fingerprint | 该订阅者的 OpenPGP 指纹——出站加密的目标钥匙,没有它订阅者收不到密文(只能收到签名信,见第六节实测) |
admin | 是否列表管理员(true/false) |
delivery_enabled | 是否正常投递(false 即挂起收信) |
给订阅者补指纹:
$ schleuder-cli subscriptions set testlist@localhost root@localhost fingerprint 0000000000000000000000000000000000000000
0000000000000000000000000000000000000000 ← set 成功后回显写入值
💡 实操顺序建议:
keys import先入公钥 → 查得指纹 →subscriptions set ... fingerprint <FP>关联。顺序反了会导致「密钥环里有钥匙但订阅者没绑定」的悬空状态。
四、密钥管理(keys)
schleuder-cli keys list <list@hostname>
schleuder-cli keys import <list@hostname> </path/to/keyfile>
schleuder-cli keys export <list@hostname> <fingerprint>
schleuder-cli keys check <list@hostname>
schleuder-cli keys delete <list@hostname> <fingerprint>
完整生命周期实测(先在本地生成测试密钥):
$ gpg --batch --pinentry-mode loopback --passphrase "" \
--quick-generate-key "alice@localhost" default default never
$ gpg --export alice@localhost > /tmp/alice.pub
$ schleuder-cli keys import testlist@localhost /tmp/alice.pub
Imported: 0x940BE7D6989BAC66AAD96C1B570A122C43BB4D0F alice@localhost 2026-10-26
$ schleuder-cli keys list testlist@localhost
940BE7D6989BAC66AAD96C1B570A122C43BB4D0F alice@localhost
6876C3F6389C4366680490265213A8A8F5D7C1EA testlist@localhost ← 列表自身密钥
$ schleuder-cli keys export testlist@localhost 940BE7D6989BAC66AAD96C1B570A122C43BB4D0F | head -2
pub 3072R/940BE7D6989BAC66AAD96C1B570A122C43BB4D0F 2026-10-26
uid <alice@localhost>
$ schleuder-cli keys check testlist@localhost
(无输出 = 无过期/无问题密钥)
$ schleuder-cli keys delete testlist@localhost 940BE7D6989BAC66AAD96C1B570A122C43BB4D0F
Ok.
要点:
keys import吃的是ASCII/二进制公钥文件,回显导入指纹;导入不等于绑定——绑定要再做subscriptions set ... fingerprint;keys check用于巡检(过期、缺 UID 等),无输出即健康,适合放进 cron;- 删除密钥用完整 40 位指纹,短指纹会被拒绝。
五、出站链路实测:send-list-key-to-subscriptions
这条命令把列表公钥群发给所有订阅者(订阅者要用列表公钥加密来信)。实测中把它变成了「出站链路 + 通知机制」的双重演示:
- 按 C1 篇把
smtp_settings指到测试 SMTP(MailHog 容器 1025 端口),重启 daemon; - 执行命令:
$ schleuder-cli lists send-list-key-to-subscriptions testlist@localhost
true
- 在 MailHog 侧看到 2 封信(对应 2 个订阅者),特征完全一致:
From: testlist-bounce@localhost → To: root@localhost / alice@localhost
Subject: Notice
正文: You missed an email from testlist@localhost because your subscription
isn't associated with a (usable) OpenPGP key. Please fix this.
To do that you can use the keyword X-SET-FINGERPRINT, see
<https://schleuder.org/schleuder/docs/subscribers.html#special-keywords> ...
MIME: OpenPGP/MIME signed(RFC 4880/3156,列表私钥签名)
三个一手结论:
- 订阅者没绑定可用指纹时,密文发不出去,系统改从
<listname>-bounce@host信封地址发通知信——这就是 C1 篇superadmin/bounce 机制的实相; - 通知信是列表私钥签名的明文信(对无密钥对象无法加密),头可见 Schleuder 的 OpenPGP/MIME 规范行为;
- 通知信官方指路的关键词是 X-SET-FINGERPRINT——邮件关键词体系存在的直接证据(第七节)。
六、邮件关键词命令:与 CLI 的分工
Schleuder 有一套用邮件本身下达指令的机制:把命令写在来信主题或正文的 x- 关键词行里,列表解密后执行并回信。CLI 管的是服务器侧管理,关键词命令服务的是订阅者自助与列表内协作,两者操作的是同一套列表状态。
按官方订阅者文档与实测配置(C1 篇 keywords_admin_only 默认值 [subscribe, unsubscribe, delete-key])归纳,常用关键词分两类:
订阅者自助类:
| 关键词 | 作用 |
|---|---|
x-list-options | 查询本订阅在列表上的选项 |
x-set-fingerprint <FP> | 给自己绑定指纹(第六节实测通知信指路的就是它) |
x-add-key <公钥块> | 向列表密钥环上传公钥(触发 C1 篇 keywords_admin_notify 的默认告警) |
x-resend <addr> [<addr>...] | 把原文转发给非订阅者(「群邮件枢纽」能力的日常入口,出站自动按对方可用密钥加密) |
x-attach-listkey | 请求附上列表公钥 |
管理员类(默认 keywords_admin_only 锁定):
| 关键词 | 作用 |
|---|---|
x-subscribe <addr> [<FP>] | 替他人订阅 |
x-unsubscribe <addr> | 替他人退订 |
x-delete-key <FP> | 从列表密钥环删除密钥 |
⚠️ 边界说明:关键词命令的入口依赖 MTA 管道(来信必须先进
schleuder work <list>),本地容器未接生产 MTA,上表为官方文档语义 + 配置默认值交叉印证;CLI 部分全部为实测回显。生产部署时先完成 MTA 别名接线(B1 篇第六节),关键词链路才可用。
七、绕过 CLI 直连 API(排障备用)
CLI 本质是 API 客户端。daemon 状态的最小探活(无需 CLI):
$ curl -sk -H "X-API-Key: q1w2e3r4-QWERTY-key-0001" https://localhost:4443/status.json
{"status":"ok"}
CLI 报 "Cannot connect" 时按此顺序排查:① daemon 进程/端口(ss -tlnp | grep 4443)→ ② 该 curl 探活(区分服务问题与证书/key 问题)→ ③ CLI 四项配置(1.2 节)。
八、命令速查卡(实测签名版)
# 列表
schleuder-cli lists list
schleuder-cli lists new <list@host> <adminaddr> [<pubkeyfile>]
schleuder-cli lists show <list@host> <option> # 一次一个属性
schleuder-cli lists set <list@host> <option> <value>
schleuder-cli lists list-options
schleuder-cli lists send-list-key-to-subscriptions <list@host>
schleuder-cli lists delete <list@host> --YES
# 订阅
schleuder-cli subscriptions new <list@host> <user@host> [<FP>]
schleuder-cli subscriptions list <list@host>
schleuder-cli subscriptions set <list@host> <user@host> <option> <value> # fingerprint/admin/delivery_enabled
schleuder-cli subscriptions list-options
schleuder-cli subscriptions delete <list@host> <user@host>
# 密钥
schleuder-cli keys import <list@host> <keyfile> # 导入≠绑定,还需 subscriptions set fingerprint
schleuder-cli keys list <list@host> # 含列表自身密钥
schleuder-cli keys export <list@host> <FP>
schleuder-cli keys check <list@host> # 无输出=健康,可进 cron
schleuder-cli keys delete <list@host> <FP> # 40 位完整指纹
# 探活
curl -sk -H "X-API-Key: <key>" https://<host>:4443/status.json
九、下一篇
至此本专栏完成 Schleuder 的认知(A1)→ 安装(B1)→ 配置(C1)→ 运维操作(D1)四部曲。生产上线前最后一块拼图是 MTA 管道的正式接线(Postfix/Exim 别名与 pipe 传输),其命令模式已在 B1/D1 篇以 MailHog 实测验证了出站方向,收信方向按同样思路用 MTA 的 pipe 机制落地即可。