19 KiB
clover 三叶草邮局 — 项目规划 v0.1
状态:规划定稿待评审 · 2026-10-11 · 作者:小宝(调研结论由 6 个并行调研组合成)
1. 项目一句话
一个开源自托管邮局:一条 compose 命令部署在 Debian/Ubuntu VPS 上,用 PurelyMail 式的现代 Web 面板管理无限域名、无限别名与 Catch-all,内置反垃圾(rspamd),DNS 记录可一键推送 Cloudflare,支持在面板里收发信、看日志与队列。
2. 需求定义
2.1 原始需求(boss)
- Debian/Ubuntu 上可用的 Docker 应用,VPS 部署邮局
- 通过垃圾邮件检测(发信能进收件箱,来信不泛滥)
- 主面板:方便地添加新域名、管理邮件和收发信件
- 一键导出 DNS 记录,导入 Cloudflare
- 参考 Mail-in-a-Box,但要好用的可视化界面(MIAB 实测面板简陋、不支持 Docker、无队列日志视图、作者明确拒绝定制化——不走它的老路)
2.2 追加需求(boss 2026-10-11)
- 用法对标 PurelyMail,但运行在自己 VPS 上
2.3 PurelyMail 对标特性(调研结论,clover 逐项映射)
| # | PurelyMail 特性 | clover 对应设计 | 优先级 |
|---|---|---|---|
| 1 | 一口价、永不按 user/domain 收费 | 自托管无计费;面板首页展示资源用量(域名/邮箱/别名/存储/日发件量),无硬限制 | P0 |
| 2 | 无限别名 = 四类路由规则(精确/前缀/非用户地址/Catch-all)+ 多目标外部转发 + 优先于真实用户 + sieve 兜底 | 独立 routing_rules 模型,面板可视化编辑,映射到 DMS alias 机制 |
P0 |
| 3 | 建域即全套 DNS + checklist 自动检测(ownership TXT / MX / SPF / DKIM / DMARC) | 建域向导自动生成 10 条记录 + dig 探测自动打勾 | P0 |
| 4 | ——(PurelyMail 自己只做到复制粘贴) | 真·一键推送 Cloudflare(CF API batch,幂等同步)+ 一键导出 BIND 文件,核心差异化卖点 | P0 |
| 5 | 密码派生密钥的 at-rest 加密,服务商不可读;日志/备份保留 1 个月 | MVP 降级:VPS 层 LUKS 卷加密指南 + 明示保留策略;后续可做 per-mailbox 加密(PGP 或应用层) | P2 |
| 6 | 开箱反垃圾:SpamAssassin + IP 黑名单 SMTP 层拒收 + 自学习贝叶斯 + greylisting | rspamd + redis + ClamAV(DMS 全家桶),rspamd 自学习、神经网络+、面板显示评分/隔离 | P0 |
| 7 | 官方 REST API(域名/路由/用户 CRUD),生态自己长(社区已有 CF 自动化脚本、SDK、MCP) | clover 面板本身就是开放 API /api/v1,开放文档 + token 体系 |
P1 |
附注(纠偏调研):PurelyMail 宣传的「passkey 免密登录」经查证不存在,其现状是「密码 + TOTP/FIDO2 双因素」。clover 面板可以弯道超车:第一因素即支持 WebAuthn Passkey。
3. 开源生态调研结论(摘要)
调研方式:6 个并行 agent 深挖官方文档 / GitHub / 社区,覆盖 10 个项目。
| 项目 | 语言 | 许可证 | Docker | 自带 UI | 管理 API | 反垃圾 | 社区 | 一句话结论 |
|---|---|---|---|---|---|---|---|---|
| docker-mailserver (DMS) | Postfix 栈 | MIT | ✅ 单镜像/多拆分,无 DIND | ❌ 纯 CLI | ❌ 无 | rspamd+ClamAV+redis | 19.2k★ 极活跃 | 功能全家桶、社区最大、无 UI——正是机会 |
| mailcow-dockerized | PHP | GPLv3 | ✅ 原生,~20 容器 | ⚠️ PHP+Twig 老化 | ✅ REST 全对象 | rspamd+ClamAV | 13k★ | 功能天花板,UI 体验差,6GB 内存起步,重 |
| Stalwart | Rust | AGPL | ✅ | ✅ 现代面板 | ✅ HTTP API | 自研过滤器 | 8k★ 很活跃 | 功能最全单体,但 AGPL 传染 + Rust 改造门槛高 |
| Mailu | Python | MIT | ✅ compose | ✅ 简洁 | ✅ REST | rspamd | 数千★ 活跃 | 轻量标杆,但无队列/日志视图,功能偏薄 |
| Poste.io | ? | 专有(PRO 收费) | ✅ 单容器 | ✅ 成熟 | ✅ PRO | rspamd+ClamAV | 10M+ pulls | 体验标杆但闭源,个人以上收费,不可基于它 |
| Maddy | Go | MIT | ✅ | ❌ | ❌ 无 | 内置检查/milter | 3k★ | IMAP 存储仍是 beta,收件侧不成熟 |
| WildDuck | Node | EUPL | ✅ | ❌ | ✅ 完整 REST | 需外拼 | 4k★ | 无 SMTP,要拼 Haraka+ZoneMTA,小规模过设计 |
| Mail-in-a-Box | Shell | CC0 | ❌ 仅裸机 | ⚠️ 简陋 | 内部 API | SpamAssassin | — | UI 简陋、不 Docker、无队列日志——用户点名排除 |
| Modoboa | Python/Django | ISC | ⚠️ 仅开发用 compose | ✅ 最深 | 弱 | Amavis | 活跃 | 面板深度标杆(被拦邮件可视/放行),但无生产镜像 |
| iRedMail | Shell | GPL-2.0 | ⚠️ 官方 Docker 仅 BETA | ✅ | 弱 | Amavis+SA | 活跃 | Docker 自标"勿上生产" |
周边可复用组件(直接抄作业):
- 反垃圾:rspamd(有 WebUI + HTTP API
/scan/symbols/stats,可嵌面板)+ redis + ClamAV,参考 DMS 组合 - WebMail:官方 Roundcube 客户端;面板一次性票据免密进入
- 证书:acme.sh
dns_cf插件 + CF Token,通配符*.domain是事实标准 - DNS 自动化:Cloudflare API v4(zone 查询、records CRUD、批量 batch 写),已有先例
d-horner/mailcow-CloudFlare-DNS可参考;MIAB/PurelyMail 都只做到"复制粘贴",自动推送是空白点 - 投递体检:MXToolbox REST API(黑名单/SPF/DKIM/DMARC 一键检查),可脚本化
4. 技术路线决策
4.1 结论:docker-mailserver 底座 + 自研 clover 面板
先排除两条死路:
- 从头写 MTA/反垃圾 = 自杀。Postfix/Dovecot/rspamd/ClamAV 是邮件行业几十年沉淀,没有任何理由重写;要重写的只是"管理和体验层"。
- 基于 Poste.io / Modoboa / MIAB 改造 = 走进死胡同。闭源收费 / 无生产镜像 / 不 Docker。
三条可行路线对比:
| 路线 | 内容 | 优点 | 缺点 | 判定 |
|---|---|---|---|---|
| A. DMS 底座 + 自研面板 | DMS 跑邮件全家桶;clover 自研 Next.js 面板(DB 是唯一事实源,经 docker CLI 同步 DMS) | MIT 无传染;19.2k★ 坑最少;无历史 UI 包袱;Docker 原生轻量;可完全照 PurelyMail 设计交互 | 账号层需自建同步 sidecar;无现成 API 可调(要 exec CLI) | ✅ 推荐 |
| B. Mailcow 外挂 SPA | 保留 mailcow 后端,外层 React/Vue 调其 REST API | API 现成、功能最全 | 20 容器 6GB 起步;PHP 内部逻辑要改仍重;GPLv3;UI 数据模型要迁就它的设计 | 备选 |
| C. Stalwart 换皮 | 自带面板和 API,只做现代化皮 + CF 推送 | 最省事 all-in-one | AGPL 传染(改造必须开源或买企业许可);Rust 栈改造门槛;未发 1.0 | 不推荐 |
4.2 DMS 的坑与对策
| DMS 的短板 | clover 对策 |
|---|---|
| 无数据库、无 API,只有 CLI + 配置文件 | SQLite 控制库为唯一事实源 → 面板所有变更通过 docker exec docker-mailserver setup ... 官方 CLI 落地(官方路径最稳,自带校验和 reload),同步结果回查校验 |
| 无 UI,第三方 UI 均不成熟 | 自研,无历史包袱,直接对标 PurelyMail |
| 无 DNS 一键导出 | DNS 生成器 + CF 批量推送(见 6.3/6.4) |
| 无 WebMail | 官方 Roundcube 客户端,由 Clover 面板一次性票据授权 |
| 无队列/日志视图 | 读 DMS 容器日志(supervisord)+ dovecot 队列命令,面板聚合展示 |
| DKIM 只到目录,无展示 | 读取 DMS dkim 目录公钥,自动填入 DNS 生成器 |
5. 目标架构
5.1 组件图
Internet
|
[ 邮件客户端 IMAP/SMTP ] | [ 外部收件方 MX ]
| | ^
v | | 25/465/587 投递
+-----------+ | |
| Caddy |<-------+----------+
| HTTPS 入口 | (邮件流量不过 Caddy,直连 DMS)
| 自动证书 |
+-----------+
| | |
/panel | /webmail | /rspamd
v v v
+----------------+ +----------+ +-----------+
| clover-panel | | mail protocols| | rspamd-ui |
| Next.js 单体 | | (iframe) | | (iframe) |
| UI+API+控制面 | +----------+ +-----------+
| SQLite |
+----------------+
| |
v v
[ docker.sock ] [ Cloudflare API ]
| (DNS 一键推送)
v
+---------------------------+
| docker-mailserver |
| postfix / dovecot / |
| rspamd+redis / clamav |
+---------------------------+
5.2 关键数据流
- 建域:面板填域名 → 生成 ownership TXT/CF Zone 授权 → 检测归属 → 生成 MX/SPF/DKIM/DMARC 等全量记录 → 一键推 CF(或导出)→ dig 自动检测逐项打勾
- 建邮箱/别名:面板 CRUD → clover DB 落库 → exec DMS CLI(
setup email add/setup alias add/setup domain add)→ 回查校验 → 记录审计日志 - 来信:外部 MX → 25 端口 → rspamd(评分/黑名单/自学习)→ 达标 → Dovecot 投递 mailbox
- 面板收发信视图:DMS 容器日志解析(队列/拒绝/投递)+ IMAP master user 读 mailbox 预览/搜索 + rspamd API 拉取评分统计
- 发信体检:MXToolbox API 一键跑黑名单/SPF/DKIM 检查,面板展示
5.3 部署形态
- 一个 compose 栈,一条
curl | bash安装器(申请面板域名、CF Token、时区等少量参数) - 统一入口 Caddy(自动 HTTPS,反代
/、/webmail、/rspamd);邮件端口由 DMS 直接暴露 - 面板地址:
panel.<首个域名>(或mail.<域名>,安装时选) - 升级:compose pull + 面板自带迁移脚本(DB migration + DMS 版本兼容检查)
6. 核心模块设计
6.1 控制面数据模型(SQLite + Drizzle)
admins(id, username, password_hash, webauthn_credentials[json], totp_secret, created_at)
domains(id, name, ownership_token, cf_zone_id, dns_status[json], mail_hostname,
quota_policy_mb, active, created_at)
mailboxes(id, domain_id, login, password_hash, quota_mb, active, created_at)
routing_rules(id, domain_id, match_type, match_value, targets[json], priority, active)
-- match_type: exact(精确地址) | prefix(前缀如 sales@) | nonuser(非用户地址) | catchall
dns_records(id, domain_id, type, name, content, ttl, cf_record_id, pushed_at, status)
settings(key, value_encrypted) -- VPS IP、CF Token、面板 URL、主机名等
audit_logs(id, actor, action, target, detail, created_at)
6.2 DMS 账号同步(最关键的工程点)
- 所有账号/域名/别名变更 → 调 DMS 官方
setupCLI(setup email add/domain add/alias add等),CLI 内部负责写配置、生成 hash、reload postfix/dovecot——不裸写配置文件,规避格式兼容风险 - 同步采用「面板 DB 为准 + 每日对账任务」双保险:cron 比对 DMS 实际账号与 DB,差异告警
- DMS 大版本升级前跑 compat 检查(CLI 行为变更),升级流程写入文档
6.3 DNS 记录生成器
建域向导自动产出(默认值均可编辑、可预览):
| 记录 | 值 |
|---|---|
TXT @ |
clover-verification=<token>(域名归属) |
A mail.<dom> |
VPS IP |
MX @ |
mail.<dom> 优先级 10 |
TXT @ |
v=spf1 a mx ip4:<IP> -all(可调 ~all) |
TXT mail._domainkey |
DMS 生成的 DKIM 公钥 |
TXT _dmarc |
v=DMARC1; p=quarantine; rua=mailto:postmaster@<dom>; fo=1 |
| (进阶) | autoconfig/autodiscover CNAME、MTA-STS、TLS-RPT |
导出格式:CF API 推送(主)+ BIND zone 文件 / 纯文本清单(兜底)。
6.4 Cloudflare 一键推送
API 选型(官方文档已核对)
认证统一走 API Token:Authorization: Bearer <token>,最小权限模板 Zone → DNS → Edit(仅授权目标 zone)。面板设置页录入、加密存储。不用 Global API Key。
| 步骤 | API | 说明 |
|---|---|---|
| 1. 定位 zone | GET /zones?name=<domain> |
按域名精确查 zone_id(域名须已在 CF 账号下) |
| 2. 读现有记录 | GET /zones/{zone_id}/dns_records?type=&name= |
分页拉全,用于幂等 diff |
| 3. 批量写入(主路径) | POST /zones/{zone_id}/dns_records/batch |
body:{deletes:[{id}], patches:[{id,...}], posts:[{...}], puts:[{...}]} |
| 4. BIND 导入(备选) | POST /zones/{zone_id}/dns_records/import |
multipart file 字段传 BIND zone 文本,返回 recs_added / total_records_parsed |
batch 行为要点(务必遵守):
- 执行顺序固定 deletes → patches → puts → posts,不是数组书写顺序
- 单请求单 DB 事务,按操作组分包返回;4XX 时
errors[].source.pointer指出出错位置(如/body/posts/0) - 单批保守按 ≤1000 条分批(M2 实测验证上限)
- 记录字段:
type / name / content / ttl / priority / proxied / comment / settings / tags - MX/SRV/CNAME/NS 等 content 若指向域名必须是 FQDN(尾点),否则 BIND/import 场景解析歧义
- DKIM 长 TXT:CF API 接受完整公钥单条 content(自动分片存储);仅 BIND 文件导出时需手动按 255 字符分片
proxied仅对可代理记录生效,邮件相关记录一律false
clover 推送策略:
- 建域后展示「记录预览表」(逐条可编辑/禁用)→ 与 CF 现有记录 diff → 生成 posts(新增)/ patches(更新)/ deletes(移除 clover 托管且废弃的)
- 点「一键推送」→ 调用 batch → 按分组展示结果与失败明细
- 推送后启动 dig 探测任务,MX/SPF/DKIM/DMARC 逐项自动打勾(checklist)
- 兜底:无 CF Token 的用户可下载 BIND zone 文件(粘到 CF 面板 Import and Export 手动导入,即
/dns_records/import的手工版)或纯文本清单 - 之后所有变更(换 IP、加域名、轮换 DKIM)都走同一条 diff+推送管道,幂等可重复执行
# 1) 查 zone_id
curl -s "https://api.cloudflare.com/client/v4/zones?name=example.com" \
-H "Authorization: Bearer $CF_TOKEN" | jq -r '.result[0].id'
# 2) 批量写入全部邮局记录(一次请求)
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/batch" \
-H "Authorization: Bearer $CF_TOKEN" -H "Content-Type: application/json" \
-d '{
"posts": [
{"type":"A","name":"mail.example.com","content":"203.0.113.10","ttl":1,"proxied":false,"comment":"clover"},
{"type":"MX","name":"example.com","content":"mail.example.com.","priority":10,"ttl":1,"comment":"clover"},
{"type":"TXT","name":"example.com","content":"v=spf1 a mx ip4:203.0.113.10 -all","ttl":1,"comment":"clover-spf"},
{"type":"TXT","name":"mail._domainkey.example.com","content":"v=DKIM1; k=rsa; p=MIIBIjANBgkq...","ttl":1,"comment":"clover-dkim"},
{"type":"TXT","name":"_dmarc.example.com","content":"v=DMARC1; p=quarantine; rua=mailto:postmaster@example.com; fo=1","ttl":1,"comment":"clover-dmarc"}
]
}'
6.5 反垃圾面板化
- rspamd WebUI iframe 反代(
/rspamd) - 面板「反垃圾」页:通过 rspamd HTTP API 拉取评分分布、符号命中 TopN、每域统计
- 隔离区:入箱隔离的邮件列表 + 一键放行/删除(调 rspamd actions + dovecot sieve)
- ClamAV 病毒扫描报告
- MXToolbox API 一键体检:IP 黑名单 / SPF / DKIM / DMARC / MX
6.6 WebMail 与单点登录
- Webmail 由官方 Roundcube 镜像提供,保留原生邮件功能
- 登录打通:面板用户点「打开邮箱」→ 一次性票据经服务器兑换,通过 Dovecot master user 自动登录(不暴露密码)
6.7 面板认证
- 管理员账号 + 密码(argon2)+ TOTP + WebAuthn Passkey(弯道超车 PurelyMail:第一因素即可 Passkey)
- Session:httpOnly cookie + CSRF 防护
- 开放 API token(6.1
audit_logs记录一切)
6.8 开放 API
/api/v1/{domains,mailboxes,routing_rules,dns,…} REST + token 鉴权,文档站同仓库,留给社区做 CLI/SDK/MCP(学 PurelyMail 的生态放大器打法)。
7. 部署要求(写进安装器和文档)
| 项 | 要求 |
|---|---|
| 系统 | Debian 11–13 / Ubuntu 22.04+,x86_64/aarch64 |
| 资源 | 最低 2 核、2GB RAM + 1GB Swap(ClamAV 自动关闭);推荐 2 核 4GB RAM,可启用 ClamAV |
| Docker | Docker Engine ≥ 24 + compose v2 |
| 网络 | 公网 25/465/587 端口放行(部分 VPS 商默认封锁,需工单开通,安装器检测并提示) |
| rDNS | 引导设置 VPS IP 的 PTR 记录指向 mail.<域名>(送达率关键) |
| IP 质量 | 建议干净 IP(非阿里/腾讯等云共享段),新 IP 有 warmup 常识引导 |
| 位置 | 建议海外 VPS:内地 VPS 对自建邮局对外服务有端口与合规限制 |
| 备份 | 数据卷 + SQLite 每日备份脚本(litestream 可选),说明恢复流程 |
8. 里程碑(单人全职估算)
| 阶段 | 内容 | 估时 |
|---|---|---|
| M0 骨架 | monorepo、compose 栈、安装器 v0、手工 CLI 配 1 域 1 邮箱跑通收发(验证 25 端口/rDNS/送达) | 1 周 |
| M1 控制面 | DB schema、DMS 同步 CLI 封装、面板域名/邮箱/别名 CRUD、路由规则四类匹配 | 2 周 |
| M2 DNS 自动化 | DNS 生成器、CF Token 管理、batch 一键推送、dig 检测 checklist、BIND 导出 | 1 周 |
| M3 反垃圾与监控 | rspamd 反代与统计页、隔离区放行、队列/日志视图、MXToolbox 体检 | 1 周 |
| M4 产品化 | Roundcube Webmail、Passkey/TOTP、建域向导、Dashboard 用量总览 | 1.5 周 |
| M5 打磨 | 备份/恢复、升级流程、开放 API + 文档、Logo/命名/许可 | 1.5 周 |
| 合计 | ~8 周(多人并行可压到 3–4 周) |
9. 风险与对策
| 风险 | 对策 |
|---|---|
| 25 端口被 VPS 商封锁 | 安装器检测 + 工单指引文档;备选 SMTPS/587 submission |
| 新 IP 无信誉被大厂拒收 | warmup 指引(每天少量发信递增)、rDNS、MXToolbox 体检、黑名单移除指引 |
| DMS 无 DB 导致账号同步故障 | 只用官方 CLI、每日对账告警 |
| DMS 升级破坏兼容 | 锁版本 + 升级前 compat 检查流程 |
| 面板单点故障 | compose restart 策略、SQLite 每日备份、一键恢复文档 |
| 许可证分层 | Clover 主体采用 AGPL-3.0-or-later;Roundcube、docker-mailserver 等第三方组件遵循各自许可证 |
| 邮件 at-rest 加密 | MVP 卷加密指引;P2 做 per-mailbox 加密 |
| 合规 | 建议海外 VPS;文档明示各地政策差异,用户自担 |
10. 待 boss 确认的开放问题
- 面板技术栈:Next.js 单体(推荐,一个容器搞定)/ Go 后端 + Nuxt 前后端分离
- 数据库:SQLite(推荐单机轻量)/ PostgreSQL
- 许可证:AGPL-3.0-or-later(已采用)
- MVP 账号模型:单管理员(推荐,PM 是自助注册但自托管先单管理员)/ 直接做多用户注册
- WebMail:官方 Roundcube 原生客户端
- 是否有现成 VPS + 域名可以尽早开始 M0 验证(25 端口 + 送达率是项目生死线,越早真机验证越好)
- Logo/命名规范(三叶草 🍀 意向已明确)
附:调研过程与原始报告结论已并入第 3 节;如需看某项目细节可展开追查。