SPF记录配置错误怎么查?四种错法对应的报错现象
先看收件方返的结果码。permerror 几乎都是两种成因:域名下有两条 v=spf1 记录,或者 include 层层嵌套超过 10 次查表上限。语法错也一样报 permerror,一个全角冒号就够。只有部分邮件被拦(人工发的正常、系统发的进垃圾箱),是漏了第三方发信平台。
先划清分工。SPF、DKIM、DMARC 怎么配那篇讲的是从零写一条正确的记录,语法、include 写法、三条记录怎么配合,都在那边。这篇不重复。
这篇处理的是另一种处境:记录已经配了,但配错了,而且不知道错在哪。SPF 的麻烦之处在于它不像 MX——MX 错了信直接收不到,你立刻就知道了;SPF 错了信照样发得出去,只是被扔进垃圾箱,或者被对方静默拒掉,退信还不一定回到你手上。等发现的时候,可能已经丢了几个月的客户询盘。
先看结果码,再谈改哪一条
SPF 的结果码写在收件方那边,不在你这里。两个入口能拿到:一是用 Gmail 或 Outlook 收一封测试信,打开「显示原始邮件」,找 Authentication-Results 这一段;二是看对方退信里附的验证说明。
这一段里的 spf= 后面就是结果码。七种取值,含义和该做什么完全不一样。
| 结果码 | 含义 | 常见成因 | 要不要动手 |
|---|---|---|---|
pass | 发信 IP 在白名单里 | 配置正确 | 不用 |
none | 域名上根本没有 SPF 记录 | 没配,或记录加在了子域名上 | 要,属于漏配 |
neutral | 记录存在但没有表态 | 用了 ?all,等于放弃判断 | 要,几乎等于没配 |
softfail | 不在白名单,但只做标记 | 用了 ~all,或漏了某个发信平台 | 看情况,过渡期正常 |
fail | 不在白名单,判为伪造 | 用了 -all 且漏了发信源,或被人冒名 | 要,先分清是哪种 |
permerror | 记录本身无法解析 | 两条并存、超查表上限、语法错 | 要,本篇讲的就是它 |
temperror | 查询过程出错,非记录问题 | DNS 超时、解析商临时故障 | 先观察,多半自己恢复 |
permerror 是唯一一个「百分之百是配置写错了」的码。看到它不用怀疑网络、不用怀疑对方策略,直接回 DNS 后台。下面四种错法,前三种都会落到 permerror 上,第四种表现为 fail 或 softfail。
顺带说一句 fail 的两种成因怎么分:如果这封信确实是你发的,那就是漏了发信源;如果发件人你根本不认识,那是别人在冒用你的域名,这时候该做的是把 DMARC 策略收紧到拒收,光改 SPF 拦不住。
错误一:两条 SPF 记录并存,等于没有 SPF
这是最容易犯、后果最重的一条。一个域名下只能有一条以 v=spf1 开头的 TXT 记录。有两条,收件方不会挑一条用,而是直接判 permerror——比完全不配还糟。不配的时候至少是 none,多数收件方会照常投递只做个标记;判成 permerror,很多反垃圾策略会直接降权或者拒收。
它还会连累 DMARC。DMARC 的通过条件之一是 SPF 或 DKIM 至少有一个 pass,SPF 判了 permerror,这一半就废了,收到报告会看到 dmarc=fail,但你去查 DMARC 记录本身又是对的,很容易查偏方向。
成因基本只有一种:换邮箱服务商的时候,在旧记录旁边新增了一条新的,旧的没删。做这件事的人通常以为「多一条更保险」,实际正好相反。
怎么确认,一条命令:
dig txt 你的域名.com
返回里如果有两条以 v=spf1 开头的字符串,问题就确定了。注意别被分段迷惑——同一条记录被拆成几段引号是正常的,那是一条;两条各自以 v=spf1 开头的,才是两条。
修法不是删掉一条,而是合并。旧服务商如果还要继续发信(比如老系统还在跑通知邮件),把它那一段 include 写进同一条记录里:
v=spf1 include:spf.qiye.163.com include:旧服务商的地址 -all
一条记录里写几个 include 都是合法的,只有「两条记录」才不合法。这个区别很多人搞反了。
错误二:include 层层嵌套,超过查表上限
SPF 有一个硬上限:解析一条记录的过程中,最多允许 10 次 DNS 查询。每遇到一个 include、a、mx、ptr、exists、redirect,都消耗一次,而且 include 展开进去之后里面的机制照样计数。超了就是 permerror,Gmail 的说明里会直接写 too many DNS lookups。
这个限制在设计上是合理的——防止有人构造一条记录把收件方的解析器拖死。但对现在的企业很不友好,因为一家公司替你发信的系统太多了:
- 企业邮箱服务商本身,一次
- 官网表单的询盘通知,一次
- CRM 或 ERP 的自动邮件,一到两次
- 客服工单系统,一次
- EDM 营销平台,一到两次
- 财务或人事系统的通知邮件,一次
数一数就到八、九次了。再加一个平台,整条记录当场失效,而且是从「能发信」变成「完全不能发信」,因为 permerror 是整体判定,不是只废掉多的那个。
关键点:要数的不是你自己写了几个 include,而是展开之后总共查了几次。有些服务商的 include 里面又套了别人的 include,你写一个,实际消耗三个。这一点只能靠工具查,手工数必然漏。
压缩的办法,按代价从小到大排:
- 删掉已经不发信的平台。换掉的 EDM、停用的旧系统、试用过就没再用的工具,这类 include 常年躺在记录里占额度。
- 同厂商的多个产品合并。不少平台的不同产品共用一个发信 include,查一下文档,两个能并成一个。
- 固定 IP 的服务器改用
ip4:直接写。ip4不消耗查表次数,自建的发信服务器、有固定出口 IP 的办公网,直接写 IP 段最划算。 - 把非关键系统的发信拆到子域名。营销邮件用
notice.你的域名.com发,子域名有自己独立的一条 SPF,不占主域名的额度。代价是子域名要单独配 DKIM 和对齐,工程量最大,放最后考虑。
错误三:语法看着对,一个字符就废掉
这一类最气人,因为记录肉眼看上去完全正常,甚至能通过后台的保存校验。
全角字符。中文输入法下打出来的冒号是「:」不是「:」,引号是「“」不是「"」。SPF 的解析器只认半角。这个错在复制粘贴文档时高发,因为有些文档里的示例是用中文标点排版的。
机制名后面漏冒号。写成了 include spf.qiye.163.com,少了那个冒号,解析器认不出这是个 include 机制,整条记录判错。
直接把 IP 写进去。写成 v=spf1 203.0.113.10 -all。IP 必须带 ip4: 前缀,裸写会被当成一个不存在的机制名。
开头写错。v=spf1 是固定格式,写成 v=spf 1、v=spf-1 都不认。版本号部分对大小写敏感,机制名不敏感,这一点容易记混。
输入框截断。这个最隐蔽。SPF 记录会越写越长,几十个字符到两百多字符很常见。部分域名商的后台输入框有长度上限,超了不报错,静默截断。截掉的位置通常在末尾——正好是 -all 所在的地方。结果记录开头全对,结尾少了一截,判 permerror。
查的办法还是 dig txt,但要看结尾:返回的字符串末尾必须是你写的 -all 或 ~all。结尾缺东西,就是被截断了。解决办法是把解析商后台换成能存长记录的方式,或者把记录压短(合并 include、改用 ip4)。
错误四:漏了某个还在发信的系统
前三种都会报 permerror,一看就知道是配置问题。这一种不报错,记录本身完全合法,只是不全——某个出口的 IP 不在白名单里,那些信就被判 fail 或 softfail。
它的症状很有辨识度:人工在客户端发的信正常,系统自动发的信进垃圾箱。老板用 Foxmail 发报价单没问题,官网表单提交后那封询盘通知却躺在客户的垃圾箱里。原因是这两个出口走的是不同的服务器、不同的 IP。
哪些系统容易漏,按高发顺序:官网表单的提交通知、CRM 的客户跟进提醒、ERP 的订单与发货通知、财务系统的对账单、客服工单的回复提醒、招聘系统的面试通知、企业微信或钉钉里配的邮件提醒、还有各类 SaaS 工具的到期提醒。
找全的办法有两个,第二个比第一个可靠得多:
- 把公司里所有「会替你发邮件」的系统列一遍,逐个问 IT 或供应商:发信走哪个服务、出口 IP 是什么。漏的概率不低,因为有些系统是业务部门自己买的,IT 不知道。
- 看 DMARC 报告。配了
rua之后,各邮件服务商每天会回传 XML,里面列出了所有用你域名发信的 IP 和验证结果。这份数据是外部视角,比内部盘问准。报告里出现你没见过的 IP,就是漏的那个。DMARC 的写法见前面提到的那篇配置文。
补的方式二选一:那个平台有官方 include 就加 include,有固定 IP 段就写 ip4。加之前先确认它不会把查表次数顶超——刚在第 3 节数过的额度,这时候要用上。
改的顺序:改旧的,不要加新的
前面四种错,有一半是在「修改」这个动作上产生的。所以最后说顺序。
- 先把当前记录完整复制到记事本。改坏了能一秒回滚。截图不够,要能粘贴的纯文本。
- 在原来那条记录上改,不要新增。这是避免错误一的唯一办法。怕改坏的正常反应是「先加一条新的,稳了再删旧的」,这个反应在 SPF 上会直接造成 permerror。
- 改完立刻
dig txt复核三件事:只有一条v=spf1、include 拼写没被截断、结尾的-all还在。 - 发两封测试信。一封从员工客户端发到 Gmail,一封触发某个系统通知发到 Gmail,两封都要看到
spf=pass。只测第一封,错误四会漏过去。 - 等 TTL 过期再判断。改完立刻查是新的,不代表对方立刻看到。TTL 的时间账跟 MX 是同一套逻辑,见 MX 记录多久生效。
还有一个取舍要说清:从 ~all 收紧到 -all 是有代价的。软失败只是标记,硬失败是拒收。收紧之前没把发信源找全,收紧当天就会有一批自动邮件开始被拒,而且往往是你最不希望丢的那批——客户询盘、订单确认。稳妥的顺序是先跑两到四周的 ~all,把 DMARC 报告里出现的 IP 都处理干净,再改 -all。
最后一句实话:SPF 这类问题的排查成本,八成花在「不知道去哪看结果」上。结果码只在收件方那边,你这边改十遍也不知道对不对。先学会用一封测试信把 Authentication-Results 调出来,比背语法有用。信发出去了但被退回的,先看退信里的报错码,码表见 退信报错码对照,能少走很多弯路。
相关问题
一个域名可以有两条 SPF 记录吗?
不行。一个域名下只能有一条以 v=spf1 开头的 TXT 记录,有两条的话收件方不会挑一条用,而是直接判 permerror,比完全不配还糟,因为不配至少是 none,多数收件方会照常投递。而且 SPF 失效会连带 DMARC 的 SPF 对齐一起失败。修法是把两个 include 合并进同一条,不是删掉其中一条。
SPF 记录最多能写几个 include?
没有固定个数,限制的是 DNS 查询总次数:解析一条记录的过程中最多 10 次。include、a、mx、ptr、exists、redirect 各算一次,include 展开进去的内部机制照样计数。所以写一个 include 可能消耗三次额度。超了会判 permerror,Gmail 的说明里写 too many DNS lookups。压额度最省事的办法是删掉不再发信的平台,以及把固定 IP 改用 ip4 直接写。
SPF 配错了邮件会怎么样?
信照样发得出去,但会被判失败:轻则进对方垃圾箱,重则被拒收。麻烦的是你这边往往没有提示,退信也不一定回来。判 permerror 时影响最大,很多反垃圾策略会直接降权。判断方法是给 Gmail 发一封测试信,打开原始邮件看 Authentication-Results 里的 spf= 结果。
SPF 记录改了多久生效?
取决于改之前那条记录的 TTL。TTL 是 3600 秒,最坏一小时内全部更新;域名商默认 86400 的,就是一天。想快就在改之前把 TTL 降到 600,等旧值过期再动记录。验证要查权威 DNS,本机 nslookup 受缓存影响最不可信。改完立刻查是新的,不代表对方已经看到。
系统自动发的邮件进垃圾箱,人工发的正常,是 SPF 的问题吗?
大概率是。这两个出口走不同的服务器和 IP,人工发信走企业邮箱,系统通知走官网表单、CRM、ERP 之类的平台,后者的 IP 不在你的 SPF 白名单里,就被判 fail 或 softfail。确认办法是看 DMARC 的 rua 报告,里面会列出所有用你域名发信的 IP 和验证结果,出现没见过的 IP 就是漏的那个。