技术指南
邮件服务上线:验证 DNS 身份、中继边界与回滚
把邮件服务上线拆成 DNS 身份、认证提交、中继拒绝、队列证据、渐进投递与隔离恢复。
自建邮件服务不是把几个端口打开后等待收件。上线前必须证明域名身份、收信路径、认证提交、中继边界、队列可见性和恢复路径分别成立;SPF、DKIM、DMARC 通过也只说明认证条件,不承诺进入收件箱。
来源提供产品与配置清单,本文改成上线证据链
归档来源覆盖 Mailcow、邮件套件、DNS 记录、端口、反向代理、备份、监控和第三方 SMTP 中继。它强调 PTR、SPF、DKIM、DMARC、队列和备份是长期责任,这些方向可保留;固定内存与价格、默认凭据、产品排名、控制台路径、复制即用安装命令和‘评分等于送达’不进入本文。当前 mailcow 默认最低配置与 DMARC 标准也已变化,必须以当前主文档重新核对。
先判断是否应该自建完整邮件系统
| 需求 | 更合适的起点 | 自建前必须承担 |
|---|---|---|
| 个人或团队邮箱 | 托管邮箱或受支持的群件服务 | 垃圾邮件、账号安全、可用性、迁移与恢复 |
| 应用通知与事务邮件 | 可审计的 SMTP/API 中继 | 退信、投诉、抑制名单、密钥轮换与供应商边界 |
| 必须控制邮件数据与策略 | 先做受限自建 canary | MTA、DNS 身份、反滥用、队列、日志、升级和 24x7 响应 |
VPScope 的判断是:如果没有 postmaster 责任人、独立控制台、备份恢复、退信处理和滥用响应,自建不是‘更私有的默认项’,而是尚未满足上线条件。可把收信、用户邮箱和应用出信拆开选择,不必由一台主机承担全部角色。
把四条流向写成邮件契约
| 流向 | 允许主体 | 成功证据 | 失败与回退 |
|---|---|---|---|
| 互联网收信 | 外部 MTA 到本域 MX | 本地收件、队列 ID、最终投递 | 4xx 暂缓、5xx 永久拒绝、备用 MX 策略 |
| 用户提交 | 经认证用户或设备 | 认证、TLS、发件身份与队列 ID | 撤销凭据、限制来源、停止提交 |
| 应用出信 | 明确的应用身份 | 独立凭据、envelope-from、DKIM 与 DSN | 暂停生产者或切回已审中继 |
| 管理与恢复 | 最小权限运维人员 | 控制台、备份、配置版本和演练记录 | 不依赖待修复邮件路径的独立入口 |
先核对当前资源、虚拟化与出站约束
截至 2026-08-17,mailcow 当前默认最低要求为 6 GiB RAM 加 1 GiB swap,并要求完整虚拟化、当前 Docker 与 Compose;具体功能、垃圾邮件负载、邮箱规模和备份窗口还会增加需求。不要沿用来源中的 2–4 GiB 旧建议,也不要仅凭空闲内存决定上线。先确认供应商是否允许 TCP/25、PTR 是否可控、IPv6 是否实际使用,以及控制台能否在网络规则失误时恢复。
date -u
hostnamectl
timedatectl status
free -h
df -hT
ss -lntup
docker version
docker compose version先让 A、PTR、MX 与实际发送路径相互指向
| 记录 | 要证明什么 | 常见失败 |
|---|---|---|
| A / AAAA | 邮件主机名指向实际接收或发送地址 | 发布未使用的 IPv6,或地址仍指向旧主机 |
| PTR | 使用中的发送地址反解到邮件主机名 | 无法控制 PTR,或反解名不能正向回同一地址 |
| MX | 域名收件目标是可达的邮件主机名 | MX 指向 IP、旧主机或未开放的地址族 |
| HELO/EHLO | MTA 使用可解析、稳定的自身身份 | 使用 localhost、临时主机名或与 PTR 无关的名称 |
domain=example.com
mailhost=mail.example.com
ipv4=192.0.2.25
selector=s20260817
dig +short A "$mailhost"
dig +short AAAA "$mailhost"
dig +short -x "$ipv4"
dig +short MX "$domain"
dig +short TXT "$domain"
dig +short TXT "${selector}._domainkey.${domain}"
dig +short TXT "_dmarc.${domain}"SPF 只授权 envelope-from 使用哪些发送端
一个域名应得到一份可评估的 SPF 策略,覆盖真实发送源和经过批准的中继。RFC 7208 不允许从多份 SPF 策略中任选一份;新增供应商时应合并、审阅 DNS 查询依赖,并移除旧来源。SPF 不验证可见 From 正文,也不替代 DKIM 或 DMARC 对齐。
DKIM 用选择器支持可重叠轮换
私钥只留在签名系统,DNS 发布选择器公钥。先发布新选择器并从外部解析器确认,再让 canary 使用新私钥;保留旧记录覆盖在途和延迟邮件的验证窗口,确认新签名稳定后才撤旧。DNS TXT 可能由多段字符字符串组成,读取时应按顺序拼接,不能把引号或分段误判为两把密钥。
openssl s_client -starttls smtp -connect mail.example.com:25 \
-servername mail.example.com -verify_return_error </dev/null
openssl s_client -starttls smtp -connect mail.example.com:587 \
-servername mail.example.com -verify_return_error </dev/null
openssl s_client -connect mail.example.com:993 \
-servername mail.example.com -verify_return_error </dev/nullDMARC 先观察对齐,再逐步执行策略
RFC 9989 在 2026 年取代 RFC 7489 与 RFC 9091。DMARC 评估可见 From 域与通过的 SPF 或 DKIM 身份是否对齐;它不是新的传输认证协议。通常先用 `p=none` 与 `rua` 收集代表性聚合报告,盘点每一类合法发送流,再按风险逐步收紧。未经观察直接设为 reject 可能拒绝遗漏的合法系统。
接收、提交与读取是不同边界
| 接口 | 典型用途 | 上线检查 |
|---|---|---|
| TCP/25 | MTA 之间的 SMTP 接收与发送 | 供应商策略、双向可达、TLS、队列与拒绝语义 |
| TCP/587 | 认证用户或应用提交 | 必须认证、TLS、速率与发件身份限制 |
| TCP/465 | 支持时的隐式 TLS 提交 | 客户端兼容与认证策略,不替代 587 检查 |
| TCP/993 | 隐式 TLS 的 IMAP 读取 | 证书、账号策略、并发与邮箱权限 |
实际开放端口以所选软件当前文档和启用功能为准。管理面、数据库、缓存、指标和容器内部端口不应因邮件服务上线而自动暴露公网。云防火墙、主机防火墙、监听地址和容器发布规则必须得到同一结论。
用 RCPT 阶段证明未认证外发被拒绝
Postfix 官方文档把中继策略建立在本地域、可信网络和认证身份上,且限制顺序会改变结果。用自己控制的外部测试主机建立未认证会话:投递到本域测试收件人应按策略接受;把收件人换成另一个受控外域时,应在 `RCPT TO` 阶段明确拒绝。随后从认证提交接口向同一外域 canary 验证允许。不要完成向陌生地址的投递来‘证明’开放中继。
EHLO probe.example.net
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]> # 本域:按收信策略判断
RSET
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]> # 未认证外域:必须拒绝
QUIT队列 ID 与最终状态比客户端的 sent 更重要
| 证据 | 能回答的问题 | 不能省略 |
|---|---|---|
| 接收日志与 queue ID | 哪一会话接受了哪封消息 | 时间、连接端、envelope-from、recipient |
| 4xx / deferred | 远端要求稍后重试或本地依赖暂时失败 | 下一次尝试、队列年龄与告警门槛 |
| 5xx / bounced | 永久拒绝或策略失败 | 增强状态码、DSN、抑制后续无效重试 |
| delivered / removed | 本 MTA 已完成其负责的下一跳 | 不等于进入收件箱或被用户阅读 |
RFC 5321 区分临时失败和永久失败。应用拿到提交成功只表示 MTA 接受了责任,不表示最终送达;必须关联队列、DSN、退信、投诉和远端响应。日志与邮件地址属于敏感数据,应限制访问、字段与保留期。
从一条发送流和少量同意收件人开始
- 先验证本域收件、本地投递、读取与回复,保存原始头部和队列 ID。
- 从认证提交发送到自己控制的不同提供商测试邮箱,检查 TLS、SPF、DKIM、DMARC 与 Authentication-Results。
- 故意使用一个不存在的受控本域地址,确认退信和应用抑制流程可见。
- 按发送流分开观察事务、人工邮箱和批量消息,不共享无法归因的凭据与 envelope-from。
- 在完整业务窗口内监控队列年龄、4xx/5xx、投诉与账号异常,再逐组扩大。
Gmail 当前发件人指南要求认证、正反向 DNS、TLS、格式与低垃圾邮件率等条件,并对批量发件人增加 SPF、DKIM、DMARC 和对齐要求。满足这些是进入评估的基础,不是收件箱承诺;内容、收件人同意、投诉、信誉和发送节奏仍需持续观察。
第三方中继改变责任边界,不会消除身份工作
切换 smart host 前重新核对 envelope-from、可见 From、SPF include、DKIM 签名方、DMARC 对齐、退信/投诉回传和凭据权限。为每个应用使用独立凭据并能快速撤销。中继服务的地区、限额、价格和政策会变化,不能把来源中的固定套餐写成恢复保证。
备份配置、密钥和邮件,再证明隔离恢复
mailcow 当前官方备份入口是仓库内的 `helper-scripts/backup_and_restore.sh`,并明确提醒不要把脚本复制到别处运行。按实际组件和版本使用官方流程,保护 DKIM 私钥、证书、数据库、邮箱数据与配置;但一次备份成功仍不证明可恢复。
- 在与生产隔离的主机或网络恢复,避免重复收信和误发邮件。
- 记录源版本、目标版本、备份摘要、恢复耗时和缺失组件。
- 以只读方式核对账号、域、别名、邮件样本、队列配置和 DKIM 选择器。
- 恢复实例不接管生产 MX,也不持有可向真实用户发送的有效凭据。
- 定期轮换恢复样本,并证明仓库密码、密钥和控制台能独立取回。
回滚先停止新流量,再保全队列证据
触发条件可以是开放中继、认证失败、队列持续老化、合法邮件大面积 5xx、PTR/对齐错误、异常投诉或恢复目标失效。先暂停应用生产者或用户提交,保留队列和日志;再恢复上一份 DNS、路由、配置或已审中继。不要用清空队列掩盖故障,也不要让 DNS 回滚同时丢失尚未归因的消息。
隔离演练验证了 DNS 身份与 DKIM 轮换边界
VPScope 在回环地址 127.0.0.1:15325 启动一次性权威 DNS,使用保留域 `example.test` 和地址 192.0.2.25。固定 SHA-256 的 dkimpy 1.1.8 与 dnslib 0.9.26 源码通过校验;生成的 2048-bit RSA 公钥按 DNS 字符串限制分段发布。A、PTR、MX、单一 SPF、DMARC 和两个 DKIM 选择器均按预期解析。
当前和上一选择器各自签名后都通过真实 DNS 查询验证;正文篡改、错误公钥和不存在的选择器均失败。测试没有建立 SMTP 连接或发送邮件,不能证明端口、TLS、认证、开放中继拒绝、队列、远端接收、信誉或收件箱位置。DNS 子进程停止,端口关闭,一次性密钥、消息和依赖目录由 EXIT trap 删除。
邮件服务上线前的可复查清单
- 自建理由、责任人、收信、提交、应用出信和独立恢复路径已经写入邮件契约。
- 当前软件资源、虚拟化、Docker/Compose、供应商 TCP/25 与 PTR 能力已重新核对。
- 使用中的每个 IPv4/IPv6 都有一致 A/PTR、稳定 HELO,并在 MX 与防火墙路径中实际可达。
- SPF 只有一份可评估策略;DKIM 新旧选择器完成重叠验证;DMARC 从代表性报告与对齐证据逐步收紧。
- 管理面与内部组件没有随邮件端口公开,TLS 按接收、提交和读取分别验证。
- 未认证外域 RCPT 被拒绝,认证提交与本域收件各自在受控 canary 上成功。
- 队列 ID、4xx/5xx、DSN、退信、投诉与应用消息可以关联,提交成功没有被写成最终送达。
- 第三方中继若启用,SPF、DKIM、DMARC、退信和凭据责任已重新建模。
- 备份在隔离环境恢复并完成应用级检查,不会接管生产 MX 或误发邮件。
- 暂停生产者、保存队列、恢复旧配置/路由和逐步重开已经演练。