SPF 记录:原理、语法及配置方法简介

SPF,全称为 Sender Policy Framework,即发件人策略框架。

当前 Email 通信,还是在使用 SMTP 这个协议。SMTP 的全称为 Simple Mail Transfer Protocol,即「简单邮件传输协议」。正如它的名字锁暗示的,SMTP 实际上是一个非常简单(甚至简陋)的传输协议,本身并没有很好的安全措施。根据 SMTP 的规则,发件人的邮箱地址是可以由发信方任意声明的。在 SMTP 协议制定的时候也许还好,但在垃圾和诈骗邮件横行的今天,这显然是极不安全的。

SPF 出现的目的,就是为了防止随意伪造发件人。

SPF 记录的原理

SPF 记录实际上是服务器的一个 DNS 记录,原理其实很简单:

假设邮件服务器收到了一封邮件,来自主机的 IP 是173.194.72.103,并且声称发件人为email@example.com。为了确认发件人不是伪造的,邮件服务器会去查询example.com的 SPF 记录。如果该域的 SPF 记录设置允许 IP 为173.194.72.103的主机发送邮件,则服务器就认为这封邮件是合法的;如果不允许,则通常会退信,或将其标记为垃圾/仿冒邮件。

因为不怀好心的人虽然可以「声称」他的邮件来自example.com,但是他却无权操作example.com的 DNS 记录;同时他也无法伪造自己的 IP 地址。因此 SPF 是很有效的,当前基本上所有的邮件服务提供商(例如 Gmail、QQ 邮箱等)都会验证它。

SPF 记录的语法

一条 SPF 记录定义了一个或者多个 mechanism,而 mechanism 则定义了哪些 IP 是允许的,哪些 IP 是拒绝的。

这些 mechanism 包括以下几类:

all | ip4 | ip6 | a | mx | ptr | exists | include

每个 mechanism 可以有四种前缀:

"+"  Pass(通过)
"-"  Fail(拒绝)
"~"  Soft Fail(软拒绝)
"?"  Neutral(中立)

测试时,将从前往后依次测试每个 mechanism。如果一个 mechanism 包含了要查询的 IP 地址(称为命中),则测试结果由相应 mechanism 的前缀决定。默认的前缀为+。如果测试完所有的 mechanisms 也没有命中,则结果为 Neutral。

除了以上四种情况,还有 None(无结果)、PermError(永久错误)和 TempError(临时错误)三种其他情况。对于这些情况的解释和服务器通常的处理办法如下:

结果 含义 服务器处理办法
Pass 发件 IP 是合法的 接受来信
Fail 发件 IP 是非法的 退信
Soft Fail 发件 IP 非法,但是不采取强硬措施 接受来信,但是做标记
Neutral SPF 记录中没有关于发件 IP 是否合法的信息 接受来信
None 服务器没有设定 SPF 记录 接受来信
PermError 发生了严重错误(例如 SPF 记录语法错误) 没有规定
TempError 发生了临时错误(例如 DNS 查询失败) 接受或拒绝

注意,上面所说的「服务器处理办法」仅仅是 SPF 标准做出的建议,并非所有的邮件服务器都严格遵循这套规定。

Mechanisms

下面介绍上面提到的 mechanism:

all

表示所有 IP,肯定会命中。因此通常把它放在 SPF 记录的结尾,表示处理剩下的所有情况。例如:

"v=spf1 -all" 拒绝所有(表示这个域名不会发出邮件)
"v=spf1 +all" 接受所有(域名所有者认为 SPF 是没有用的,或者根本不在乎它)

ip4

格式为ip4:或者ip4:/,指定一个 IPv4 地址或者地址段。如果prefix-length没有给出,则默认为/32。例如:

"v=spf1 ip4:192.168.0.1/16 -all"
只允许在 192.168.0.1 ~ 192.168.255.255 范围内的 IP

ip6

格式和ip4的很类似,默认的prefix-length/128。例如:

"v=spf1 ip6:1080::8:800:200C:417A/96 -all"
只允许在 1080::8:800:0000:0000 ~ 1080::8:800:FFFF:FFFF 范围内的 IP

a 和 mx

这俩的格式是相同的,以a为例,格式为以下四种之一:

a
a/
a:
a:/

会命中相应域名的 a 记录(或 mx 记录)中包含的 IP 地址(或地址段)。如果没有提供域名,则使用当前域名。例如:

"v=spf1 mx -all"
允许当前域名的 mx 记录对应的 IP 地址。

"v=spf1 mx mx:deferrals.example.com -all"
允许当前域名和 deferrals.example.com 的 mx 记录对应的 IP 地址。

"v=spf1 a/24 -all"
类似地,这个用法则允许一个地址段。

例如,这是一个比较常见的 SPF 记录,它表示支持当前域名的 a 记录和 mx 记录,同时支持一个给定的 IP 地址;其他地址则拒绝:

v=spf1 a mx ip4:173.194.72.103 -all

include

格式为include:,表示引入域名下的 SPF 记录。注意,如果该域名下不存在 SPF 记录,则会导致一个PermError结果。例如:

"v=spf1 include:example.com -all" 即采用和 example.com 完全一样的 SPF 记录

exists

格式为exists:。将对执行一个 A 查询,如果有返回结果(无论结果是什么),都会看作命中。

ptr

格式为ptr或者ptr:。使用ptr机制会带来大量很大开销的 DNS 查询,所以连官方都不推荐使用它。

关于v=spf1

这是必须的,这个表示采用 SPF 1 版本,现在它的最新版本就是第 1 版。

Modifiers

SPF 记录中还可以包括两种可选的 modifier;一个 modifier 只能出现一次。

redirect

格式为redirect=

将用给定域名的 SPF 记录替换当前记录。

exp

格式为exp=,目的是如果邮件被拒绝,可以给出一个消息。而消息的具体内容会首先对执行 TXT 查询,然后执行宏扩展得到。

如何用 SPF 保护我的域名

如果你拥有自己的域名,并且用它发送邮件,那么你应该为它添加 SPF。通过域名服务商提供的「域名解析」、「DNS Editor」或者「DNS Zone Editor」等功能添加,并填写正确的 SPF 数据就可以了。

严格来说,SPF 数据应该创建为 SPF 记录。但是鉴于很多 DNS 服务商不支持 SPF 记录,甚至有的邮件服务器也不支持 SPF 记录,因此也可以创建为一条 TXT 记录。目前,你应该至少创建一条 TXT 记录。

因为本质上 SPF 的作用是为一个域名指定合法的发件 IP,所以你需要知道自己使用的邮件服务器的发件 IP 是什么。如果你使用第三方的域名邮箱服务(比如腾讯的域名邮箱),那么他们应该有相应的文档告诉你该怎么填写。如果你用虚拟主机,则主机提供商也应该会告诉你。

生效时间

SPF 记录本质上是一个 DNS 记录,所以并不是修改之后立即生效的——通常需要几个小时的时间。

https://www.kitterman.com/spf/ 检测工具

一些工具

虽然我不能帮你决定 SPF 该填什么,但是这里有一些非常好用的工具可以帮助你,点击它们在新窗口打开:

  • Open SPF:官方网站,有很多资料,值得一看。
  • RFC 4408:SPFv1 的规范全文。
  • SPF Recored Testing Tools:帮助你验证域名是否存在 SPF 记录、记录的语法是否正确,以及输入 IP 和 host 来测试是不是真正管用。
  • SPF: Why?:为什么我发的邮件被拒绝了?
  • Beveridge Hosting DNS Lookup:图形界面的dig,也可以显示查询到的 SPF 信息。
  • Beveridge SPF Test:另一个根据 IP 和 host 验证 SPF 是否通过的工具。
  • Gmail:如果你有 Gmail 的话,可以给自己的 Gmail 邮箱发一封邮件,然后用 Gmail 独有的 Show Original 功能查看 Gmail 服务器的 SPF 判断结果。

一、SPF,全称Sender Policy Framework,即发件人策略框架。

SPF是为了防范伪造发件人地址发送垃圾邮件而提出的一种开放式标准,是一种以IP地址认证电子邮件发件人身份的技术。域名所有者通过在DNS中发布SPF记录来授权合法使用该域名发送邮件的IP地址。

当在DNS中定义了域名的SPF记录后,为了确认邮件声称发件人不是伪造的,邮件接收方首先检查邮件域名的SPF记录,来确定发件人的IP地址是否被包含在SPF记录中,若包含,则认为是一封正确的邮件,否则认为是一封伪造的邮件并退回,或将其标记为垃圾/仿冒邮件。

设置正确的SPF记录可以提高邮件系统发送外域邮件的成功率,也可以一定程度上防止被假冒域名发送邮件。

例子:qq.comspf记录

qq.com  text = "v=spf1 include:spf.mail.qq.com ~all"

二、SPF记录的语法

SPF记录是由SPF版本和指定的IP组成。

SPF记录由一个版本开始,格式为:

record = version terms *SP

version = "v=spf1"

 

terms 由机制mechanisms和修改符modifiers(可选的)组成。

 

域名定义了一个或者多个机制mechanisms,用来描述哪些IP是被允许使用该域名发送邮件。

Mechanisms包含以下几种类型:

mechanism = ( all / include/ a / mx / ptr / ip4 / ip6 / exists )

 

域名可能也定义修改符modifiers,每个修改符只能使用一次。

Modifiers包含以下几种类型:

modifier = redirect / explanation

(一)机制mechanisms

每个mechanism有四种前缀(默认前缀为+”):

"+"

Pass

"-"

Fail

"~"

SoftFail

"?"

Neutral

在一条SPF记录中,从左到右依次对每个mechanism进行验证。对一个mechanism进行检测,有三种结果可能发生:IP匹配成功,IP匹配失败或者返回异常。如果IP匹配成功,处理结果返回该mechanism的前缀;如果IP匹配失败,继续下一个mechanism;如果返回异常,则mechanism结束并返回该异常值;如果没有mechanism或者modifier匹配,则结果返回Neutral”。

如果不存在SPF记录,则返回“None”;如果在DNS解析过程中出现临时性错误,则返回“TempError”;如果存在某些语法错误或者评估错误(如该域指向不为人知的机制),则返回“PermError”。

SPF记录验证可能返回的结果如下:

Result

Explanation

Intended action

Pass

SPF记录验证该发信IP为合法的

接收邮件

Fail

SPF记录验证该发信IP是不合法的

拒绝邮件

SoftFail

SPF验证该发信IP不是合法的,但是不采取强制措施

接收邮件但作标识

Neutral

SPF记录没有明确说明发信IP是否合法的信息

接收邮件

None

域名没有设置SPF记录或者SPF记录验证没有结果

接收邮件

PermError

发生永久性错误(如:SPF记录格式错误)

没有规定

TempError

发生临时性错误

接收邮件或拒绝邮件

1、“all”机制

all”表示所有IP都匹配。通常放在SPF记录末尾,表示处理剩下的所有情况。

例如:

"v=spf1 mx -all"  表示允许所有该域的MX邮件服务器发送邮件,禁止其他的。

"v=spf1 -all" 表示该域不会发送任何邮件。

"v=spf1 +all" 表示域名所有者认为SPF是没有用的或者并不关心(任何服务器都可使用该域名发送邮件)。

2、“ip4”机制

格式为:

ip4:<ip4-address> 

ip4:<ip4-network>/<prefix-length>

如果没有提供 prefix-length ,默认为 /32

例如:

"v=spf1 ip4:192.168.0.1/16 -all" 

表示只允许192.168.0.1~192.168.255.255范围内的IP地址。

3、“ip6”机制

格式为:

ip6:<ip6-address>

ip6:<ip6-network>/<prefix-length>

如果没有提供 prefix-length ,默认为 /128 

例如:

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

表示只允许1080::8:800:0000:0000~1080::8:800:FFFF:FFFF范围内的IP地址

"v=spf1 ip6:1080::8:800:68.0.3.1/96 -all"

表示只允许1080::8:800:0000:0000~1080::8:800:FFFF:FFFF范围内的IP地址

4、“a”机制

格式为:

a

a/<prefix-length>

a:<domain>

a:<domain>/<prefix-length>

所有A记录都会检测。如果客户端IP在这些记录中,则该机制结果匹配。

若没有指定域,则使用当前域。

A记录必须与客户端IP地址完全匹配,除非提供前缀长度,在这种情况下,A记录查询返回的IP地址将扩展到其相应的CIDR前缀,且客户端IP将在其子网中查询。

例如:

"v=spf1 a -all"

表示当前域被使用。

"v=spf1 a:example.com -all"

等价于当前域为example.com

"v=spf1 a:mailers.example.com -all"

表示指定mailers.example.com的主机IP可以外发邮件。

"v=spf1 a/24 a:offsite.example.com/24 -all"

如果example.com解析到192.0.2.1,那么整个C类地址192.0.2.0/24将作为客户端IP地址外发邮件。同样,如果offsite.example.com返回多个A记录,每个IP地址将被扩展到CIDR子网。

5、“mx”机制

格式:

mx

mx/<prefix-length>

mx:<domain>

mx:<domain>/<prefix-length>

所有域的MX记录对应的A记录按照MX优先级进行验证。如果客户端IP在这些记录中,那么该机制匹配。

如果没有指定域,则使用当前域。

A记录必须与客户端IP地址完全匹配,除非提供前缀长度,在这种情况下,A记录查询返回的IP地址将扩展到其相应的CIDR前缀,且客户端IP将在其子网中查询。

例如

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

表示允许当前域通过其MX服务器发送邮件,并通过deferrals.domain.comMX服务器重试延迟的邮件。

"v=spf1 mx/24 mx:offsite.domain.com/24 -all"

也许一个域的MX服务器使用一个IP地址接收邮件,使用另一个相邻IP地址发送邮件。

6、“ptr”机制

格式:

ptr

ptr:<domain>

通过PTP查询客户端IP对应的主机名。对主机名进行验证:PTR主机名对应的A记录至少有一个与原客户端IP匹配,无效主机名将被丢弃。如果一个有效主机名以该域结尾,则该机制匹配。

若没有指定域,则使用当前域。

尽量避免使用该机制,因为会带来很大开销的DNS查询。

例如:

"v=spf1 ptr -all"

直接控制所有机器的域(不像拨号或宽带ISP)允许其所有服务器发送邮件。比如,hotmail.com或者paypal.com

"v=spf1 ptr:otherdomain.com -all"

表示允许所有以otherdomain.com结尾的主机名的服务器发送邮件。

7、“exists”机制

格式为:

exists:<domain>

对提供的域进行A记录查询。如果有返回结果,则为匹配,无论查询结果是什么。

例如:在下面例子中,客户端IP1.2.3.4 a,当前域为example.com

"v=spf1 exists:example.com -all"

example.com不能解析,则结果返回失败;若能解析,则该机制匹配。

当使用该机制的宏,可以执行RBL方式反向IP查询或者设置每个用户异常。

"exists:%{i}._spf.sparkpostmail.com"用于SPF验证,%{i}为连接的ip地址,通过查询"%{i}._spf.sparkpostmail.com"A记录,若有返回结果,则允许该ipMAIL FROM域的名义发送邮件。

以下为两个在审议中的特别的IP地址:

$ host 35.167.215.19._spf.sparkpostmail.com

35.167.215.19._spf.sparkpostmail.com has address 35.167.215.19

$ host 35.167.179.82._spf.sparkpostmail.com

35.167.179.82._spf.sparkpostmail.com has address 35.167.179.82

两者均需通过exists机制。

值得注意的是,SPF记录也包括ptr机制,虽然在最近的SPF RFC版本中已正式弃用,且推荐不使用,但是在执行SPF验证时必须支持。我们发布ptr机制是因为今天美国的邮箱提供商也不能完全解析exists机制。同样,指定的两个IP地址也需通过ptr机制:

$ host 35.167.215.19

19.215.167.35.in-addr.arpa domain name pointer mta523b.sparkpostmail.com.

$ host 35.167.179.82

82.179.167.35.in-addr.arpa domain name pointer mta522b.sparkpostmail.com.

8、“include”机制

格式为:

include:<domain>

表示指定域查询匹配。若查询返回不匹配或者有错误,接着处理下一个机制。警告:如果指定域没有一个有效的SPF记录,结果将返回永久性错误。某些邮件接收者会根据“PermError”拒绝接收邮件。

例如:在下面例子中,客户端IP1.2.3.4,当前域为example.com.

"v=spf1 include:example.com -all"

example.com没有SPF记录,结果为“PermError”。

假设example.comSPF记录为“v=spf1 a -all”,查询example.comA记录,

若与1.2.3.4匹配,返回“Pass”;

若不匹配,处理包含域的-all”,include整个匹配失败;

从这个例子的外部指令集可见,最终的结果仍为失败。

因为信任关系,include”机制可能会被认为有越权行为。需要确保“include”机制不会给跨用户伪造的信息SPF验证返回“Pass”。除非对指定的其他域技术机制到位,从而反正跨用户伪造,“include”机制应该提供“Neutral”处理结果而非“Pass”。即在“include:”前添加“?”前缀。例如:

"v=spf1 ?include:example.com -all"

如此看来,include”机制不宜选择。

(二)修改符Modifiers

Modifiers是可选的。在每个记录中每个修改符只能使用一次。未知修改符unknown-modifier忽略。

redirect”修改符

格式为:

redirect=<domain>

表示使用指定域的SPF记录替代当前记录。宏扩展的域也将取代当前域。

例如:在下面例子中,客户端IP为 1.2.3.4 ,当前域为example.com

"v=spf1 redirect=example.com"

example.com没有SPF记录,则返回错误,结果是未知的。

假设example.comSPF记录为“v=spf1 a -all”,查询example.comA记录,

若与1.2.3.4匹配,则结果为“Pass”;

若不匹配,则匹配失败,接着执行-all”机制。

exp”修改符

格式为:

exp=<domain>

SMTP接收者拒绝邮件,可以返回一个解释信息给发信者。SPF记录中可以包含一个解释字符串给发信者。这样,ISP可以通过网页进一步指导不合格的用户如何配置SASL

对域进行扩展,执行TXT查询,然后通过宏扩展得到TXT查询结果展示给发信者。其他宏可以用来提供一个自定义。

 

 

参考文献

1SPF RFC协议:http://tools.ietf.org/html/rfc7208

2SPF协议官方网站:http://www.openspf.org/Introduction

业务热线电话:(+86)021-52765253 021-61172807      上海哲涛网络科技有限公司版权所有 © 2005-2018       沪ICP备06058430-1号

沪公网安备 31011302000898号

校睿宝,培训机构学员管理软件,教师工资计算软件,消课管理软件!

手机智慧课堂答题,短信答题,微信答题!

数据备份软件,文件数据备份软件,文件备份软件,B/S架构备份软件,分布式计算机备份软件!