← 返回博客

SPF 记录配置完全指南:Sender Policy Framework 详解

从零开始创建、测试和排查 SPF DNS 记录。覆盖所有机制(ip4、ip6、include、a、mx)、限定符、10 次查询上限,以及与 DMARC 的对齐关系。

更新于 2026年10月21日
SPF 记录配置完全指南:Sender Policy Framework 详解

SPF 记录配置完全指南:Sender Policy Framework 详解

Sender Policy Framework(SPF)是一项基于 DNS 的邮件认证标准。域名所有者通过发布一条 DNS TXT 记录,列出被授权以本域名发信的 IP 地址和主机名。收件方服务器收到邮件时,会查询发件域的 SPF 记录,检查发信 IP 是否在列表中——匹配则通过,不匹配则触发垃圾邮件过滤或直接拒绝。

SPF 是邮件认证三件套之一,另外两件是 DKIM(对邮件头部加密签名)和 DMARC(将 SPF 与 DKIM 绑定为策略并向收件方说明如何处理失败)。三者缺一不可,但 SPF 通常最先配置,因为它不需要管理加密密钥,只需要一条 DNS TXT 记录。

SPF 的工作原理

邮件到达时,收件服务器查看 MAIL FROM(也叫信封发件人或退信地址)找到要检查的域名,再查询该域的 TXT 记录,逐条对比各机制(mechanism)与发信 IP。第一个匹配的机制决定最终结果;全部不匹配则为 neutral(中立,即无意见)。

SPF 记录的结构

SPF 记录是域名根(或子域名)上的一条 DNS TXT 记录,典型格式如下:

v=spf1 ip4:203.0.113.0/24 include:mail.rovela.dev include:_spf.google.com ~all

每条记录必须以 v=spf1 开头,后接一个或多个机制,末尾是兜底机制。

常用机制

ip4 和 ip6 直接匹配 IP 地址或 CIDR 段,是最简单也最推荐的方式,不消耗 DNS 查询次数:

ip4:203.0.113.5
ip4:203.0.113.0/24
ip6:2001:db8::/32

include 委托到另一个域的 SPF 记录。这是授权第三方发信平台(如 Rovela)最常见的做法:

include:mail.rovela.dev

a 匹配域名的 A/AAAA 记录,适用于网站服务器同时发信的场景。

mx 匹配域名的 MX 记录,适用于收发邮件用同一台服务器的情况。这个机制只在「收信服务器同时也是发信服务器」时才对,很多企业把收信放在 Google Workspace 或 Microsoft 365,发信走别家平台,这种情况下加 mx 是错的。

exists 对一个动态主机名做 A 记录查询,只要有 A 记录返回就通过。属于少见的高级用法,比如按发信来源编码的子域做路由判断。

ptr 执行反向 DNS 查询,速度慢、可靠性差,RFC 7208 已弃用,避免使用。

限定符

每个机制前可以加限定符,决定匹配时返回什么结果:

限定符结果含义
+Pass已授权(默认,通常省略)
-Fail明确未授权,收件方应拒绝
~SoftFail可能未授权,收件方应接受但标记
?Neutral不表态

兜底机制通常是 -all(硬拒绝)或 ~all(软拒绝)。配置初期用 ~all,审计完所有发信来源后再切换到 -all。

10 次查询上限

这是生产环境中最常见的 SPF 故障原因。RFC 7208 规定一次 SPF 评估最多触发 10 次 DNS 查询。每个 include、a、mx、exists 都算一次,嵌套的 include 也会累加。超过 10 次会产生 permerror,大多数收件方将其视为失败。

看一个容易低估的例子:

v=spf1 include:mailprovider1.com include:mailprovider2.com include:mailprovider3.com include:crm.example.com include:support.example.com ~all

表面上只有 5 个 include,但每个被包含的域名自己还可能引用更多 include。一家大型邮件服务商的 SPF 记录往往自己就吃掉 4 到 5 次查询。真正常见的超限场景不是「加太多东西」,而是「只加了三四家,其中一家悄悄扩了内部依赖」。

控制查询次数的方法:

  1. 添加前先计数。 用 dig TXT yourdomain.com +short 读出当前记录,再逐个 dig 每个 include 指向的域名,手工展开嵌套层级。也可以用在线 SPF 检查工具,它会直接给出总查询数。
  2. 直接用 ip4/ip6。 IP 机制不消耗查询次数,自有服务器和固定出口 IP 都应该写成 CIDR 段而不是 include。
  3. 必要时展开 include。 把第三方 include 替换成实际 IP,代价是服务商更换 IP 时不会主动通知你,需要定期回查。适合自有 IP 段,不适合云平台。
  4. 按用途拆分子域。 事务邮件用 send.example.com,营销邮件用 news.example.com,各自有独立的 SPF 记录,查询预算互不占用。这是最省事也最稳定的做法。
  5. 定期复查。 别人的 SPF 记录你不控制,第三方每年新增一两次 include 是常态。把它纳入季度审计,别等到退信率上升才发现。

配置步骤

第一步:梳理所有发信来源

在修改 DNS 之前,列出所有以本域名发信的系统:自有邮件服务器、Rovela 等事务邮件 API、Mailchimp 等营销平台、CRM 和客服系统、内部应用(密码重置、通知、报表),以及 Google Workspace 或 Microsoft 365。

第二步:获取各服务商的 include

每家正规服务商都会发布自己的 SPF 记录。Rovela 的是 include:mail.rovela.dev,Google Workspace 的是 include:_spf.google.com,查阅各家文档确认。

第三步:合并成一条记录

一个域名只能有一条 SPF 记录(即只能有一条以 v=spf1 开头的 TXT 记录),多条会导致 permerror。把所有来源合并到一条记录:

v=spf1 ip4:203.0.113.0/24 include:mail.rovela.dev include:_spf.google.com ~all

第四步:添加到 DNS

在域名根(@)添加 TTL 3600 的 TXT 记录。若在迁移旧记录,提前一天将 TTL 降到 300 以加快传播。

第五步:测试

用 dig TXT yourdomain.com +short 确认记录生效。向 check-auth2@verifier.port25.com 发一封测试邮件,会自动回复 SPF、DKIM、DMARC 三项检测结果。

第六步:用 DMARC 报告持续监控

配置 DMARC 报告(哪怕 p=none)后,你会收到聚合报告,显示哪些 IP 在冒用你的域名发信以及 SPF 通过情况,这是发现遗漏发信来源的最佳手段。

常见问题与修复

多条 SPF 记录。 删到只剩一条,把所有授权来源合并进去。

SPF 通过但 DMARC 失败。 DMARC 要求 SPF 认证域与 From: 头部的域对齐。大多数云邮件平台使用自己的退信地址,导致 SPF 对齐失败——这是正常的。解决方法是配置 DKIM 对齐而非 SPF 对齐。

转发邮件 SPF 失败。 邮件转发时路由改变但信封发件人不变,转发服务器的 IP 不在原始域的 SPF 列表中,SPF 因此失败。开启 DKIM 即可解决,因为 DKIM 签名在转发中保持完整,DMARC 会用 DKIM 结果放行。

SoftFail 仍进垃圾箱。 如果记录完整且稳定,可以切换到 -all。更严格的策略反而会改善收件率,因为它表明你对自己的发信来源有信心。

与 DKIM、DMARC 配合使用

SPF 单独使用并不足够。完整的认证体系:

; SPF
yourdomain.com.  IN TXT  "v=spf1 include:mail.rovela.dev ~all"

; DKIM(密钥在 Rovela 后台生成,Rovela 负责轮换)
rovela._domainkey.yourdomain.com.  IN TXT  "v=DKIM1; k=rsa; p=<公钥>"

; DMARC
_dmarc.yourdomain.com.  IN TXT  "v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com; pct=100"

Rovela 的一键 DNS 配置(支持 Cloudflare 和 DNSPod)会自动写入 SPF 和 DKIM 记录,DNS 生效后即可通过三项检测。

子域名

SPF 不会自动继承到子域名。如果你用 notifications.yourdomain.com 发信,就必须在那个子域名上单独配置一条 SPF 记录。

反过来更重要:不打算用来发信的子域,应该显式加一条 v=spf1 -all。没有 SPF 记录的子域,任何人都可以伪造它以你的品牌发信,而收件方看到「这个域没有 SPF」时通常不会拒绝,只是放行。给子域加一条空记录的成本极低:

; 不用于发信的子域
yourdomain.com.       IN TXT  "v=spf1 -all"
*.yourdomain.com.     IN TXT  "v=spf1 -all"

注意根域的那条要写成完整的记录(含各发信来源),不要把 -all 误加到正在使用的根域上,那会直接掐断所有合法发信。

排查顺序

SPF 出问题时,按这个顺序走,比凭感觉改记录快得多:

  1. 确认查的是哪条记录。 dig TXT yourdomain.com +short。如果返回多条以 v=spf1 开头的记录,先删到只剩一条,其余问题都不用看了。
  2. 确认收件方检查的是哪个域。 SPF 查的是 MAIL FROM,不是 From: 头部。服务器日志里能看到真实的 envelope sender。
  3. 逐个数查询次数。 用工具算,不要目测。
  4. 确认发信 IP 真的在列表里。 把实际出口 IP 拿去和展开后的列表逐段比对,NAT 后面多跳出口是常见意外。
  5. 确认对齐。 SPF 通过但 DMARC 失败,八成是对齐问题而不是 SPF 本身的问题——这是两家不同的检查。

维护建议

SPF 记录是活的配置,不是一次性的设置:

  • 新增服务就更新。 每引入一个会代表你发信的 SaaS 工具(CRM、工单、分析、通知),当天就把它的 include 加进去。漏加不会报错,只会让那部分邮件开始丢。
  • 每季度审计。 确认所有 include 仍能解析、IP 段仍归属于你、查询次数仍在 10 以内。服务商停用旧域名时 include 会变成 permerror,而你可能毫无察觉。
  • 下线服务要清理。 停用的 SaaS 工具留下的 include 不只是浪费查询预算,还是一条永远授权着的发信通道。这两条理由中的任何一条都足够让你把它删掉。
  • 变更前降 TTL。 大改动前把 TTL 从 3600 降到 300,方便出错时快速回滚。
  • 和 DKIM 一起看。 只维护 SPF 而放任 DKIM 过期,DMARC 报告里的通过率会慢慢下滑,这个趋势在聚合报告里比在退信率上更早显现。