Mox 常用 CLI 命令详解
按业务域逐条实测 Mox v0.0.17 的 mox 命令:服务控制、账号密码、域名与配置热重载、sendmail 投递与队列管理、backup/verifydata 与 export 迁移、DNS/DKIM/DMARC/SPF/MTA-STS 诊断、cid 日志追踪,含 15 组真实回显与三段排障链。
Mox 常用 CLI 命令详解
目标:把 Mox v0.0.17 单二进制的
mox命令按业务域逐条讲清——服务控制、账号密码、域名配置、队列管理、备份迁移、DNS 协议诊断、日志追踪——全部命令附真实执行回显。全部命令与回显均在 Ubuntu 22.04.5 LTS 服务器(Mox v0.0.17)实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- Mox 版本:v0.0.17(
./mox version→v0.0.17-go1.27.3) - 安装布局:二进制
/home/mox/mox,配置/home/mox/config/,数据/home/mox/data/ - 主机名/域名:
mail.example.com/example.com,账号admin@example.com(演示密码q1w2e3r4) - 安装与配置文件详解分别见 《Ubuntu 22.04 安装 Mox 指南》、《Mox v0.0.17 配置参数详解》
二、工具概览
mox 是单二进制多子命令形态:mox serve 是唯一的常驻进程形态,其余全部子命令都是一次性运维操作。不带参数运行 mox 即打印全量子命令清单(实测节选):
mox serve
mox quickstart [-skipdial] [-existing-webserver] [-hostname host] $user@domain [$user | $uid]
mox stop
mox setaccountpassword $account
mox setadminpassword
mox loglevels [$level [$pkg]]
mox queue holdrules list
# ……(中间为 queue hold/unhold/schedule/transport/requiretls/fail 等系列,完整清单以不带参数运行 mox 的输出为准)
mox queue drop [filterflags]
mox queue dump $id
mox import maildir $accountname $mailboxname $maildir
mox export maildir [-single] $dstdir $accountpath [$mailbox]
mox localserve
mox help [$command ...]
mox backup $destdir
mox verifydata $datadir
mox licenses
mox config test
mox config dnscheck $domain
mox config dnsrecords $domain
mox config describe-domains >domains.conf
mox config describe-static >mox.conf
mox config account list
# ……(中间为 config account/addresses/domain/tlspubkey/alias 系列与 export/import,完整清单以不带参数运行 mox 的输出为准)
mox admin imapserve $preauthaddress
mox checkupdate
mox cid $cid
mox clientconfig $domain
mox dane dial $host:$port
mox dns lookup [ptr | mx | cname | ips | a | aaaa | ns | txt | srv | tlsa] $name
mox dkim genrsa >$selector._domainkey.$domain.rsa2048.privatekey.pkcs8.pem
mox dmarc lookup $domain
mox sendmail [-Fname] [ignoredflags] [-t] [< messagefile]
mox spf check $domain $ip
mox mtasts lookup $domain
mox version
按业务域分组速查:
| 业务域 | 子命令 | 一句话用途 |
|---|---|---|
| 版本与帮助 | help / version / licenses / checkupdate | 用法、版本、许可、新版本检查 |
| 服务控制 | serve / stop / loglevels | 常驻、优雅停机、日志级别 |
| 账号密码 | setaccountpassword / setadminpassword / config account … / config address … | 账号增删查与口令 |
| 域名与配置 | config domain … / config test / config describe-* / config dnsrecords / config dnscheck | 域名增删、配置校验与 DNS 核验 |
| 收信与队列 | sendmail / queue list / dump / hold / unhold / schedule / drop / holdrules / retired … | 投递与队列运维 |
| 备份迁移 | backup / verifydata / export / import | 在线备份、校验、邮箱导入导出 |
| 邮箱维护 | ensureparsed / recalculatemailboxcounts / reparse / message parse | 解析修复与统计 |
| 协议诊断 | dns lookup / dkim … / dmarc … / spf … / mtasts / dane … / dnsbl … / clientconfig | DNS 记录与邮件认证链诊断 |
| 日志追踪 | cid | Received 头 ID 反解为日志 cid |
两条调用约定先记住,能避开一半的报错:
- 工作目录:子命令按当前工作目录找
config/mox.conf,运维操作先cd /home/mox(否则报open config file: open config/mox.conf: no such file or directory (hint: use mox -config ... or set MOXCONF=...)); - 参数形态:
$account指账号名(如admin),$address指完整邮箱地址(如admin@example.com),两者混用是最常见错误。
三、前置条件
- mox 已安装并以 systemd 托管(
systemctl is-active mox→active,实测); - 以 root 执行(queue/backup 等命令经 ctl 通道与服务进程通信,服务进程本身已降权为 mox 用户);
- 演示中涉及的密码为测试口令
q1w2e3r4,生产环境请使用强口令。
四、各工具详解
4.1 版本与帮助
cd /home/mox
./mox version
实测输出:
v0.0.17-go1.27.3
linux/amd64
💡 说明:输出格式为
<版本号>-<构建工具链版本>。若二进制来自源码 tar.gz 直接go build,版本号显示(devel)(无 git 标签所致,功能不受影响,详见安装指南第三章对照表)。
./mox checkupdate
实测输出:
getting last known version: development version
latest version: v0.0.17
Changelog
checkupdate 直接查询官方更新源并打印最新版与变更日志,是确认「当前版本是否落后」的最快途径。
./mox licenses 2>&1 | head -3
实测输出:
# github.com/mjl-/mox/LICENSE
Copyright 2021 Mechiel Lukkien <mechiel@ueber.net>
查看许可证(MIT)。查某个子命令的完整帮助用 mox help <子命令>,例如 ./mox help quickstart 输出 quickstart 的用法、三个标志与完整行为说明。
4.2 服务控制
mox serve:前台常驻进程,生产由 systemd 托管(ExecStart=/home/mox/mox serve),手工调试时直接跑。
mox stop:优雅停机。实测:
cd /home/mox
./mox stop
sleep 1
systemctl is-active mox
实测输出:
mox stopped
activating
stop 走 mox 的 ctl 套接字(data/ctl)通知服务进程收尾退出;systemd 状态短暂 activating 后,因服务配置 Restart=always 自动拉起:
systemctl start mox # 若未配置自动重启则手动拉起
sleep 2
systemctl is-active mox
实测输出:
active
mox loglevels:查看/调整运行期日志级别(无需重启,改的是运行态):
cd /home/mox
./mox loglevels
实测输出:
(default): debug
调整全局级别为 info:./mox loglevels info(再次运行 ./mox loglevels 确认输出 (default): info)。永久修改要落 mox.conf 的 LogLevel(静态配置,需重启),详见配置详解篇 3.4 节的实测闭环。
4.3 账号与密码管理
设置密码(两命令都从 stdin 读口令,回显输入,输入两次确认):
cd /home/mox
printf 'q1w2e3r4\nq1w2e3r4\n' | ./mox setadminpassword
printf 'q1w2e3r4\nq1w2e3r4\n' | ./mox setaccountpassword admin
实测输出(两命令同构):
Type new password. Password WILL echo.
WARNING: Bots will try to bruteforce your password. Connections with failed
authentication attempts will be rate limited but attackers WILL find passwords
reused at other services and weak passwords. If your account is compromised,
spammers are likely to abuse your system, spamming your address and the wider
internet in your name. So please pick a random, unguessable password, preferably
at least 12 characters.
password:
⚠️ 排障实录:
setaccountpassword admin@example.com会报open account: no such account——第一个参数是账号名admin,不是邮箱地址。密码存储的是 SCRAM-SHA-256/SCRAM-SHA-1/CRAM-MD5/bcrypt 派生密钥(非明文),改完立即生效(实测 Web 登录 200)。
账号增删查(domains.conf 动态配置,操作即热重载):
cd /home/mox
./mox config account add jack jack@example.com
./mox config account list
./mox config account addresses jack
./mox config account rm jack
实测输出:
account added, set a password with "mox setaccountpassword jack"
admin
jack
jack@example.com
account removed
account list 列出全部账号名(admin、jack);account addresses <账号> 列出该账号的邮箱地址;add 的回显直接提示下一步设密码。config account disable <账号> <原因> 可临时停用(账号保留、拒绝登录),enable 恢复。
地址管理(把已有地址挂到账号/解绑):
./mox config address add sales@example.com jack
./mox config address account sales@example.com
./mox config address rm sales@example.com
实测输出(add/rm 成功时静默;account 子命令查询归属):
jack
4.4 域名与配置管理
域名增删:
cd /home/mox
./mox config domain add example.net admin
./mox config domain rm example.net
实测输出:
domain added, remember to add dns records, see:
mox config dnsrecords example.net
mox config dnscheck example.net
domain removed, remember to remove dns records for example.net
domain add 自动生成 DKIM 密钥对并写入 domains.conf(热重载即时生效,日志出现 m="domain added")。
配置语法校验:
./mox config test
实测输出:
config OK
生成带注释的参数参考模板(输出即官方文档):
./mox config describe-static > /tmp/mox-static-reference.conf
./mox config describe-domains > /tmp/mox-domains-reference.conf
wc -l /tmp/mox-static-reference.conf /tmp/mox-domains-reference.conf
实测输出:
1044 /tmp/mox-static-reference.conf
743 /tmp/mox-domains-reference.conf
DNS 记录清单与核验(每域名两条核心命令):
./mox config dnsrecords example.net
./mox config dnscheck example.net
dnsrecords 打印该域待发布的完整记录清单(MX/SPF/DKIM/DMARC/MTA-STS/autoconfig 等 zone 格式,实测同 quickstart 输出结构)。dnscheck 对已发布记录逐项核验,实测输出(域名刚添加、DNS 未配置时的真实形态):
# DNSSEC
warning: It looks like the DNS resolvers configured on your system do not verify DNSSEC, or aren't trusted (by having loopback IPs or through "options trust-ad" in /etc/resolv.conf).
# MX
error: MX records consists of explicit null mx record (".") indicating that domain does not accept email.
# DANE
warning: DANE is inactive because MX records are not DNSSEC-signed.
# SPF
error: IP "10.89.58.2" does not pass domain SPF evaluation, status not "pass" but "fail" (mechanism "-all", explanation "")
error: Looking up host SPF record: spf: no txt record for mail.example.com.
# DKIM
error: For selector "2026a", the public key in DKIM DNS TXT record does not match with configured private key.
error: For selector "2026b", the public key in DKIM DNS TXT record does not match with configured private key.
# DMARC
error: Configured DMARC reporting address is not present in record.
warning: It is recommended you specify you would like aggregate reports about delivery success in the DMARC record, see instructions.
把每一项的 error 消完(在 DNS 运营商发布记录、传播生效后复跑),全部 pass 即收发链路就绪。
4.5 收信与队列管理
mox sendmail:给系统进程(cron 等)用的 sendmail 兼容提交器,经 SMTP 提交到 moxsubmit.conf 指定的服务器:
cd /home/mox
./mox config describe-sendmail > /etc/moxsubmit.conf # 首次生成提交配置骨架
实测排障链(三步,全部真实回显):
- 不生成 moxsubmit.conf 直接发:
parsing config: open /etc/moxsubmit.conf: no such file or directory; - 生成了但没填认证:
checking passwords/keys: got passwords/keys , need exactly one; - 填了账号密码但证书是 ACME 引导自签:
submit failed: open smtp session: x509: certificate signed by unknown authority。
按需填好 /etc/moxsubmit.conf(本机提交场景:Host: mail.example.com、Port: 465、TLS: true、Username: admin@example.com、Password: q1w2e3r4、From: admin@example.com,自签证书场景加 TLSInsecureSkipVerify: true),然后发信:
printf "From: admin@example.com\nTo: admin@example.com\nSubject: mox cli test\n\nHello from mox CLI test.\n" > /tmp/msg.txt
./mox sendmail -t < /tmp/msg.txt
echo "sendmail exit=$?"
实测输出:
sendmail exit=0
⚠️ 两个要点:其一,
-t从 To/Cc 头取收件人,但 From 头会被重写为 moxsubmit.conf 的 From,该字段留空会得到550 ... from header does not have exactly one address: 0 addresses;其二,提交失败的消息会自动存到当前用户家目录的moxsubmit.failures/下(实测/root/moxsubmit.failures/newmsg.*),不丢信。
队列查看与诊断:投给不可达地址即可观察到滞留形态:
./mox queue list
实测输出:
messages:
5 2026-10-21T10:54:52Z from:admin@example.com to:test@nonexistent-domain-invalid.example next 7m30s last 3s error "dialing smtp server: looking up \"nonexistent-domain-invalid.example.\": lookup nonexistent-domain-invalid.example. on 127.0.0.1:53: no such host"
每行含消息 id、提交时间、收发地址、下次尝试倒计时(next)、上次尝试距今(last)与最近错误。投递成功的消息从活跃队列消失(日志打印 delivered from queue ... msgid=3 recipient=admin@example.com)。
queue dump:打印队列消息的完整原文(含 mox 添加的 Received、DKIM-Signature 头——可直观核对出站签名):
./mox queue dump 5 2>&1 | head -9
实测输出:
Received: from mail.example.com by mail.example.com ([10.89.58.2]) via tcp
with ESMTPSA id jFGUnLP08G6zTmZcrn4NHA (TLS1.3 TLS_AES_128_GCM_SHA256) for
<test@nonexistent-domain-invalid.example>; 21 Oct 2026 10:54:52 +0000
Message-Id: <RRCidiQ56yecaOTkCbDgPg@mail.example.com>
Date: 21 Oct 2026 10:54:52 +0000
DKIM-Signature: v=1; d=example.com; s=2026a; i=admin@example.com;
a=rsa-sha256; t=1792580092; x=1792839292; h=From:To:Cc:Bcc:Reply-To:
References:In-Reply-To:Subject:Date:Message-Id:Content-Type:From:To:
挂起/恢复/改期/丢弃(注意用 -ids 过滤标志,直接写裸 id 会被当成过滤表达式而只打印用法帮助):
./mox queue hold -ids 5 # 挂起,暂停一切投递尝试
./mox queue unhold -ids 5 # 恢复
./mox queue schedule -ids 5 -now 5s # 把下次尝试改到 5 秒后
./mox queue drop -ids 5 # 直接删除该消息(不可恢复)
实测输出:
1 messages changed
1 messages changed
1 message(s) rescheduled
1 message(s) dropped
schedule 支持 -now <duration> 立即或延时重试;hold/unhold/schedule/drop 都接受同一组 filterflags(-account/-from/-to/-ids/-n 等,可批量操作),如 ./mox queue drop -from @example.net 清空某域全部出站消息。
挂起规则(holdrules):预置规则让匹配的新消息一进队列就挂起(维护窗口前冻结出站):
./mox queue holdrules add -account admin
./mox queue holdrules list
./mox queue holdrules remove 1
实测输出:
hold rules:
(none)
hold rules:
id 1: account "admin"
(none)
规则列表带自增 id,remove 按 id 删。queue transport/requiretls/fail 等按同形态操作消息的传输通道与 TLS 策略(详见 ./mox help queue)。
4.6 数据备份与迁移
backup + verifydata(最小备份闭环):
cd /home/mox
./mox backup data/tmp/testupgrade
echo "backup exit=$?"
./mox verifydata data/tmp/testupgrade/data
echo "verify exit=$?"
实测输出:
backup exit=0
data/tmp/testupgrade/data: OK
verify exit=0
backup 在线执行(不停服),把 config/ 与 data/ 完整拷到目标目录;verifydata 校验数据一致性输出 : OK。
⚠️ 排障实录:备份目标必须是 mox 运行用户可写的目录——服务进程已降权(uid 1000),写
/root下会报成片permission denied。放/home/mox/data/tmp/下或先mkdir <dir> && chown mox:mox <dir>。
export/import(邮箱级迁移,标准 Maildir/mbox 格式):
cd /home/mox
./mox export maildir -single /tmp/maildir-export data/accounts/admin
find /tmp/maildir-export -type f | head -6
实测输出:
/tmp/maildir-export/Rejects/cur/1792566227.3.mox:2,S
/tmp/maildir-export/Inbox/cur/1792566799.4.mox:2,S
/tmp/maildir-export/Inbox/new/1792580202.7.mox:2,
# ……(另有 Inbox/new 下第 6 封消息及 Rejects 等邮箱目录,输出节选至此)
⚠️ 排障实录:export 的最后一个参数是账号数据路径(
data/accounts/admin),不是账号名——传账号名会报open database "admin/index.db": no such file or directory。-single把全部邮箱合入单棵 Maildir 树;去掉则每个邮箱一目录。导入用mox import maildir <账号名> <邮箱名> <maildir目录>(注意 import 用账号名,与 export 相反)。
4.7 邮箱维护
| 命令 | 用途 | 实测 |
|---|---|---|
mox recalculatemailboxcounts admin | 重算账号各邮箱的邮件数/未读数 | 静默成功 |
mox ensureparsed admin | 确保账号全部消息已解析建索引 | 静默成功 |
mox reparse admin | 用当前代码重新解析全部消息(升级后修复索引) | 静默成功 |
mox message parse <文件> | 打印单条消息的结构 JSON | 见下 |
message parse 对实际投递消息文件(存储于 data/accounts/<账号>/msg/<首字母>/<id>)的实测回显(节选):
{
"BoundaryOffset": -1,
"HeaderOffset": 0,
"BodyOffset": 1100,
"EndOffset": 1126,
"RawLineCount": 1,
"DecodedSize": 26,
"Envelope": {
"Date": "2026-10-21T10:56:42Z",
"Subject": "mox cli test",
"From": [
4.8 DNS 与协议诊断
这组命令把邮件认证链的每一环拆开单测(排障主力):
cd /home/mox
./mox dns lookup mx example.com
./mox dns lookup txt _dmarc.gmail.com
实测输出:
mx records (1, without dnssec):
- mail.example.com., preference 10
txt records (1, without dnssec):
- v=DMARC1; p=none; sp=quarantine; rua=mailto:mailauth-reports@google.com
dns lookup 支持 ptr/mx/cname/ips/a/aaaa/ns/txt/srv/tlsa 九类记录,输出自带「条数 + 是否 DNSSEC 验证」标注。
./mox dmarc lookup gmail.com
实测输出:
dmarc record at domain gmail.com: v=DMARC1; p=none; sp=quarantine; rua=mailto:mailauth-reports@google.com
(without dnssec)
./mox mtasts lookup gmail.com
实测输出:
error: mtasts: cannot fetch policy: http get: Get "https://mta-sts.gmail.com/.well-known/mta-sts.txt": dial tcp 142.250.107.138:443: i/o timeout
DNS TXT record _mta-sts.gmail.com: v=STSv1; id=20190429T010101
⚠️ 排障实录:mtasts lookup 分两步——先查
_mta-sts.<域>TXT(成功,上第二行),再 HTTPS 抓策略文件https://mta-sts.<域>/.well-known/mta-sts.txt。第二行有记录但第一行报错,说明 DNS 正常而 443 出站被网络策略挡住(本例实测超时),按出站 443 放行排查。
./mox spf check example.com 10.89.58.2
实测输出:
error: spf: no txt record
status: none (without dnssec)
对「域 + 发信 IP」给出 SPF 判定;spf parse <txtrecord> 可离线解析 SPF 记录语法。
./mox dkim verify data/accounts/admin/msg/a/7
实测输出(对一封已投递、但 DKIM DNS 记录未发布的消息):
warning: missing DNS record
status "permerror", err dkim: no dkim dns record for selector and domain: dns name "2026a._domainkey.example.com."
record ""
header DKIM-Signature: v=1; d=example.com; s=2026a; i=admin@example.com;
a=rsa-sha256; t=1792580202; x=1792839402; h=From:To:Cc:Bcc:Reply-To:
References:In-Reply-To:Subject:Date:Message-Id:Content-Type:From:To:
DKIM 签名本体存在(header 段完整展示),校验失败在 DNS 侧缺 2026a._domainkey.example.com TXT 记录——这正是「先看签名、再查记录」的定位路径。配套命令:dkim lookup <selector> <域>(查公钥)、dkim genrsa/gened25519(生成新选择器私钥)、dkim txt <私钥文件>(输出对应 DNS TXT 值)。
mox clientconfig:打印某域对外公布的客户端配置(与 autoconfig 界面同源):
./mox clientconfig example.com
实测输出:
Protocol Host Port Listener Note
Submission (SMTP) mail.example.com 465 public with TLS
IMAP mail.example.com 993 public with TLS
To prevent authentication mechanism downgrade attempts that may result in
clients sending plain text passwords to a MitM, clients should always be
explicitly configured with the most secure authentication mechanism supported,
the first of: SCRAM-SHA-256-PLUS, SCRAM-SHA-1-PLUS, SCRAM-SHA-256, SCRAM-SHA-1,
CRAM-MD5.
用户报「客户端连不上」时,先以此输出核对服务器主张的端口与协议,再查客户端实际配置。
4.9 日志追踪:mox cid
mox 每条日志都带 cid(连接计数器);投递的每封邮件在 Received 头里写入加密的 received id。mox cid 把 received id 反解为 cid,即可在日志里锁定这条连接的全部记录:
cd /home/mox
./mox cid LcYX6KsWtVTcvAgzs1tf8A
实测输出:
1a15e092524
随后 journalctl -u mox | grep 1a15e092524 即可还原该连接的完整协议过程。参数必须是 Received 头里的 24 字符 id(传短了会报 received id to cid: bad length, got N, expect 16——底层期望 16 字节,24 字符 base64 解码后正合)。
4.10 本地测试实例:mox localserve
开发联调场景(如测试应用的发信逻辑)可用一键本地实例,接受所有来信、仅监听回环:
./mox help localserve
实测输出(节选):
usage: mox localserve
-dir string
configuration storage directory (default "$userconfigdir/mox-localserve")
-initonly
write configuration files and exit
-ip string
serve on this ip instead of default 127.0.0.1 and ::1. only used when writing configuration, at first launch.
Start a local SMTP/IMAP server that accepts all messages, useful when testing/developing software that sends email.
localserve 与生产实例完全独立(独立配置目录),-initonly 只生成配置不启动。
五、注意事项
- 两条调用约定贯穿全部子命令:先
cd /home/mox(找得到 config/mox.conf);区分账号名与邮箱地址(adminvsadmin@example.com)。 - 动态/静态配置的生效路径不同:
config account/domain/address/alias系列写入 domains.conf 即热生效;mox.conf 类修改(Listeners/Transports/Webserver 等)必须./mox config test+systemctl restart mox。 - drop 不可恢复:
queue drop直接删除队列消息,误删只能让发件方重发;先queue dump <id>留档再删。 - hold 记得解:holdrules 或 hold 挂起后消息不会自动投递,维护结束务必 unhold/移除规则(
queue holdrules list核对)。 - 测试口令仅限演示:本文
q1w2e3r4仅为演示统一,生产环境用强口令并定期轮换(mox 密码命令每次都会打印强口令建议)。
六、常见问题(FAQ)
Q1:子命令报 open config/mox.conf: no such file or directory?
当前目录不对。mox 按当前工作目录找 config/mox.conf,先 cd /home/mox;或显式指定:./mox -config /home/mox/config/mox.conf <子命令>。
Q2:setaccountpassword admin@example.com 报 no such account?
参数应为账号名:./mox setaccountpassword admin。账号名用 ./mox config account list 查看。
Q3:sendmail 三连报错(no such file → need exactly one → x509)?
依次是:未生成 /etc/moxsubmit.conf(mox config describe-sendmail > /etc/moxsubmit.conf);未填 Username/Password;证书校验失败(本机自签场景将 TLSInsecureSkipVerify 置 true,或把服务器证书加入系统信任)。另外 From: 字段必填(From 头会被重写为该值)。
Q4:queue hold 写裸 id 不生效、只打印用法?
hold/unhold/schedule/drop 都是「filterflags」形态,用 -ids 5 指定消息;./mox queue list 输出里的首列数字即消息 id。
Q5:export maildir 报 open admin/index.db: no such file or directory?
export 用账号数据路径(data/accounts/admin),import 才用账号名——两者参数语义相反,注意区分。
Q6:retired list 一直是空的?
已退役消息仅在配置了 webhook 或保留策略时留存,默认投递完成后即清理。需要审计投递结果时看 journalctl -u mox | grep 'delivered from queue'。
Q7:mox cid <Received里的id> 报 bad length?
该命令收 24 字符的 Received id(base64,解出 16 字节)。确认复制的是 Received: 头里 id XXXX 的完整字符串,不是日志里的 cid。
七、参考链接
- 官方命令参考(Command reference):https://www.xmox.nl/commands/
- 官方安装页(quickstart/systemd):https://www.xmox.nl/install/
- 源码仓库:https://github.com/mjl-/mox
- 站内系列:安装主线见 《Ubuntu 22.04 安装 Mox 指南》,配置参数见 《Mox v0.0.17 配置参数详解》,选型背景见 《Mox v0.0.17 介绍与选型指南》