SPF 的 10 次 DNS 查询上限具体怎么算?超了会发生什么?

1 SPF 的 10 次 DNS 查询上限具体怎么算?超了会发生什么?
规则原文位置与两条硬限制

RFC 7208 第 4.6.4 节(DNS Lookup Limits)为避免对 DNS 造成不合理负载,设置了两条限制:

  • 总量限制:会引发 DNS 查询的项在一次 SPF 评估中总数不得超过 10超过必须返回 permerror(规范用词为 MUST)。
  • 空查询限制:「void lookup」(返回空答案或域名不存在的查询)建议限制为 2 次,实现可将其做成可配置项,此时推荐默认值为 2;超限产生 permerror

permerror 的后果:SPF 侧不再是「不通过」而是「配置错误」。对 DMARC 而言,这条腿等于直接废掉,只能靠 DKIM 支撑。

哪些计入 10 次:记住这六个

计入总数的是会触发 DNS 查询的机制与修饰符:includeamxptrexistsredirect

不计入的常见项:ip4ip6all。它们直接比对地址,不查 DNS——这正是优化的方向

最容易被低估的一点:计数是递归累加的。include 进去的域,其记录里的 includeamx 同样计入同一个 10 次预算。所以「我自己只写了 3 个 include」完全可能已经超限。

mx 与 ptr 的额外限制

同一节还规定了两个子限制,容易被忽略:

  • mx 机制:对每个 MX 记录,最多查 10 个地址记录。
  • ptr 机制:对每个 PTR 记录,最多查 10 个地址记录。

关于 ptr:它开销大、可靠性差,实际部署中应尽量避免使用。用地址段或 include 替代是更稳妥的选择。

自查方法:手工按层展开计数

不依赖任何在线工具也能自查,步骤如下:

  1. 取出本域 SPF 记录,标出全部计数项(上述六种)。
  2. 对每个 include / redirect 指向的域,取出其 SPF 记录,继续标注其中的计数项。
  3. 逐层累加,直到没有新的展开项。总数就是本次评估的查询数。
  4. 同时留意展开过程中是否出现解析为空或域名不存在的项——这些计入 void lookup 的 2 次预算。

重点:第三方服务商的 SPF 记录会随其架构变更而变化,你今天算出来是 9,下个月可能就变成 11。因此这项检查必须周期化,而不是一次性。

超限了怎么优化:四条路,按优先级
  1. 清理无效项。下线的系统、早已不用的服务商,其 include 常年留在记录里,是最常见的浪费;且失效域会同时消耗 void lookup 预算。先删这些,性价比最高。
  2. a/mx 换成 ip4/ip6对地址稳定的自有出口,直接写地址段,每替换一处就省一次查询,且不再受对方 DNS 波动影响。
  3. 拆分发送域。把营销、通知、事务性邮件分到不同子域各自维护 SPF,从根本上分摊预算。这是最治本的方案,同时也便于分域管理声誉。
  4. 谨慎使用记录扁平化。把第三方 include 展开成 ip4 列表确实能降查询数,但对方一改地址你就会漏发。若采用,必须配套自动化同步与告警,否则是把「超限」换成了更隐蔽的「漏发」。

参考:RFC 7208 Sender Policy Framework (SPF) for Authorizing Use of Domains in Email, Version 1