DNS 和邮件路由
DNS 如何驱动整个电子邮件传递路径——MX 记录、优先级和故障转移、A/AAAA 回退、Null MX、PTR 记录,以及每个发送域需要的 DNS 记录。
邮件路由算法
当发送服务器需要将消息传递到 user@example.com 时,它遵循此算法,定义在 RFC 5321 第 5 节中:
-
查询 MX 记录 针对
example.com - 如果 MX 记录存在,按优先级排序(最低数字 = 最高优先级)
- 对于每个 MX 主机名,解析其 A 和/或 AAAA 记录以获取 IP 地址
- 尝试连接到最高优先级的 MX。如果失败,尝试下一个。
- 如果不存在 MX 记录(NODATA 响应),回退到域的 A/AAAA 记录并在那里尝试传递
- 如果 MX 记录是 Null MX (
0 .),该域不接受邮件——生成永久失败 - 如果域根本不存在(NXDOMAIN),生成永久失败
MX 记录
MX(邮件交换器)记录是用于邮件路由的主要 DNS 记录类型。它将域映射到一个或多个具有优先级的邮件服务器:
10 mx1.example.com.
20 mx2.example.com.
30 mx-backup.example.com.
每条记录有两部分:
- 优先级(偏好值)——较低的数字优先尝试。发送服务器总是首先尝试优先级最低的 MX。
- 交换(主机名)——要连接的邮件服务器。这必须是主机名,绝不是 IP 地址。主机名必须有 A 或 AAAA 记录。
优先级和故障转移
在上面的示例中,发送者首先尝试 mx1.example.com(优先级 10)。如果该服务器无法到达、返回 4xx 临时错误或连接超时,发送者尝试 mx2.example.com(优先级 20),然后是 mx-backup.example.com(优先级 30)。
如果多个 MX 记录具有相同的优先级,发送者应在它们之间随机化。这提供负载均衡:
10 mx2.example.com.
10 mx3.example.com.
这里,所有三个服务器具有相等的优先级。发送服务器为每个传递尝试随机选择一个,在所有三个之间分配负载。
MX 必须指向主机名,而不是 IP
MX 记录的交换字段必须是主机名。它不能是 IP 地址(RFC 5321 明确说明了这一点)。主机名本身必须解析为 A 和/或 AAAA 记录。它不能是 CNAME——虽然某些解析器容忍指向 CNAME 的 MX 目标,但这在技术上是禁止的,会导致互操作性问题。
MX 不能指向 CNAME
这是一个常见的配置错误。如果 mx1.example.com 是指向 mail.provider.com 的 CNAME,某些发送服务器将无法传递。始终为 MX 目标使用 A/AAAA 记录。
A/AAAA 回退
如果域根本没有 MX 记录(甚至没有 Null MX),发送服务器将回退到域的 A 或 AAAA 记录,并在那里尝试 SMTP 传递。这称为"隐式 MX"规则。
tiny-domain.com. IN A 198.51.100.50
发送服务器将尝试在端口 25 上传递到 198.51.100.50。这有效,但对于任何主动发送或接收邮件的域来说都被认为是不好的做法。始终发布显式 MX 记录。
回退仅在零 MX 记录时适用。如果 MX 记录存在但所有 MX 主机都无法到达,发送者不会回退到 A 记录——它会将消息排队以供重试。
Null MX:"此域不接受邮件"
RFC 7505 定义了 Null MX——一种明确声明域不接受电子邮件的方式:
单个点(.)作为交换,优先级为 0,意味着"不尝试传递"。发送服务器应立即生成永久失败(5.1.2——坏目标系统),而不是浪费时间连接。
使用 Null MX 的情况:
- 只发送电子邮件而从不接收的域
- 停放的域
- 专门用于网站托管的域
没有 Null MX,发送者将回退到 A 记录并浪费时间尝试永远不会成功的连接。
PTR 记录:反向 DNS
PTR 记录将 IP 地址映射回主机名。它是 A 记录的反向:
mail.example.com. IN A 198.51.100.42
; 反向查询
42.100.51.198.in-addr.arpa. IN PTR mail.example.com.
PTR 记录不是 MX 路由算法的一部分,但对可传递性至关重要。大多数主要邮箱提供商检查连接服务器 IP 地址的 PTR 记录:
- IP 必须有 PTR 记录(缺少 PTR = 可能是垃圾邮件)
- PTR 主机名应该解析回相同的 IP(前向确认反向 DNS,或 FCrDNS)
- PTR 主机名不应该看起来"通用"(例如,
198-51-100-42.dynamic.isp.com表示住宅连接)
PTR 记录由 IP 地址块的所有者(通常是您的托管提供商或 ISP)管理,而不是通过您域的 DNS。您可能需要联系您的提供商来设置或更改 PTR 记录。
每个发送域需要的 DNS 记录
这是通过 Mailer To Go 等服务发送电子邮件的域的完整 DNS 记录集:
example.com. IN MX 10 mx1.example.com.
example.com. IN MX 20 mx2.example.com.
; MX 主机的 A 记录
mx1.example.com. IN A 203.0.113.10
mx2.example.com. IN A 203.0.113.11
; SPF 记录(谁可以以此域名发送)
example.com. IN TXT "v=spf1 include:_spf.mailertogo.com -all"
; DKIM 公钥(用于签名验证)
mtg._domainkey.example.com. IN CNAME mtg._domainkey.mailertogo.com.
; DMARC 策略
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
; MTA-STS 策略(对传入邮件强制 TLS)
_mta-sts.example.com. IN TXT "v=STSv1; id=20260311"
; TLSRPT(TLS 失败报告)
_smtp._tls.example.com. IN TXT "v=TLSRPTv1; rua=mailto:tls-reports@example.com"
对于仅发送邮件但不接收邮件的域(例如,用于事务性电子邮件的子域):
notifications.example.com. IN MX 0 .
; SPF、DKIM、DMARC 如上
notifications.example.com. IN TXT "v=spf1 include:_spf.mailertogo.com -all"
mtg._domainkey.notifications.example.com. IN CNAME mtg._domainkey.mailertogo.com.
_dmarc.notifications.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
TTL 考虑
DNS 记录有一个生存时间 (TTL),控制解析器缓存它们的时间长度。对于邮件相关记录:
- MX 记录: 1 小时 (3600) 是典型的。较低的 TTL 允许更快的故障转移,但会增加 DNS 查询负载。
- SPF/DKIM/DMARC 记录: 1 小时很常见。在初始设置或更改期间使用较短的 TTL(300 秒),然后增加。
- MX 主机的 A/AAAA 记录: 5 分钟到 1 小时。如果需要快速 IP 更改,则更短。
进行 DNS 更改时,在更改之前减少 TTL(等待旧 TTL 过期),进行更改,验证,然后将 TTL 增加回操作值。
DNSSEC 和邮件
DNSSEC(DNS 安全扩展)向 DNS 记录添加密码签名,防止欺骗和缓存中毒。对于电子邮件,DNSSEC 特别重要,因为:
- 它验证 MX 记录——攻击者不能通过中毒 DNS 将邮件重定向到恶意服务器
- 它是 DANE(基于 DNS 的命名实体身份验证)所必需的,它将 TLS 证书绑定到 DNS
- 它验证 SPF、DKIM 公钥和 DMARC 记录
没有 DNSSEC,网络攻击者可以伪造 DNS 响应并重定向或截获电子邮件。电子邮件域的 DNSSEC 采用在增加,但还不是通用的。
电子邮件提交的 SRV 记录
RFC 6186 定义了 SRV 记录,邮件客户端可以使用这些记录来自动发现提交和 IMAP/POP 服务器:
_imaps._tcp.example.com. IN SRV 0 1 993 imap.example.com.
_pop3s._tcp.example.com. IN SRV 0 1 995 pop.example.com.
这些用于邮件客户端自动配置——当用户输入其电子邮件地址时,客户端查询 SRV 记录以查找正确的服务器、端口和协议。这与基于 MX 的服务器到服务器路由分开。
可能出错的地方
缺少 MX 记录
没有 MX 记录,发送者会回退到您的 A 记录。如果您的网络服务器在端口 25 上没有运行 SMTP 服务器,邮件传递会在超时后失败。始终发布显式 MX 记录,或者如果您不接受邮件,则发布 Null MX。
MX 指向 CNAME
如上所述,这在技术上是无效的。某些发送者会跟随 CNAME;其他人会失败。为所有 MX 目标主机名使用 A/AAAA 记录。
循环 MX 引用
如果 example.com 有指向 mail.example.com 的 MX,而 mail.example.com 有自己的 MX 指向回 example.com,邮件可能会循环。MX 目标应该是仅具有 A/AAAA 记录的叶主机名。
缺少 PTR 记录
您的发送 IP 没有反向 DNS,或它解析为通用 ISP 主机名。主要邮箱提供商(Gmail、Microsoft、Yahoo)会延迟或拒绝您的邮件。确保您的发送 IP 有 PTR 记录,解析回相同的 IP。
传递期间 DNS 超时
如果收件人域的 DNS 服务器缓慢或无法访问,发送服务器无法解析 MX 记录。该消息排队以供重试。持续的 DNS 失败最终导致反弹(通常在 4-5 天后)。作为发送者,您无能为力——这是收件人的基础设施问题。
SPF 记录超过 DNS UDP 限制
DNS 响应在 UDP 上限制为 512 字节(使用 EDNS0 时为 4096)。具有许多 include: 指令的很长 SPF 记录可能会被截断。解析器回退到 TCP,这会增加延迟,如果 DNS 服务器不支持 TCP,可能会失败。保持您的 SPF 记录简洁。
调试邮件 DNS
用于诊断邮件路由问题的基本命令:
$ dig MX example.com +short
10 mx1.example.com.
20 mx2.example.com.
# 验证 MX 目标解析为 IP
$ dig A mx1.example.com +short
203.0.113.10
# 检查 PTR(反向 DNS)
$ dig -x 198.51.100.42 +short
mail.example.com.
# 验证前向确认反向 DNS
$ dig A mail.example.com +short
198.51.100.42
# 检查 SPF 记录
$ dig TXT example.com +short | grep spf
"v=spf1 include:_spf.mailertogo.com -all"
# 检查 DKIM 公钥
$ dig TXT mtg._domainkey.example.com +short
"v=DKIM1; k=rsa; p=MIIBIjANBgkqh..."
# 检查 DMARC 策略
$ dig TXT _dmarc.example.com +short
"v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
# 检查 Null MX
$ dig MX no-mail.example.com +short
0 .
关键要点
- MX 记录是邮件路由的主要机制。较低的优先级数字优先尝试。
- 如果不存在 MX 记录,发送者会回退到 A/AAAA 记录。发布显式 MX 记录(或 Null MX)以避免歧义。
- MX 目标必须是具有 A/AAAA 记录的主机名——绝不是 IP,绝不是 CNAME。
- PTR 记录(反向 DNS)不是路由的一部分,但对可传递性至关重要。每个发送 IP 都需要一个与前向 A 记录匹配的 PTR。
- 完整的发送域至少需要 MX(或 Null MX)、SPF、DKIM 和 DMARC 记录。
- 在更改前后使用
dig验证每个 DNS 记录。