4. check_host() 函数
此描述不是应用程序编程接口定义,而是用于说明算法的函数描述.符合要求的SPF实现必须产生与此描述在语义上等效的结果.
check_host()函数获取SPF记录、解析它们,并评估它们以确定特定主机是否被允许使用给定身份发送邮件.执行此检查的接收ADMD必须按此处所述正确评估check_host()函数.
实现可以使用与此处定义的规范算法不同的算法,只要在所有情况下结果相同即可.
4.1. 参数 (Arguments)
check_host()函数接受这些参数:
-
- 发出邮件的SMTP客户端的IP地址,可以是IPv4或IPv6. -
- 提供所寻求的授权信息的域;最初是"MAIL FROM"或"HELO"身份的域部分. -
- "MAIL FROM"或"HELO"身份.
对于递归评估,
注意,
4.2. 结果 (Results)
check_host()函数可以返回第2.6节中描述的几个结果之一.根据结果,要采取的行动由接收方的本地策略决定.这在第8节中讨论.
4.3. 初始处理 (Initial Processing)
如果
如果
4.4. 记录查找 (Record Lookup)
根据记录的发布方式 (参见上文第3节),需要对
如果DNS查询返回服务器故障 (RCODE 2)或其他错误 (RCODE不是0或3),或者如果查询超时,则check_host()立即终止并返回结果"temperror".
4.5. 选择记录 (Selecting Records)
记录以版本部分开始:
record = version terms *SP
version = "v=spf1"
从查询返回的记录集开始,丢弃不以"v=spf1"版本部分开头的记录.注意,版本部分由SP字符或记录末尾终止.例如,版本部分为"v=spf10"的记录不匹配并被丢弃.
如果结果记录集不包含任何记录,check_host()产生"none"结果.如果结果记录集包含多个记录,check_host()产生"permerror"结果.
4.6. 记录评估 (Record Evaluation)
check_host()函数解析和解释SPF记录以找到当前测试的结果.首先验证记录的语法,如果记录中任何地方有任何语法错误,check_host()立即返回结果"permerror",而不进行进一步的解释或评估.
4.6.1. 术语评估 (Term Evaluation)
有两种类型的术语:机制 (mechanisms, 在第5节中定义) 和修饰符 (modifiers, 在第6节中定义).记录包含按以下增强巴科斯-瑙尔范式 (ABNF)指定的这些的有序列表.
terms = *( 1*SP ( directive / modifier ) )
directive = [ qualifier ] mechanism
qualifier = "+" / "-" / "?" / "~"
mechanism = ( all / include / a / mx / ptr / ip4 / ip6 / exists )
modifier = redirect / explanation / unknown-modifier
unknown-modifier = name "=" macro-string
; where name is not any known modifier
name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )
大多数机制允许在名称后使用":"或"/"字符.
修饰符总是在名称后立即包含等号('=')字符,并在可能是macro-string一部分的任何":"或"/"字符之前.
不包含"="、":"或"/"的术语是机制,如第5节中定义的.
根据[RFC5234]中ABNF符号的定义,机制和修饰符名称不区分大小写.
4.6.2. 机制 (Mechanisms)
每个机制从左到右依次考虑.如果没有更多机制,结果是第4.7节中描述的默认结果.
当评估机制时,可能发生三种情况之一:它可以匹配、不匹配或返回异常.
如果匹配,处理结束,限定符值作为该记录的结果返回.如果不匹配,处理继续下一个机制.如果返回异常,机制处理结束并返回异常值.
可能的限定符及其导致check_host()返回的结果如下:
"+" pass
"-" fail
"~" softfail
"?" neutral
限定符是可选的,默认为"+".
当机制匹配且限定符为"-"时,返回"fail"结果,并按第6.2节所述计算解释字符串.
具体机制在第5节中描述.
4.6.3. 修饰符 (Modifiers)
修饰符不是机制.它们不返回匹配或不匹配.相反,它们提供附加信息.尽管修饰符不直接影响记录的评估,但"redirect"修饰符在评估所有机制后会产生影响.
4.6.4. DNS 查询限制 (DNS Lookup Limits)
某些机制和修饰符(统称为"术语")在评估时会导致DNS查询,而某些则不会.以下术语会导致DNS查询:"include"、"a"、"mx"、"ptr"和"exists"机制,以及"redirect"修饰符.SPF实现必须在SPF评估期间将这些术语的总数限制为10个,以避免对DNS造成不合理的负载.如果超过此限制,实现必须返回"permerror".其他术语——"all"、"ip4"和"ip6"机制,以及"exp"修饰符——在SPF评估时不会导致DNS查询("exp"修饰符仅在稍后时间导致查询),并且它们的使用不受此限制.
当评估"mx"机制时,查询的"MX"资源记录数量包含在上述导致DNS查询的机制/修饰符的总限制10个中.除了该限制之外,每个"MX"记录的评估不得导致查询超过10个地址记录——"A"或"AAAA"资源记录.如果超过此限制,"mx"机制必须产生"permerror"结果.
当评估"ptr"机制或%{p}宏时,查询的"PTR"资源记录数量包含在上述导致DNS查询的机制/修饰符的总限制10个中.除了该限制之外,每个"PTR"记录的评估不得导致查询超过10个地址记录——"A"或"AAAA"资源记录.如果超过此限制,除前10个以外的所有记录必须被忽略.
差异的原因是MX记录的集合和内容由发布ADMD控制,而PTR记录的集合和内容由实际建立连接的IP地址的所有者控制.
这些限制是每个记录中每个机制或宏的限制,并且是对上述指定的查询限制的补充.
MTA或其他处理器应该对评估check_host()的最大经过时间施加限制.这样的限制应该允许至少20秒.如果超过这样的限制,授权的结果应该是"temperror".
如第11.1节末尾所述,在某些情况下,限制DNS查询返回答案计数为0的正面答案(RCODE 0)或"Name Error"(RCODE 3)答案的"术语"数量可能很有用.这些有时统称为"void lookups"(空查询).SPF实现应该将"void lookups"限制为2个.实现可以选择使这样的限制可配置.在这种情况下,建议默认值为2.超过限制会产生"permerror"结果.
4.7. 默认结果 (Default Result)
如果没有任何机制匹配且没有"redirect"修饰符,则check_host()返回"neutral"结果,就像最后一个指令指定了"?all"一样.如果有"redirect"修饰符,check_host()按第6.1节中定义的方式继续.
最好使用"redirect"修饰符或"all"机制来明确终止处理.尽管在每个未明确终止的记录末尾都有一个隐式的"?all",但明确提供它有助于调试工作.
例如:
v=spf1 +mx -all
或
v=spf1 +mx redirect=_spf.example.com
4.8. 域规范 (Domain Specification)
这些机制和修饰符中的几个有一个
注意:宏扩展的结果不受任何进一步的转义.因此,此功能无法产生DNS标签中合法的所有字符(例如,控制字符).然而,此功能足够强大,可以表达合法的主机名和DNS中使用的常见实用标签(例如"_spf").
对于几个机制,
使用语法无效的域评估check_host()的结果是未定义的.
注意:本文档及其前身没有规定如何正确处理语法无效的