术语 · 检查 SPF 记录
如何检查应用邮件的 SPF 记录?
应在 SMTP MAIL FROM 地址所用的域名上检查 SPF,而不是自动检查可见 From 域名。查询 TXT,选取以 v=spf1 开头的那条记录,验证每一项,针对发信 IP 从左至右评估机制,并在跟踪 include 或 redirect 时统计会触发 DNS 查询的项。随后确认收件方的 SPF 结果,以及经身份验证的域名是否与 DMARC 对齐。SPF 通过会授权发信客户端使用某个 SMTP 身份;它不证明 DKIM、DMARC、投递或收件箱送达率。
从 SPF 实际检查的身份入手
一次 SPF 检查需要三个输入:SMTP 客户端的 IP 地址、要评估其授权策略的域名,以及发件人身份。对于普通的应用邮件,这个域名取自 SMTP MAIL FROM 地址,也称为信封发件人或 Return-Path。它可能与收件人在邮件 From 头中看到的地址不同。如果 MAIL FROM 为空(投递状态通知通常就是如此),SPF 会用 HELO 身份来完成 MAIL FROM 检查。在查询 DNS 之前,请先从收到的测试邮件或发信服务商的配置中记下真实的连接 IP 和信封身份。如果应用实际使用 bounce.provider.test 或 bounces.example.test 上的 MAIL FROM 发信,那么仅仅因为 example.test 出现在 From 中就去检查它,得出的结论并不可靠。
在确切的 MAIL FROM 域名上查询 TXT
在第一步确定的确切域名上查询 DNS TXT 记录。RFC 7208 要求 SPF 版本 1 的策略以 TXT 记录的形式发布在其所管辖的所有者名称上。忽略无关的 TXT 值,只选出版本部分恰好为 v=spf1 的记录。没有选出任何记录时,SPF 结果为 none。选出多于一条 SPF 记录时,结果为 permerror;为不同服务商分别发布多条记录并不是合并它们的有效方式。DNS 工具可能会把单条 TXT 资源记录拆分成多个带引号的字符串,但在解析 SPF 之前,这些字符串会被直接拼接,中间不插入空格。请记录完整的应答、解析器、查询时间和 TTL,以便在变更后重复检查。
校验语法,并从左到右评估各项
SPF 记录是一条有顺序的策略,而不是一份无序的服务商列表。在 v=spf1 之后,各机制按从左到右的顺序评估,直到某个机制匹配为止。前置限定符决定结果:+ 表示 pass,为默认值;- 表示 fail;~ 表示 softfail;? 表示 neutral。ip4 和 ip6 机制将客户端地址与某个地址或网段进行比较。a 和 mx 机制需要解析 DNS,而 include 会评估另一个域名的 SPF 策略,并且只按 include 的规则匹配。exists 执行一次基于 DNS 的测试。all 总是匹配,通常用来结束记录。任何位置的语法错误都会在正常评估之前导致 permerror。一个有用的检查工具应当报告匹配的是哪个机制、它的限定符以及每个展开的域名,而不是只返回一个彩色徽标。
追踪 include 和 redirect,不要把它们当成别名
在同一个评估上下文中跟踪每一个 include 和 redirect。include 是一种机制:它判断被包含的策略对当前客户端和发件人是否返回 pass,如果不匹配,则回到原记录继续评估。redirect 是一个修饰符,只有在当前记录的所有机制都未匹配时才会被考虑;它会把评估转交给另一个策略,同时保留客户端 IP 和发件人。如果记录中任何位置出现了 all,redirect 就会被忽略。这些差异在迁移时非常重要。将 include:vendor.test 替换为 redirect=vendor.test,可能会替换掉域名所有者的整个兜底策略,而不仅仅是添加一个服务商。请检测循环引用、缺失的目标、无效的目标,以及嵌套的永久性或暂时性错误,并在结果中保留依赖链,以便服务商一侧的策略变更能够被发现。
统计完整的 DNS 查询预算
统计整个递归评估过程中所有会触发 DNS 查询的项,而不仅仅是顶层记录中的项。RFC 7208 规定,一次 SPF 评估中 include、a、mx、ptr、exists 和 redirect 项总数不得超过十个;超出上限时必须返回 permerror。all、ip4 和 ip6 机制不占用这一预算。MX 和 PTR 的处理还有额外的地址查询上限。该 RFC 还建议将空查询(即成功但应答为空,或返回名称错误的查询)限制为两次,超出时返回 permerror。不建议使用 ptr 机制,因为它既慢又不可靠。一条记录看起来可能很短,但服务商的 include 展开后,嵌套项的数量可能足以导致失败。因此,请报告总数、每个计入的项、空查询次数,以及针对被测 IP 实际走过的分支。
解读 SPF 结果,但不要夸大其含义
请使用标准的结果术语。pass 表示被测客户端有权使用所检查的 SMTP 身份。fail 表示找到了一条匹配的否定授权。softfail 是一种较弱的否定声明,而 neutral 表示该域名对这个客户端不作任何断言。none 表示没有选出 SPF 记录。temperror 反映的是暂时性的评估问题,通常与 DNS 有关;permerror 则表示策略本身无法被正确评估。如果没有任何机制匹配,也没有适用的 redirect,结果为 neutral,相当于隐含的 ?all。报告结果时,请同时给出身份、客户端 IP、匹配的项、DNS 追踪记录和时间。不要把 pass 解读为邮件安全、收件人想要这封邮件、服务商已受理、已投递到邮箱或进入收件箱,因为这些结果都不由 SPF 决定。
检查真实的邮件,而不只是已发布的记录
静态的记录检查只能回答策略能否被发现和解析,并不能证明应用实际使用了预期的 MAIL FROM 域名或出站 IP。请通过每一条真实的生产路径,向您管理的收件账户发送一封受控的测试邮件,然后检查收到的邮件头。将连接 IP、信封发件人以及收件方的 Authentication-Results 条目与 DNS 评估结果进行对比。对于每个服务商、区域、独享或共享 IP 池、备用路径,以及可能改变 Return-Path 的每类邮件,都要重复这一过程。由于地址和路由细节可能属于敏感信息,请将邮件头保存在访问受限的存储中。如果服务商控制台与实际收到的邮件不一致,后者更能说明实际走的是哪条路径;但单个收件方的结果仍不应被推广为普遍的投递行为。
将 DMARC 对齐作为单独的一步来评估
即使服务商自有的 Return-Path 域名通过了 SPF,DMARC 仍可能无法使用这一结果。现行 DMARC 规则会将通过 SPF 验证的 RFC5321.MailFrom 域名与可见的 RFC5322.From 字段中的作者域名进行比较。严格对齐要求两者是同一个 DNS 域名。宽松对齐则允许两者按照 DMARC 的发现规则解析到同一个组织域名。例如,在宽松模式下 bounces.example.test 与 example.test 可以对齐,而 bounce.provider.test 与 example.test 不能对齐。DMARC 结果也可以依赖一个已对齐且验证通过的 DKIM 签名,因此 SPF 未对齐本身并不意味着 DMARC 失败。请分别报告身份验证和对齐情况,并使用现行的域名发现流程,而不是写死“比较最后两个标签”的做法。
测试特定服务商的 MAIL FROM 配置
服务商的配置决定了实际传输中出现的是哪个 SPF 身份。以 Amazon SES 为例,其文档说明自定义 MAIL FROM 域名需要单独的 MX 记录和 SPF TXT 记录。当自定义域名的 MX 配置错误时,SES 可能会回退到一个与区域相关的 amazonses.com MAIL FROM 域名,也可能直接拒绝发送,具体取决于所配置的行为。即使可见的 From 地址没有变化,这种回退也可能改变 DMARC 对齐结果。对于任何服务商,都请记录所配置的 Return-Path 域名、所需的 DNS 值、回退行为、发信区域和负责人。在 DNS 或服务商变更之后,等待相关的缓存应答过期,然后重新进行 DNS 评估和受控发送。除非某个服务商确实是可见 From 域名的实际发信身份,并且该域名完整的发件方清单支持这样做,否则不要把该服务商的 include 复制到可见的 From 域名上。
在变更期间使用可复现的 SPF 审计
为每条发信路径维护一行记录,包括负责人、应用、邮件类别、可见 From 域名、MAIL FROM 域名、HELO 域名、预期的来源地址段、所依赖的服务商,以及最近一次受控测试的时间。保存每次 SPF 检查的结果,包括选出的记录、递归追踪、DNS 查询次数、匹配的机制、结果、对齐判定和一个不含敏感信息的测试标识符。在迁移期间,只在必要的过渡窗口内同时授权新旧两套合法来源,验证新路径后,再有计划地移除过时的授权。监控永久性和暂时性的身份验证错误,而不是只在出现拒收时才作出反应。在服务商变更、IP 池迁移、域名变更、DNS 修改或新增应用之后,重新执行审计。这一流程既能发现过窄、会阻断合法路径的策略,也能发现过宽、保留了无用授权的策略。
以相同证据标准检查 SendHQ
SendHQ 文档说明,直接发送必须使用已验证工作区域名上的地址。这会验证发信身份,但不能替代 SPF 评估。受控 SendHQ 邮件仍需要如上所述的 DNS 跟踪、接收邮件头检查、SPF 结果和 DMARC 对齐检查。
常见问题
检查 SPF 时应该使用哪个域名?
对于普通邮件,使用 SMTP MAIL FROM 地址中的域名。如果反向路径为空,则按 RFC 7208 的规定使用 HELO 身份。不要默认可见的 From 域名就是 SPF 身份。
一个域名可以为两个服务商发布两条 SPF 记录吗?
不可以。如果 DNS 记录选择过程找到多于一条以 SPF 版本部分开头的记录,评估将返回 permerror。请将受支持的机制合并到一条策略中,同时不要超出语法、长度和递归 DNS 查询的限制。
一条 SPF 记录最多可以进行多少次 DNS 查询?
在整个递归处理过程中,一次评估最多只能使用十个会触发 DNS 查询的 include、a、mx、ptr、exists 和 redirect 项。超出上限会产生 permerror。直接写出的 ip4、ip6 和 all 机制不占用这一预算。
SPF 通过是否意味着 DMARC 通过?
不一定。只有当通过验证的 MAIL FROM 身份在所配置的严格或宽松模式下与可见的 From 域名对齐时,DMARC 才能使用 SPF 结果。一个已对齐且验证通过的 DKIM 签名也可以作为另一个经过验证的标识符。
为什么在线 SPF 查询工具的结果与收到的邮件不一致?
该工具可能检查的是可见的 From 域名、使用了不同的客户端 IP、读到了不同的 DNS 缓存视图,或者遗漏了某个嵌套错误。请将它的输入与真实邮件的信封身份、连接路径和收件方的身份验证结果进行对比。
更换邮件服务商后应该检查哪些内容?
检查每一个新旧 MAIL FROM 域名、递归的 SPF 依赖、DNS 查询次数、实际来源 IP、服务商的回退行为、收到邮件中的 SPF 结果以及 DMARC 对齐情况。在移除旧授权或增加发送量之前,先测试每一类邮件。
参考来源
- RFC 7208:Sender Policy Framework(发件人策略框架) — IETF
- RFC 5321:Simple Mail Transfer Protocol(简单邮件传输协议) — IETF
- RFC 9989:Domain-Based Message Authentication, Reporting, and Conformance(基于域的邮件身份验证、报告与一致性) — RFC Editor
- 在 Amazon SES 中使用自定义 MAIL FROM 域名 — Amazon Web Services
- SendHQ OpenAPI 接口约定 — SendHQ