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地址列表.