术语 · SPF 记录语法
什么是 SPF 记录语法?它如何影响应用邮件?
SPF 记录语法是一条以空格分隔的 DNS TXT 策略,以 v=spf1 开头,后面跟着用于匹配已授权发信来源的机制,以及可选的 redirect 或 explanation 修饰符。机制可以带有 +、-、~ 或 ? 作为结果限定符;常见的机制包括 ip4、ip6、a、mx、include、exists 和 all。顺序很重要,因为评估会在第一个匹配的机制处停止。每个确切的域名只发布一条 SPF 策略,将会触发 DNS 查询的项控制在协议限制之内,测试每一个真实的信封发件人,并记住 SPF 验证的是 SMTP 身份,并不会自动验证可见的 From 域名,也不代表邮件会进入收件箱。
SPF 记录是一个有序的策略表达式
RFC 7208 将 SPF 记录定义为一个 DNS TXT 字符串,其第一项为 v=spf1。其余以空格分隔的项分为两类:可以匹配的机制,以及改变处理方式的修饰符。评估从左到右进行,并在第一个匹配的机制处停止,因此顺序本身就表达了策略。一条典型的记录可能会授权两个固定的地址范围,包含一个服务商的策略,最后以 -all 结尾。不要原样照抄这种模式:正确的记录取决于确切的 SMTP MAIL FROM 或 HELO 身份以及真实的发信来源。请先盘点应用服务商、邮件服务器、客服工具、身份平台、营销系统、转发路径和灾备发件方。将策略发布在被评估的域名上,而不是自动发布在可见 From 域名上。一条语法有效的记录仍可能授权了错误的来源、遗漏了某条生产邮件流,或超出 DNS 评估限制。
限定符将机制的匹配映射为 SPF 结果
机制可以以限定符开头:+ 表示 pass,- 表示 fail,~ 表示 softfail,? 表示 neutral。如果没有限定符,则默认为 +。限定符只在该机制匹配时生效。当机制不匹配时,它并不影响后续各项是否继续评估。团队往往只关注最后的 all 项,但之前的每个 include、地址、a、mx 或 exists 机制同样带有限定符,并且都可能终止评估。请进行明确的审查,不要以为 ~all 就代表测试模式,或 -all 就证明所有来源都已知。fail 结果是收件方针对被评估的 SMTP 身份和 IP 得出的证据,而不是删除邮件的通用指令。收件方会应用各自的本地策略。neutral 和 softfail 都不算授权通过。记录已授权、未授权以及暂时无法解析的来源分别应得到的结果,并使用受控的 IP 和身份测试数据进行验证。
地址类机制直接明了,但需要明确归属
ip4 和 ip6 机制授权匹配的网络范围,这些范围按各自协议的语法书写,并可带有前缀长度。它们在评估时不需要额外的地址查询,但随着出口网络的变化可能会过时。请使用公网发信地址,绝不要使用运行环境的私有地址,并在运营故障切换允许的范围内尽量缩小地址范围。每个地址范围都应有负责人、来源系统、环境、变更流程和审查日期。a 机制解析 A 或 AAAA 名称,除非提供了其他 domain-spec,否则默认使用当前 SPF 域名。mx 机制解析 MX 主机及其地址。这些机制会增加 DNS 查询工作量,并可能授权那些在应用发布流程之外发生变化的基础设施。除非所有解析出的地址都被有意允许使用该确切的 SMTP 身份发信,否则不要把 a 或 mx 当作捷径。监控变更,并同时测试 IPv4 和 IPv6 路径。
include 评估的是另一条策略,而不是一段文本片段
include 机制会评估被引用域名的 SPF 策略,并在该嵌套评估返回 pass 时匹配。它并不是把各项机械地粘贴到当前字符串中,而且其他嵌套结果也有各自明确定义的效果。只有当被引用的组织明确说明该域名适用于您与其之间的发信关系时,才使用 include。服务商的网站域名、MX 域名或可见 From 域名,并不自动就是它的 SPF include。include 会带来运营上的依赖:服务商修改记录可能改变授权范围、增加嵌套的 DNS 查询,或产生暂时性和永久性错误。记录供应商、服务、确切的 include 域名、合同来源、负责人和移除计划。从服务商实际的发信 IP 和您的信封域名出发测试最终的策略。除非您同时愿意负责跟踪服务商每一次地址变更并保持原有语义,否则绝不要把服务商的 include 展平为复制来的 IP 列表。
all、redirect 和 explanation 各有不同的作用
all 机制总是匹配,通常放在最后;它之后的项不会影响评估。它的限定符决定了之前未匹配的来源得到什么结果。redirect 修饰符告诉 SPF,在当前记录中没有任何机制匹配时,改用另一个域名的策略。redirect 与 include 不同:include 是有序列表中的一个机制,而 redirect 在其定义的条件下取代最终的策略决定。一条记录不应包含多个 redirect 修饰符。exp 修饰符可以为 fail 结果引用一段说明,但它并不授权邮件,还会带来额外的运营和隐私方面的考量。请保持说明内容通用,避免包含发件人或收件人数据。当多个域名有意共享整条策略且归属协调一致时,选择 redirect。当需要在更宽泛的本地策略中加入某个服务商的授权来源时,选择 include。不仅要测试预期通过的情况,也要测试未匹配的路径。
避免使用 ptr,并将 exists 和宏视为高级用法
RFC 7208 指出不应使用 ptr 机制,因为它速度慢、不可靠且负担重。不要为了让某个不熟悉的 IP 通过而添加 ptr。exists 机制可以使用 domain-spec 执行 DNS 存在性测试,而 SPF 宏可以在受支持的字段中展开身份和连接的组成部分。这些工具可以表达委派式或按客户划分的授权,但会增加复杂度、DNS 查询工作量、隐私暴露和故障模式。宏语法并不是任意的字符串模板;只有已定义的字母、转换符、分隔符和上下文才有效。绝不要把完整的收件人地址、机密信息或不受限制的租户输入放入 DNS 查询中。如果一组自有 IP 范围加上有文档说明的服务商 include 就能表达该策略,请优先采用这种方式。对于高级策略,在投入生产之前,请针对多个域名、发件人、IP 协议族、空反向路径、宏转义、NXDOMAIN、超时和意外的 DNS 应答构建确定性的测试数据。
遵守 10 次 DNS 查询上限
RFC 7208 规定,SPF 实现在一次检查中最多只能处理 10 个会触发 DNS 查询的项,包括相关的 include、a、mx、ptr、exists 和 redirect 处理。嵌套的 include 也计入其中。规范还建议将空查询(即 DNS 返回空应答或名称错误)限制为 2 次。超出处理限制可能会产生永久性错误,而不是通过。请统计展开后的整个评估图,而不仅仅是顶层 TXT 字符串中可见的项。一个服务商的 include 可能带来多个嵌套依赖,而一个 mx 机制可能会针对多个主机触发地址查询。使用遵循标准的评估工具并配合采集的 DNS 测试数据,但也要亲自检查依赖树。移除不再使用的服务商和冗余的机制。避免不安全的展平操作,以免悄悄丢失服务商的更新。监控策略变更,并为服务商的演进预留查询余量,而不是恰好卡在上限部署。
每个域名只发布一条 SPF 策略
RFC 7208 使用 DNS TXT 记录承载 SPF,并要求选取以 v=spf1 开头的那条记录。同一个确切的所有者名称下存在多条 SPF 记录会导致永久性错误,而不是合并授权。请在协调一致的归属下修改现有策略;不要因为另一个应用需要权限就添加第二条 TXT 记录。该名称下可以共存其他无关的 TXT 记录,但只应存在一条被选中的 SPF 策略。确认 DNS 管理平台的引号处理和字符串拆分行为,先查询权威服务器,再查询独立的递归解析器。保留之前的值和 TTL 以便回滚。DNS 传播并非即时完成,否定缓存也可能持续存在。控制台上的绿色勾选只能证明它自己观测到的查询和解析行为。请根据原始收件邮件头和服务商日志,核实生产环境中确切的信封域名,包括可能单独发布策略的子域和退信地址。
将 SPF 语法与 DMARC 联系起来,但不要混为一谈
SPF 通常按照协议规则评估 MAIL FROM 域名或 HELO 身份。DMARC 使用可见的 RFC 5322 From 域名,并且只有当经 SPF 验证的域名与该可见域名对齐时,才把 SPF 作为一条通过路径。因此,服务商的退信路径可能通过 SPF,但在 DMARC 层面仍未对齐。反过来,当 SPF 失败或未对齐时,已对齐的 DKIM 通过同样可以满足 DMARC。请分别记录 SPF 结果、被评估的域名、连接 IP、可见 From、DKIM 结果、对齐情况和 DMARC 结果。转发通常会改变连接 IP,即使原始发件人已获授权,也可能导致 SPF 失效。不要为了包含任意转发方而放宽 SPF。请使用 DKIM,并在适当时使用经过身份验证的链式机制和收件方证据。SPF 通过并不能证明邮件完整性、内容安全、收件人同意、服务器已接收或进入收件箱。
用确定性的流程验证变更
在编辑 DNS 之前,导出当前记录,并逐一列出每个机制或修饰符及其负责人和用途。按照 RFC 7208 语法解析候选记录,基于受控的快照展开 DNS 依赖,统计会触发查询的项,并测试已授权和未授权的 IPv4 与 IPv6 测试数据。检查嵌套 include 在 pass、fail、neutral、softfail、暂时性错误和永久性错误下的行为。测试通过 HELO 处理空反向路径的情况、子域、服务商退信路径,以及一个应当落到 all 的来源。通过常规的变更控制流程发布,查询权威和递归 DNS,然后通过每一条真实邮件流发送受控邮件。保留来自可信收件方的原始 Authentication-Results,并与预期的身份进行比较。如果出现生产来源缺失、多条记录被选中、查询次数超限错误、大范围的 temperror 或意外授权,请回滚。绝不要通过发送未经请求的邮件来测试。
使用 SendHQ 设置 SPF
SendHQ 会在发信身份设置中配置 SPF TXT 策略。对于冲突的 SPF 策略,它会停止设置并报告建议的合并 SPF 值,而不会悄然覆盖无关策略。只保留一条可选择的 SPF 策略;有关设置和修复详情,请参阅 Domains and DNS 文档。
常见问题
SPF 记录必须以什么开头?
从 DNS TXT 中选出的 SPF 策略以 v=spf1 开头,后面是按顺序排列的机制和可选的修饰符,并按照 RFC 语法分隔。
SPF 中的加号、减号、波浪号和问号分别是什么意思?
它们是匹配机制的限定符,分别表示 pass、fail、softfail 和 neutral。如果省略,该机制默认使用加号限定符。
一个域名可以发布两条 SPF 记录吗?
不可以。同一个确切域名下存在多条被选中的 v=spf1 记录会产生 SPF 永久性错误;请协调变更,将其合并为一条策略。
SPF 的 DNS 查询上限是多少?
RFC 7208 规定,一次检查最多处理 10 个会触发 DNS 查询的项,包括嵌套处理。请统计展开后的依赖图,而不仅仅是顶层的项。
include 等同于复制另一条记录吗?
不等同。include 执行一次嵌套的 SPF 评估,并在其结果为 pass 时匹配。其他结果和 DNS 故障仍遵循协议定义的行为,并带有相应的运营风险。
SPF 记录应该使用 ptr 吗?
设计新策略时不应使用。RFC 7208 指出不应使用 ptr,因为它速度慢、不可靠,并且会给名称服务器带来负担。
SPF 通过是否意味着 DMARC 通过?
不一定。DMARC 还要求经 SPF 验证的域名与可见 From 域名对齐,除非由已对齐的 DKIM 提供通过路径。
SendHQ 会配置 SPF 吗?
会。SendHQ 会在发信身份设置中配置 SPF TXT 策略,并在出现冲突的 SPF 策略时停止设置。
参考来源
- RFC 7208:发件人策略框架(SPF) — RFC Editor
- RFC 7489:基于域的消息认证、报告与一致性(DMARC) — RFC Editor
- RFC 5321:简单邮件传输协议(SMTP) — RFC Editor