Domain IP Lookup

一封邮件如何找到您的邮件服务器

发件人

you@gmail.com

MX 查询

谁来收邮件?

邮件服务器

优先级 10 优先

收件箱

已送达

优先级数值最小者优先;数值较大的作为备用

故障排查

SPF 记录未找到:原因与修复方法

8 分钟阅读作者: Domain IP Lookup Team

检测工具提示“no SPF record found”,或者邮件头里出现 spf=none。这两种说法含义相同:解析器查询了某一个具体名称下的 TXT 记录,其中没有一条以 v=spf1 开头。你的邮件服务器本身没有问题。真正的问题是为什么返回了空结果,原因通常是检查或发布记录时用错了名称。

本文讲的是如何排查这种空结果。如果你的记录存在但出了问题,请改看关于DNS 查询次数过多和10 次查询上限的文章。

“未找到”到底是什么意思

SPF 存放在普通的 TXT 记录中。收件方从邮件中取出域名(通常是信封发件人,也叫退信地址或 Return-Path 地址),请求它的 TXT 记录,只保留文本以 v=spf1 开头的记录。如果过滤后的列表为空,结果就是 none。这不是语法错误,而是没有策略。

它与另外两种常被混淆的情况不同。每种情况都有各自的结果和修复方法。

你看到的现象DNS 中的实际情况结果修复方法
No SPF record found该名称下没有任何 TXT 以 v=spf1 开头none在正确的名称下发布一条记录
Multiple SPF records有两条或更多 TXT 记录以 v=spf1 开头permerror合并为一条记录
Too many DNS lookups只有一条记录,但解析它需要超过 10 次查询permerror精简 include,或改用 IP 段
SPF fail 或 softfail记录存在,但发信 IP 不在其中fail / softfail添加该发信方,或停止使用它

核心要点

“未找到”针对的是某一个确切的 DNS 名称。在改动记录之前,先弄清楚收件方查询的是哪个名称。

原因 1:记录放在了错误的名称下

SPF 只在邮件所用的域名下查询,别处不会查。它不会从父域继承,也不会去 www 下查找。发布在 www.example.com 的记录对来自 @example.com 的邮件没有任何作用,发布在 example.com 的记录对来自 @news.example.com 的邮件也没有作用。

典型的错误出在 DNS 管理面板上。给根域名(即不带前缀的域名)添加记录时,主机字段通常填 @,不过有些面板要求留空,或者要求填写完整域名。先看面板的提示文字,再用查询来确认,不要只相信表单。

  • 记录在 www 或 mail 上: 内容正确,主机错误。如果你用 @example.com 发信,请把它移到根域名上。
  • 域名重复: 会自动追加区域名的面板,会把 example.com 变成 example.com.example.com。查询这个名称,你会发现记录就在那里。
  • 发信域名不对: 你检查的是 example.com,但信封发件人是 bounce.example.net 或 mail.example.com。收件方查的是那个名称,而不是你的域名。

原因 2:你检查的域名与邮件使用的域名不同

人们在 From 头里看到的地址是一回事,而 SPF 评估的信封发件人可能是另一回事。许多邮件服务商使用自定义的退信域名,有些默认使用它们自己的域名。这样 SPF 就是在那个名称上评估的,检查时根本不会参考你自己的记录。

邮件头会显示评估的是哪个域名(见下文)。如果它是你的某个子域名,即使父域的记录完美无缺,这个子域名也需要自己的记录。不发信的子域名可以发布 v=spf1 -all。

原因 3:文本不是有效的 SPF 字符串

检查工具对值的开头要求很严格。文本必须以 v=spf1 开头,带等号,且中间没有空格。下面这些差一点就对的写法都会得到“未找到”:

  • spf1 include:_spf.example.net ~all(缺少 v=)
  • v=spf include:_spf.example.net ~all(版本应为 spf1)
  • v = spf1 ...(等号两侧有空格)
  • 粘贴的文本带有从文档或聊天中复制来的弯曲“智能”引号

引号值得单独说一下。大多数托管的 DNS 面板会自动加上直双引号,所以你自己再输入的话,可能会被当作普通字符存进去。如果 dig 的返回里出现两层引号,请去掉你自己输入的那一层。

原因 4:你编辑的区域不是实际生效的区域

这一条连经验丰富的人也会中招。你可以在 DNS 面板里添加一条完美的 TXT 记录,却依然在公共 DNS 中查不到,因为互联网查询的并不是这个面板。通常的原因是委派。

  • 注册商与 DNS 托管方不同: 域名在一家公司注册,但它的名称服务器指向另一家(CDN、主机商或独立的 DNS 服务商)。只有被委派的名称服务器上的区域才会生效。在注册商自己的 DNS 页面添加的记录,或者在以前服务商那里遗留的区域中的记录,都会被忽略。

用 NS 查询找出被委派的名称服务器,然后到那家服务商那里编辑区域。比起传播延迟,这往往更能解释“我一个小时前就加了,可还是没有”。

原因 5:旧的记录类型、缓存或时间

早期的 SPF 草案使用专用的记录类型(编号 99,名称为 SPF)。该类型已被弃用,收件方评估的是 TXT 记录,所以只以 SPF 类型发布的记录对现代检查是不可见的。即使你的 DNS 服务商仍提供 SPF 类型,也请发布 TXT 记录。

时间是最后一个嫌疑对象,也是最弱的一个。如果某个解析器已经得知该名称没有 TXT 记录,它可能会在一段时间内持续返回这个空结果,时长取决于该区域的否定缓存设置。直接查询权威名称服务器可以消除这个疑问。我们的文章DNS 传播需要多久讲解了其机制。

确认 DNS 实际返回什么

在改动任何东西之前,先向 DNS 提出收件方问过的同一个问题。在 Linux 或 macOS 上:

dig
dig TXT example.com +short
# a healthy answer includes a line like:
# "v=spf1 include:_spf.example.net ~all"
Windows
nslookup -type=TXT example.com

返回为空,或只包含网站验证令牌之类的内容,就证实了“未找到”。要绕过你自己解析器的缓存,可以直接询问某个名称服务器:dig TXT example.com @ns1.example.net +short,其中的名称服务器取自 NS 查询的结果。如果它返回了记录而你平常的查询没有,那就是缓存问题。如果两者都没有,说明记录不在生效的区域里。

本站的 SPF 检查工具会查询你输入的域名的 TXT 记录,保留以 v=spf1 开头的记录,没有找到时报告“No SPF record”。如果找到了,它还会展开各个 include 并统计查询次数。TXT 查询会显示某个名称下的每一个 TXT 值,在记录存在但格式有误时很有用,因为你能看到原始文本。

查看失败邮件的邮件头

打开一封已送达邮件的原始源码,找到收件服务器添加的 Authentication-Results 头。其中的 SPF 部分会给出结果,通常还会写明被评估的域名。邮件头的措辞因收件方而异,所以请把示例当作一种模式,而不是确切的格式。

Authentication-Results 示例
spf=none (example.com does not designate permitted sender hosts)
spf=fail smtp.mailfrom=example.com
spf=permerror smtp.mailfrom=example.com
  • spf=none: 被评估的域名下没有记录。适用本文。
  • spf=fail 或 softfail: 记录存在,但发信 IP 未获授权。添加该发信方,或修正策略。
  • spf=permerror: 记录有问题,要么有两条记录,要么查询次数过多。

请留意 smtp.mailfrom(或 Return-Path)中的域名。SPF 评估的是它,而不是 From 地址。关于完整阅读邮件头的方法,请参阅如何追踪邮件的原始发件人。

发布一条最简且安全的记录

在信封发件人所用的名称下发布一条 TXT 记录。记录是一串从左到右读取的机制,最后以针对其他所有发信方的默认规则结尾。

  • ip4 / ip6: 授权一个地址或地址段,例如 ip4:203.0.113.25。不消耗 DNS 查询。
  • include: 授权另一个域名的 SPF 记录所授权的内容,例如 include:_spf.example.net。消耗一次查询。
  • a: 授权该域名自身 A(或 AAAA)记录中的 IP 地址。消耗一次查询。
  • mx: 授权该域名 MX 记录中列出的主机。消耗一次查询;如果收信主机并不是发信主机,这样写就不对。
  • ~all、-all、?all: 默认规则。~all 是 softfail,-all 是 fail,?all 是 neutral。
情形应在该名称下发布的记录
由一家外部服务商代发你的邮件v=spf1 include:_spf.example.net ~all
由你自己的固定 IP 服务器发信v=spf1 ip4:203.0.113.25 ~all
从不发信的子域名或闲置域名v=spf1 -all

先用 ~all,同时确认所有发信方都已列出,等你确定无误后再考虑改用 -all。?all 不表达任何主张,多半只是过渡用法。列表正确比结尾写法更重要,因为收件方会把 SPF 与 DKIM、DMARC 结合起来判断。

常见平台的简要提示

各平台的菜单不同,也会变化,但出问题的模式总是重复出现。请针对每种配置逐项检查。

  • Microsoft 365 和 Google Workspace: 两者都会提供一个 include,供你从管理控制台或设置指南中复制。在这里出现“未找到”,通常意味着记录发到了错误的 DNS 服务商或错误的主机上。
  • GoDaddy 和其他注册商: 如果名称服务器已改为 CDN 或主机商,注册商的 DNS 页面就不再具有权威性。请到 NS 查询显示的服务商那里编辑记录。
  • Cloudflare: 当域名使用 Cloudflare 名称服务器时,请在 Cloudflare 的 DNS 标签页中添加 TXT 记录。

没有 SPF 时收件方会怎么做

SPF none 不意味着自动拒收。标准把决定权留给收件方的本地策略,所以结果各不相同。既没有 SPF,又没有 DKIM 或 DMARC 来弥补的邮件,更容易显得可疑,而且一些服务商还公布了针对批量发件人的认证要求。请查看你所发往的各家服务商的最新规则。

SPF 检查的是信封发件人,所以它本身无法阻止他人伪造你可见的 From 地址;那是 DMARC 的职责。请参阅 SPF、DKIM 和 DMARC 详解和如何检查 SPF 记录。

需要查看某个域名的公网 DNS 地址?使用 Domain IP Lookup 工具。

常见问题