垃圾邮件制造者和电子邮件诈骗者经常使用假域名和电子邮件地址(或者合法域名和电子邮件地址)伪造电子邮件来欺骗用户,使他们认为邮件来自他们熟悉的个人或公司。例如,垃圾邮件制造者可能发送来自 president@whitehouse.gov 等地址的邮件,用户可能会误认为该邮件确实来自此地址。伪造电子邮件可能会欺骗用户打开未经许可的邮件,甚至向某个假的授权机构提供信息。另外,垃圾邮件制造者喜欢从不在 RBL 列表上的合法域发送电子邮件。
发件人策略框架 (Sender Policy Framework, SPF) 是一种可以在 SMTP 对话期间检测和拒绝伪造电子邮件的技术。具体地说,SPF 是一种协议,可以允许某个域明确地授权可以使用其域名的主机。此外,可能还要配置接收主机检查此授权。这样,SPF 可以显著减少出现伪造电子邮件的情况。
当邮件传入 Messaging Server 时,MTA 将进行 SPF 查询以确定地址是否确实来自该地址上的域。SPF 查询查阅 DNS 中属于此邮件的域的 TXT 记录 (domain)。 domain 可以是作为 HELO 或 EHLO 参数指定的域名(如果使用了 spfhelo 通道关键字),也可以是在 MAIL FROM: 命令中给出的邮件始发者地址中的域名(通常是 @ 字符之后的部分)。如果没有指定的或可用的域名,则在 HELO/EHLO 期间指定的那个域名将被用作 domain。请注意,大部分 ISP 会发布一个与其域匹配的授权 IP 地址列表。如果 IP 地址与域名不匹配,则邮件将被认为是伪造的。
在查询 DNS 之前,我们会先检查 SPF_LOCAL 映射表中是否存在匹配的域。如果在表中找到匹配的域,则首先使用此域。
如果在映射表中找到的记录包含 redirect = domain 子句,则会通过 DNS 查询重定向到域,而跳过递归和冗余的映射文件检查。
生成的 TXT 记录示例:
v=spf1 +mx a:colo.siroe.com/28 -all
对于此 RFC 支持的 SPF 记录而言,v=spf1 令牌是必须的。
+mx 指示我们检查 domain 的 MX 记录,并确认此 SMTP 连接的源 IP 地址与作为 domain MX 查询结果给出的 IP 地址之一匹配。如果存在匹配项,则 + 表示此操作的结果为 Pass。
a:colo.siroe.com/28 指示我们检查 colo.siroe.com 的 A 记录,然后确认此 SMTP 连接的源 IP 地址与 A 记录位于同一指定的 CIDR 子网,只比较 28 位(掩码 255.255.255.240)。未指定限定字符,因此使用默认值 +,表示匹配导致 Pass。
最后,-all 与任何其他项匹配,并导致 Fail。有关 SPF 记录更完整的介绍,请参阅 http://www.ietf.org/rfc/rfc4408.txt 上的 RFC 4408。
SPF 处理可以得到以下结果之一。下表显示了结果及其说明。
表 15–1 SPF 处理结果
结果 |
说明 |
---|---|
Pass |
查找已通过,表示找到了 SPF 记录,并且该记录验证了始发系统有权使用 domain。 |
Fail |
查找找到了匹配的 SPF 记录,但是,该记录明确地拒绝向 SMTP 客户端授予在 SMTP 事务期间使用 domain 的权限。我们 SPF 实现的默认行为是使用 5xx 回复拒绝 SMTP 命令。 |
SoftFail |
查找找到了匹配的 SPF 记录并且该记录也拒绝为 SMTP 客户端授权使用 domain,但是,拒绝不是很严格且记录不会指向彻底失败。我们实现的默认行为是接受邮件,但是在 Received-SPF: 标题中注明 SoftFail,以进行后续评测,如 Sieve 处理。 |
Neutral |
SPF 记录未声明授权 SMTP 客户端使用 domain。邮件将被接受。规范要求 Neutral 与下面的 None 处理方法一样。 |
None |
未找到匹配 SPF 记录,因此不进行任何 SPF 处理。 |
PermError |
在 SPF 处理中遇到永久错误,例如 SPF 记录中的语法错误、处理嵌套 SPF 记录时发生 DNS 故障(由于 include: 机制或 redirect= 修饰符所致),或处理嵌套 SPF 记录时超过为 SPF 处理配置的限制。默认行为是使用 5xx 回复拒绝 SMTP 命令。 |
TempError |
在 SPF 处理中遇到临时错误,很可能是由于查询 SPF 记录时 DNS 超时。默认行为是使用 4xx 回复拒绝 SMTP 命令。 |
在 SPF 处理完成后,Received-SPF: 标题将被写入记录 SPF 处理结果的邮件。然后,可以在 Sieve 处理期间查询此标题以做进一步考虑。如果启用 option.dat 文件中的 MTA 选项 MM_DEBUG (>0),则可以使用全面的调试。
SPF 仅仅是一种用于对抗垃圾邮件的工具,并不会解决所有问题。垃圾邮件制造者可以很容易地创建域,并添加 SPF TXT 记录而使该域看起来是合法的。另一方面,SPF 只对检测自已建立的 ISP 的伪造邮件很有效,尽管很多 TXT 记录使 SPF 看起来不会失败。
由于需要对每个邮件进行 DNS 查询,因此系统中有一个非常快的 DNS 服务器很重要。
设置 SPF 技术分为两步:
将通道关键字置于外来的 TCP 通道(通常是 tcp_local 通道,但如果允许从 tcp_local 切换到另一个通道,也可能存在其他通道)。请参见表 15–2。
在 option.dat 文件中设置选项。请参见表 15–3。
本节提供有关 SPF 通道关键字和 SPF MTA 选项的参考信息。SPF 支持是通过应用于外来 tcp_* 通道(通常是 tcp_local)的四个通道关键字实现的。下表显示了这些关键字及其说明。
表 15–2 SPF 关键字
关键字 |
说明 |
---|---|
spfnone |
禁用 SPF 处理 |
spfhelo |
为作为 HELO 或 EHLO 参数指定的域名启用 SPF 处理。 |
spfmailfrom |
为收到 MAIL FROM: 后提供给始发者信封地址的域名启用 SPF 处理. |
spfrcptto |
为收到 RCPT TO: 后提供给始发者信封地址的域名启用 SPF 处理. 处理方式与 spfmailfrom 一样,只是它在 SMTP 事务中被延迟,直到发出 RCPT TO: 命令并且收件人被确认为有效收件人后为止。 |
spfmailfrom 和 spfrcptto 关键字会发生冲突,应该只在通道上指定其中一个关键字。但是,可以同时使用 spfhelo 和 spfmailfrom(或 spfrcptto)以执行两种 SPF 检查。
还支持建立对 SPF 处理的限制,并可以针对各种 SPF 结果,控制是接受 SMTP 命令,还是以 4xx 响应(临时故障)或 5xx 响应(永久故障)拒绝该命令,这些 SPF 结果包括: Fail、SoftFail、PermError 和 TempError。
option.dat 中的以下 MTA 选项可以用于对 SPF 处理进行限制。
表 15–3 SPF 限制选项
选项 |
说明 |
---|---|
SPF_MAX_RECURSION |
指定由于 include: 或 redirect= 而导致的嵌套 SPF 记录中允许的递归数。超过此限制将导致 PermError。 默认值:10(由 RFC 规定) |
SPF_MAX_DNS_QUERIES |
指定需要 DNS 查找的机制数或修饰符数(包括 include:、a:、mx:、ptr:、exists:、redirect= 和 exp=)。请注意,此限制不会计为实际 DNS 查找的数量,因此一个机制可能会导致多个 DNS 查询。超过此限制将导致 PermError。 默认值:10(由 RFC 规定) |
SPF_MAX_TIME |
指定完成 SPF 处理允许的时间(以秒为单位)。超过此值将导致 TempError。默认值远大于 RFC 建议的值。 默认值:45 |
另外,可以配置 option.dat 中的以下 MTA 选项,以控制 SMTP 服务器在响应Fail、SoftFail、PermError 和 TempError 的 SPF 结果时所采取的行为。对于每种结果,SMTP 服务器都可发回 2xx(成功)、4xx(临时故障)或 5xx(永久故障)响应。另外,对于 Fail 和 SoftFail,MTA 能够区分 "all" 机制导致的 SPF 结果和明确引用的匹配。这样您可以区分特定结果和 SPF 记录的默认结果。上述任一选项的有效值是 2、4 或 5。值 2、4 和 5 分别对应来自 SMTP 服务器的 2xx、4xx 和 5xx 响应,这些响应是获取特定 SPF 状态的结果。因此,如果 SPF_SMTP_STATUS_FAIL=2 并且 SPF 记录明确地用 "-a:192.168.1.44"(我们的 IP 地址)阻塞我们,那么我们将使用 "250 OK" 接受该地址,而不是使用 5xx 进行响应。
表 15–4 SPF 故障和错误选项
选项 |
说明 |
---|---|
SPF_SMTP_STATUS_FAIL |
当 SPF 记录的匹配是 "-" 标志的机制("-all" 除外)时使用 默认值:5 |
SPF_SMTP_STATUS_FAIL_ALL |
当匹配机制为 "-all" 时使用 默认值:5 |
SPF_SMTP_STATUS_SOFTFAIL |
当 SPF 记录的匹配是 "~" 标志的机制("~all" 除外)时使用 默认值:2 |
SPF_SMTP_STATUS_SOFTFAIL_ALL |
当匹配机制为 "~all" 时使用 默认值:2 |
SPF_SMTP_STATUS_TEMPERROR |
当有临时故障(通常与 DNS 处理问题有关)时使用。 默认值:4 |
SPF_SMTP_STATUS_PERMERROR |
当有永久故障(通常由于语法或其他 SPF 处理期间发现的技术错误所致)时使用。(请注意,这将由非本地错误引发。) 默认值:5 |
此测试实用程序可用于测试 SPF 处理。
spfquery 不测试您的 SPF 配置。而测试启用 SPF 处理时会返回什么。
要求:必须作为有权运行 Messaging Server 二进制文件和访问其库的用户运行,例如,超级用户或 mailsrv 用户。
位置:msg-svr-base/sbin/
spfquery [-i ip-address] [-s sender-email] [-h helo-domain] [-e none | neutral | pass | fail | temperror | permerror] [-v] [-V] [?] domain |
下表显示了 spfquery 选项及其说明。
表 15–5 spfquery 选项
选项 |
说明 |
|
---|---|---|
-i ip address |
指定作为 SPF 查询远程地址使用的 IP 地址。默认值为 127.0.0.1。此选项也可以是 - -ip-address。 |
|
-s domain |
要使用的电子邮件地址,就像 MAIL FROM: 指定的一样。默认值:postmaster@domain。此选项也可以是 - -sender。 |
|
-h helo-domain |
域名,就像为 HELO 域指定的一样。请注意,此域自身不会受到验证,而是作为宏处理的补充信息。默认值与为 domain 指定的值相同。此选项也可以是 - -helo-domain。 |
|
-e result |
spfquery 将会比较 SPF 处理的结果与预期的结果,如果两个结果不同,将会打印一封邮件并以非零返回状态退出 spfquery;可能出现以下任一结果: none、neutral、pass、fail、softfail、temperror 或 permerror。此选项还可以是 - -expect。 |
|
-v |
在 SPF 处理期间,启用详细输出。此选项还可以是 - -verbose。 |
|
-V |
打印当前版本的 SPF 库。此选项还可以是 - -version。 |
|
|
打印此用法信息。此选项还可以是 - -help。 |
# /opt/SUNWmsgsr/sbin/spfquery -v -i 192.168.1.3 11.spf1-test.siroe.com Running SPF query with: IP address: 192.168.1.3 Domain: 11.spf1-test.siroe.com Sender: postmaster@11.spf1-test.siroe.com (local-part: postmaster) HELO Domain: 11.spf1-test.siroe.com 15:30:04.33: ---------------------------------------------------------------- 15:30:04.33: SPFcheck_host called: 15:30:04.33: source ip = 192.168.1.3 15:30:04.33: domain = 11.spf1-test.siroe.com 15:30:04.33: sender = postmaster@11.spf1-test.siroe.com 15:30:04.33: local_part = postmaster 15:30:04.33: helo_domain = 11.spf1-test.siroe.com 15:30:04.33: 15:30:04.33: Looking up "v=spf1" records for 11.spf1-test.siroe.com 15:30:04.35: DNS query status: Pass 15:30:04.35: "v=spf1 mx:spf1-test.siroe.com -all" 15:30:04.35: 15:30:04.35: Parsing mechanism: " mx : spf1-test.siroe.com" 15:30:04.35: Assuming a Pass prefix 15:30:04.35: Processing macros in spf1-test.siroe.com 15:30:04.35: Comparing against 192.168.1.3 15:30:04.35: Looking for MX records for spf1-test.siroe.com 15:30:04.41: mx02.spf1-test.siroe.com: 15:30:04.41: 192.0.2.22 - No match 15:30:04.41: 192.0.2.21 - No match 15:30:04.41: 192.0.2.20 - No match 15:30:04.41: 192.0.2.23 - No match 15:30:04.41: mx01.spf1-test.siroe.com: 15:30:04.42: 192.0.2.13 - No match 15:30:04.42: 192.0.2.11 - No match 15:30:04.42: 192.0.2.12 - No match 15:30:04.42: 192.0.2.10 - No match 15:30:04.42: mx03.spf1-test.siroe.com: 15:30:04.42: 192.0.2.32 - No match 15:30:04.42: 192.0.2.30 - No match 15:30:04.42: 192.0.2.31 - No match 15:30:04.42: 192.168.1.3 - Matched 15:30:04.42: Mechanism matched; returning Pass 15:30:04.42: 15:30:04.42: Parsing mechanism: "- all : " (not evaluated) 15:30:04.42: 15:30:04.42: SPFcheck_host is returning Pass 15:30:04.42: ---------------------------------------------------------------- |
如上所述,SPF 是一种尝试通过查找特定的 TXT 记录来防止电子邮件伪造的机制,这些 TXT 记录与邮件 FROM:(信封 from)地址中的域关联。此操作实际上包括几个 DNS 查找操作,最终可生成一个 IP 地址列表,这些地址被授权发送来自域的邮件。将根据此列表检查 SMTP 客户端的 IP 地址,如果没有找到该地址,则邮件可能被认为是伪造邮件。Messaging Server 6.3 版实现了 SPF 支持。
SPF 使提供邮件转发服务的站点面临严重的问题,例如大学站点(为其毕业生转发)或专业机构站点(为其成员转发)。转发者将发出来自任意发件人的邮件,这些发件人可能包括已经实现 SPF 策略的发件人,当然还包括没有列出转发系统(或可以使用其域的地址的系统) IP 地址的发件人。
发件人重写方案(或 SRS)提供了此问题的解决方案。SRS 使用转发者自己的域将原始发件人的地址封装在一个新地址中,从而解决了该问题。转发者自己的域仅在进行 SPF 检查时公开。使用地址时会将邮件(通常是通知)路由给转发者,这样可删除地址封装并将邮件发送到真正的目的地。
当然,地址封装并非全新的技术。与 percent hack 路由和 bang 路径一样,源路由是在 RFC 822 中定义的,并正好提供了此类功能。但是,在目前的 Internet 中,这些机制都存在问题,因为允许使用它们实际上是将您的系统变成了一个开放的中继。
SRS 通过向封装格式添加一个加密的散列函数和一个时间戳来处理此问题。地址只在某个时间段是有效的,过了这段时间就不能再使用了。散列函数防止修改时间戳或封装的地址。
SRS 还提供一个机制处理多次转发,而不会使地址长度过度增长。要使该方案生效,必须在所有实现 SRS 的系统中以相同的方式对 SRS 地址的某些方面进行格式化。
现在在 6.3P1 版本中已经实现了 SRS 支持。添加了以下 MTA 选项:
SRS_DOMAIN。必须向要在 SRS 地址中使用的域设置此选项。发送到该域的电子邮件必须始终路由到能对该域进行 SRS 操作的系统。SRS 处理将覆盖常规地址处理,因此站点必定能够使用其主域作为 SRS 域。
SRS_SECRETS。这是一个以逗号分隔的密钥列表,这些密钥用于编码和解码 SRS 地址。列表中的第一个密钥必定用于编码。解码时,将按顺序尝试每个密钥,以生成不同的散列值。如果有匹配的散列值,则解码操作将继续进行。
由于能够使用多个密钥,因此可以在不中断服务的情况下更改密匙:添加第二个密钥,等待所有以前发出的地址超时,然后删除第一个密钥。
SRS_MAXAGE。(可选)指定邮件超时前的天数。如果未指定该选项,则默认值为 14 天。
必须配置为选定 SRS 域处理电子邮件的每个系统,以进行 SRS 处理,并且三个 SRS 选项的设置必须一致。
设置这些选项后,即可启用 SRS 地址解码。编码则有所不同,应仅对您已知与转发活动关联的信封 From: 地址进行编码。SRS 编码由以下六个新的通道关键字控制:addresssrs、noaddresssrs、destinationsrs、nodestinationsrs、sourcesrs 和 nosourcesrs。
要进行 SRS 编码,必须符合以下三个条件:
(1) 当前源通道必须用 sourcesrs 标记(nosourcesrs 是默认设置)。
(2) 当前目标通道必须用 destinationsrs 标记(nodestinationsrs 是默认设置)。
(3) 当前地址在重写时必须匹配标记为 addresssrs 的通道( noaddress 是默认设置)。
只有在符合以上所有条件时才能进行编码。最简单的设置是纯转发操作的设置,其中所有的邮件都从 tcp_local 通道进入或发出,并且所有的非本地地址都需要进行 SRS 处理。在这样的设置中,tcp_local 将使用 sourcesrs、destinationsrs 和 addresssrs 这三个关键字进行标记。
最后,imsimta test -rewrite 得到了增强,可以显示 SRS 编码和解码的结果,而不管输入的地址是什么。 例如,地址 foo@example.com 可能生成类似以下的输出:
SRS encoding = SRS0=dnG=IS=example.com=foo@example.org
如果重写此编码的地址,则生成的输出为:
SRS decoding = foo@example.com
imsimta test -rewrite 还会显示 SRS 解码期间出现的所有错误。