5. 机制定义 (Mechanism Definitions)
本节定义两种类型的机制:基本语言框架机制和指定发件人机制。
基本机制有助于语言框架。它们不指定特定类型的授权方案。基本机制如下:
- all
- include
指定发件人机制用于识别一组
- a
- mx
- ptr (不推荐使用)
- ip4
- ip6
- exists
以下约定适用于在任何时候执行
-
如果指令中没有给出CIDR前缀长度,则比较
和IP地址是否相等。(这里,CIDR是无类域间路由,在[RFC4632]中描述。) -
如果指定了CIDR前缀长度,则仅比较
和IP地址的指定数量的高位比特是否相等。
当任何机制获取主机地址以与
几种机制依赖于从DNS获取的信息。对于这些DNS查询,除非另有说明,如果DNS服务器返回错误(RCODE不是0或3)或查询超时,机制停止,最顶层的check_host()返回"temperror"。如果服务器返回"Name Error"(RCODE 3),则机制的评估继续进行,就好像服务器返回无错误(RCODE 0)和零个答案记录一样。
5.1. "all"
all = "all"
"all"机制是一个总是匹配的测试。它用作记录中最右边的机制以提供明确的默认值。
例如:
v=spf1 a mx -all
"all"之后的机制永远不会被测试。"all"之后列出的机制必须被忽略。当记录中存在"all"机制时,任何"redirect"修饰符(第6.1节)必须被忽略,无论术语的相对顺序如何。
5.2. "include"
include = "include" ":" domain-spec
"include"机制触发check_host()的递归评估。
-
按第7节进行扩展。 -
使用结果字符串作为
评估check_host()。 和 参数与当前check_host()评估中的保持相同。 -
递归评估返回匹配、不匹配或错误。
-
如果返回匹配,则使用"include"机制的适当结果(例如,include或+include产生"pass"结果,-include产生"fail")。
-
如果返回不匹配或错误,父check_host()按下表恢复处理,
的先前值被恢复。
事后看来,名称"include"的选择不当。仅使用引用的SPF记录的评估结果,而不是字面上包含引用记录的机制。例如,评估引用记录中的"-all"指令不会终止整体处理,也不一定导致整体"fail"。(此机制更好的名称应该是"if-match"、"on-match"等。)
"include"机制使一个域可以指定多个管理上独立的域。例如,虚荣域"example.net"可能使用管理上独立的域example.com和example.org的服务器发送邮件。
Example.net可以说:
IN TXT "v=spf1 include:example.com include:example.org -all"
这将指示check_host()实际上检查example.com和example.org的记录以获得"pass"结果。只有当主机不被这两个域中的任何一个允许时,结果才是"fail"。
此机制是否匹配、不匹配或返回异常取决于check_host()的递归评估结果:
| 递归 check_host() 结果 | 导致 "include" 机制 |
|---|---|
| pass | 匹配 (match) |
| fail | 不匹配 (not match) |
| softfail | 不匹配 (not match) |
| neutral | 不匹配 (not match) |
| temperror | 返回 temperror |
| permerror | 返回 permerror |
| none | 返回 permerror |
"include"机制旨在跨越管理边界。当保持在一个管理机构内时,"include"通常不是最佳选择。例如,如果example.com和example.org由同一实体管理,并且如果两个域的允许主机集是"mx:example.com",则example.org可以指定"include:example.com",但最好指定"redirect=example.com"甚至"mx:example.com"。
使用"include"机制,可以授权管理上外部的主机集,但发件人策略的确定仍然是原始域的SPF记录的功能(由该记录中的"all"机制确定)。"redirect"修饰符更适合将授权和策略整合到要在ADMD内共享的公共集合中。Redirect更像是要在单个ADMD中的记录之间共享的公共代码元素。可以从单个记录中控制任意数量域的授权主机和策略。
5.3. "a"
如果
a = "a" [ ":" domain-spec ] [ dual-cidr-length ]
使用适合连接类型(IPv4或IPv6)的查询类型(A或AAAA)对
5.4. "mx"
如果
mx = "mx" [ ":" domain-spec ] [ dual-cidr-length ]
check_host()首先对
关于隐式MX的注意事项:如果
5.5. "ptr" (不推荐使用)
此机制测试
ptr = "ptr" [ ":" domain-spec ]
使用以下过程查找
-
对
执行DNS反向映射:如果地址是IPv4地址,则在"in-addr.arpa."中查找相应的PTR记录;如果是IPv6地址,则在"ip6.arpa."中查找。 -
对于返回的每条记录,通过查找其IP地址来验证域名。为了防止DoS攻击,必须应用第4.6.4节中定义的PTR处理限制。如果超过限制,处理终止,机制不匹配。
-
如果
在返回的IP地址中,则该域名被验证。
检查所有已验证的域名,看它们是否匹配
如果满足以下条件,此机制匹配:
是已验证域名的子域,或 和已验证域名相同。
例如,"mail.example.com"在域"example.com"内,但"mail.bad-example.com"不在。
注意:此机制速度慢,在DNS错误的情况下不如其他机制可靠,并且对.arpa名称服务器造成很大负担。如果使用,则域的主机必须有适当的PTR记录,并且"ptr"机制应该是最后检查的机制之一。经过多年的SPF部署经验,已经得出结论,它是不必要的,应该使用更可靠的替代方案。然而,它仍然作为SPF协议的一部分在使用,因此符合要求的check_host()实现必须支持它。
5.6. "ip4" 和 "ip6"
这些机制测试
ip4 = "ip4" ":" ip4-network [ ip4-cidr-length ]
ip6 = "ip6" ":" ip6-network [ ip6-cidr-length ]
ip4-cidr-length = "/" ("0" / %x31-39 0*1DIGIT) ; 值范围 0-32
ip6-cidr-length = "/" ("0" / %x31-39 0*2DIGIT) ; 值范围 0-128
dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
ip4-network = qnum "." qnum "." qnum "." qnum
qnum = DIGIT ; 0-9
/ %x31-39 DIGIT ; 10-99
/ "1" 2DIGIT ; 100-199
/ "2" %x30-34 DIGIT ; 200-249
/ "25" %x30-35 ; 250-255
例如,"ip4:192.0.2.128/28"匹配从192.0.2.128到192.0.2.143的IPv4地址。
如果
5.7. "exists"
此机制用于构造任意域名,该域名用于A记录查询。它允许更复杂的决策。此机制匹配当且仅当对结果域名的A查询返回任何地址。
exists = "exists" ":" domain-spec
实现应该注意,查询结果的唯一相关部分是代码本身。生成的地址记录(如果有)并不重要。
"exists"机制旨在允许将SPF授权决策委托给信息索引服务。例如,查询"client_ip.quarantine.example.org"对IP地址的SPF实现是微不足道的。但是该域可以用于发布各种隔离的IP地址列表。