SPF 记录是什么以及它如何工作:SPF 记录全解释

Sender Policy Framework SPF SPF 记录 SPF Mechanism SPF Modifier SPF Qualifier SPF 估值

SPF 记录是由域名管理员发布在 DNS 中的 TXT 记录。SPF 记录指定一个 IP 地址的白名单,在该白名单中的 IP 地址被允许来代表该域名发送邮件。当邮件到达目标服务器的时候,服务器会在 DNS 中查找该 SPF 记录,然后用 SPF 记录来判断该邮件是否来自于一个被授权的 IP 地址。

SPF 全称是「发送者策略框架」(Sender Policy Framework),是一种基于 DNS (域名系统) 的,使目标服务器能够检查接收的邮件是否来自于一个被授权的 IP 地址的方法。

要了解 SPF 的规范,请参阅:RFC 7208

SPF 记录语法

简单地说,SPF 记录是发布在域名上的一串文本。

所有的 SPF 记录严格地以 "v=spf1" 开始,后面是一系列的 "terms"。请注意标注版本号的部分 "v=spf1" 是必须的:任何其他串像 "v=spf2" 会使 SPF 记录变无效,从而使得接收服务器会忽略该记录。

下面是一个 SPF 记录的例子:

v=spf1 mx a:example.com/28 -all

发布以后,上面的 SPF 记录在域名的 zone file 中看起来是这样的:

example.com.          TXT "v=spf1 mx a:example.com/28 -all"

值得一提的是,SPF 记录必须以 TXT 类型发布,而不是 SPF 类型。SPF 类型在 SPF 第一版本以后已经被弃用。

SPF 记录估值

邮件服务器中的 SPF 模块在对 SPF 记录中的 terms 进行估值后,向邮件服务器返回认证 (authentication) 结果。

SPF 中有 2 种 terms:mechanisms 以及 modifiers。我们将在下面介绍两者。

SPF 认证结果为以下其中之一:

  • None: 未能有效地解释域名,或者域名上未找到 SPF 记录;
  • Neutral: 发起请求的主机的 IP 地址是否允许并未确定;
  • Pass: 发起请求的主机的 IP 地址被允许;
  • Fail: 发起请求的主机的 IP 地址不被允许;
  • Softfail: 发起请求的主机的 IP 地址可能不被允许;
  • Temperror: SPF 模块在检查时碰到临时网络错误;
  • Permerror: 域名上发布的 SPF 无法解释。这种情况下,域名管理员必须修复此错误。

如果一直到 SPF 记录的末尾都没有找到匹配,返回 neutral。这是 SPF 估值的缺省值。

在没有找到匹配的情况下,为了明确地表明应该返回的结果,推荐在 SPF 记录的末尾使用 ~all 或者 -all

SPF qualifiers

SPF qualifier 前置于 SPF mechanism,用来指定该 SPF mechanism 的估值结果。

以下是所有的 qualifiers,以及对应的结果:

  • "+" pass
  • "-" fail
  • "~" softfail
  • "?" neutral

例如,qualifier "+" 代表 pass,"-" 代表 fail。

当 SPF mechanism 没有前置 qualifier 的时候,缺省为 "+" (pass)。

SPF mechanisms

SPF mechanisms 被 SPF 从左到右逐一地被估值。

SPF mechanism 的估值结果为以下之一:

  • match; 匹配;估值结束,qualifier 的值被作为 SPF 记录的估值结果返回;
  • not match; 不匹配;继续估值下一个 mechanism;
  • exception; 异常;估值结束,异常值被返回。

有两种 SPF mechanisms:基本 mechanisms 和指定发送者 mechanisms。

基本 mechanisms 有 allinclude

指定发送者 mechanisms 有 amxptrip4ip6,和 exists

我们将在下面逐一解释。

ip4 mechanism

ip4 mechanism 可以是以下之一:

  • ip4/<ip4-address>:如果发起请求主机的 IP 地址和 ip4-address 相同,那么匹配;
  • ip4:<ip4-network>/<prefix-length>:如果发起请求主机的 IP 地址位于 ip4-network,那么匹配;如果没有提供 prefix-length,缺省值为 /32。

比如,下面的 SPF 记录:

v=spf1 ip4:192.168.0.1/16 -all

使得从位于 192.168.0.1 和 192.168.255.255 之间的任何 IP 地址发送的邮件通过 SPF 认证。

ip6 mechanism

ip6 mechanism 可以是以下之一:

  • ip6/<ip6-address>:如果发起请求主机的 IP 地址和 ip6-address 相同,那么匹配;
  • ip6:<ip6-network>/<prefix-length>:如果发起请求主机的 IP 地址位于 ip6-network,那么匹配;如果没有提供 prefix-length,缺省值为 /128。

比如,下面的 SPF 记录:

v=spf1 ip6:1080::8:800:200C:417A/96 -all

使得从位于 1080::8:800:0000:0000 和 1080::8:800:FFFF:FFFF 之间的任何 IP 地址发送的邮件通过 SPF 认证。

all mechanism

all mechanism 匹配任何 IP 地址。它常常出现在 SPF 记录的末尾,这样当之前所有的 mechanisms 都没有匹配的时候,它可以提供一个确定的结果。SPF 绝不会检查位于 "all" 后面的 mechanisms。

比如,下面的 SPF 记录:

v=spf1 mx -all

如果 "mx" 不匹配,"-all" 就会被估值并且返回一个 hardfail 结果,因为它有一个 "-" qualifier。

include mechanism

include mechanism 可以让 SPF 记录把定义在另外一个 SPF 记录中的第三方 IP 地址包括进来。

当您需要用外部邮件发送/邮件营销来发送邮件的话,这个特别有用。为了正确地验证这些来自第三方服务器的邮件,您必须把他们的 SPF 记录「包含」到您的 SPF 记录中。要这样做的话,需要对每一个这样的外部服务使用 include mechanism。

比如,如果您需要使用 SendGrid 来发送邮件的话,您需要在您的 SPF 记录中包含 SendGrid 的 SPF 记录:

v=spf1 include:sendgrid.net ~all

一旦包含进去,发送自 SendGrid 服务器的邮件将会通过 SPF 认证。

a mechanism

如果发起请求主机的 IP 地址是 a mechanism 指定的其中一个 IP 地址的话,a mechanism 将会匹配。

a mechanism 可以是以下之一:

  • a:如果发起请求主机的 IP 地址和该域名(发布 SPF 记录的域名)解释到的 IP 地址一样,那么匹配;
  • a/<prefix-length>:如果发起请求主机的 IP 地址位于 a/<prefix-length> 指定的范围,那么匹配;
  • a:<domain>:如果发起请求主机的 IP 地址和指定域名解释到的 IP 地址一样,那么匹配;
  • a:<domain>/<prefix-length>:如果发起请求主机的 IP 地址位于 a:<domain>/<prefix-length> 指定的范围,那么匹配。

例如,假定一下的 SPF 记录发布在 example.com 上,IP 地址为 199.1.1.1:

v=spf1 a -all

那么当位于 IP 地址 199.1.1.1 的主机发送邮件到接收邮件服务器的时候,该邮件将会通过 SPF 认证。

mx mechanism

当对 mx mechanism 进行估值时,SPF 将会对域名上所有的 MX 记录的所有的 A 记录进行测试。如果发起请求主机的 IP 地址和其中的某个 IP 地址相同,那么 mx mechanism 匹配。

如果域名没有指定,SPF 将使用当前域名(发布 SPF 记录的域名)。

mx mechanism 可以是以下之一:

  • mx
  • mx/<prefix-length>
  • mx:<domain>
  • mx:<domain>/<prefix-length>

例如,以下发布在 example.com 上的记录:

v=spf1 mx mx:deferrals.domain.com -all

允许来自以下主机发送的邮件:

  • example.com 的所有 MX 记录的所有 A 记录
  • deferrals.domain.com 的所有 MX 记录的所有 A 记录
ptr mechanism

ptr mechanism 可以是以下之一:

  • ptr
  • ptr:<domain>

如果域名没有指定,SPF 将使用当前域名(发布 SPF 记录的域名)。

首先 SPF 会使用反向 IP 查询来获得发起请求主机的 IP 地址的主机名。然后 SPF 尝试使用这些主机名找到匹配,如下所述。

如果以下之一为真,那么 prt mechanism 匹配:

  • 请求主机的 IP 地址和主机名的其中一个 IP 地址相同;
  • 主机名以当前域名结束。

在这个过程中,无效的主机名将被丢弃。

例如,下面的 SPF 记录发布在 example.com 上,发起请求主机的 IP 地址为 199.1.1.1:

v=spf1 ptr -all

假定 199.1.1.1 反向解释到 example.com,并且 example.com 解释到 199.1.1.1,那么来自 199.1.1.1 的邮件将会通过 SPF 验证。

请留意,由于 ptr mechanism 使用大量的 DNS 查询,所以并不推荐使用。

exists mechanism

exists mechanism 有一个域名参数。SPF 在域名上执行一个 A 查询,如果有结果返回,那么匹配。

例如,如果发布在 example.com 上的 SPF 记录是:

v=spf1 exists:microsoft.com -all

并且 microsoft.com 解释到某个 IP 地址 (不管是什么地址),代表 example.com 发送的邮件将会通过 SPF 验证。

SPF modifiers

SPF 有两个 modifiers:redirect 和 exp。

SPF modifiers 是可选的。每条 SPF record 中的任何 SPF modifier 只能够使用一次。未知的 modifiers 会被忽略。

redirect modifier

redirect modifier 有一个域名参数值:

  • redirect=<domain>

在 domain 上面的 SPF 记录会代替当前的 SPF 记录。

例如,domain.com 发布了以下的 SPF 记录:

v=spf1 redirect=example.com

如果 example.com 上面没有 SPF 记录,返回结果未知。否则,对 example.com 上面的 SPF 记录估值并返回估值结果。

exp modifier

exp modifier 有一个域名参数值:

  • exp=<domain>

如果 SPF 记录估值失败,并且存在 exp modifier,SPF 返回一个串来解释原因。

例如,example.com 发布了以下的 SPF 记录:

v=spf1 mx -all exp=explain._spf.%{d}

并且,您在 explain._spf.example.com 上面创建了一个 TXT 类型的记录,值如下:

Emails from example.com must only be sent by its own mail servers.

那么当 example.com 邮件服务器以外的主机发送邮件的时候,SPF 认证将会失败,并且返回上面的解释文本。

常用邮件发送/营销服务的 SPF 记录

以下是常用的邮件发送/营销服务,以及对应的 SPF 记录:

  • Google Workspace (Gmail),前身是 G Suite: _spf.google.com
  • SendGrid: sendgrid.net
  • Ontraport: _spf-moon-ray.ontramail.com, AND _spf-ontramail.ontramail.com
  • Constant Contact: spf.constantcontact.com
  • HubSpot: refer to HubSpot SPF Guide
  • Campaign Monitor: _spf.createsend.com
  • AWeber: send.aweber.com
  • Infusionsoft: infusionsoft.com
  • ActiveCampaign: emsd1.com
  • SendLane: creatensend.com, icmessage.com, slsv1.com, AND slsv2.com
  • Mailer Lite: _spf.mlsend.com
  • GetResponse: _spf.getresponse.com

要添加以上任意一个服务,只需要在您的 SPF 记录中插入一个包含该服务的 include mechanism。

例如,假设您现有的 SPF 记录是这样的:

v=spf1 a -all

现在您需要把 Ontraport 加到 SPF 记录中,您需要把 Ontraport 的记录插入到 "-all" 之前,像这样:

v=spf1 a include:_spf-moon-ray.ontramail.com include:_spf-ontramail.ontramail.com -all

现在来自 Ontraport 服务器的邮件将会通过 SPF 验证。

SPF 记录常见问题 (FAQ)

我可以在域名上发布多条 SPF 记录吗?

每个域名只可以发布一条 SPF 记录。如果发布多条记录的话,SPF 会返回 PermError。

如果我的 SPF 记录有语法错误会发生什么?

如果您的 SPF 记录有语法错误,接收服务器会立即返回一个 PermError 结果。这意味着所有您的邮件都会在 SPF 验证失败,并且可能不会抵达用户邮箱。

要检查您的 SPF 记录是否有语法错误,使用 DMARCLY 的免费 SPF 记录检查器

Previous Post Next Post

 Protect Business Email & Improve Email Deliverability

Get a 14 day trial. No credit card required.

Create Account