Sun Java System Messaging Server 6.3 管理指南

第 15 章 使用发件人策略框架处理伪造的电子邮件

垃圾邮件制造者和电子邮件诈骗者经常使用假域名和电子邮件地址(或者合法域名和电子邮件地址)伪造电子邮件来欺骗用户,使他们认为邮件来自他们熟悉的个人或公司。例如,垃圾邮件制造者可能发送来自 president@whitehouse.gov 等地址的邮件,用户可能会误认为该邮件确实来自此地址。伪造电子邮件可能会欺骗用户打开未经许可的邮件,甚至向某个假的授权机构提供信息。另外,垃圾邮件制造者喜欢从不在 RBL 列表上的合法域发送电子邮件。

发件人策略框架 (Sender Policy Framework, SPF) 是一种可以在 SMTP 对话期间检测和拒绝伪造电子邮件的技术。具体地说,SPF 是一种协议,可以允许某个域明确地授权可以使用其域名的主机。此外,可能还要配置接收主机检查此授权。这样,SPF 可以显著减少出现伪造电子邮件的情况。

15.1 操作原理

当邮件传入 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),则可以使用全面的调试。

15.2 局限性

SPF 仅仅是一种用于对抗垃圾邮件的工具,并不会解决所有问题。垃圾邮件制造者可以很容易地创建域,并添加 SPF TXT 记录而使该域看起来是合法的。另一方面,SPF 只对检测自已建立的 ISP 的伪造邮件很有效,尽管很多 TXT 记录使 SPF 看起来不会失败。

15.3 预部署注意事项

由于需要对每个邮件进行 DNS 查询,因此系统中有一个非常快的 DNS 服务器很重要。

15.4 设置该技术

设置 SPF 技术分为两步:

15.5 参考信息

本节提供有关 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: 命令并且收件人被确认为有效收件人后为止。


注 –

spfmailfromspfrcptto 关键字会发生冲突,应该只在通道上指定其中一个关键字。但是,可以同时使用 spfhelospfmailfrom(或 spfrcptto)以执行两种 SPF 检查。


还支持建立对 SPF 处理的限制,并可以针对各种 SPF 结果,控制是接受 SMTP 命令,还是以 4xx 响应(临时故障)或 5xx 响应(永久故障)拒绝该命令,这些 SPF 结果包括: FailSoftFailPermErrorTempError

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 服务器在响应FailSoftFailPermErrorTempError 的 SPF 结果时所采取的行为。对于每种结果,SMTP 服务器都可发回 2xx(成功)、4xx(临时故障)或 5xx(永久故障)响应。另外,对于 FailSoftFail,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 

15.6 使用 spfquery 测试 SPF

此测试实用程序可用于测试 SPF 处理。


注 –

spfquery 不测试您的 SPF 配置。而测试启用 SPF 处理时会返回什么。


要求:必须作为有权运行 Messaging Server 二进制文件和访问其库的用户运行,例如,超级用户或 mailsrv 用户。

位置msg-svr-base/sbin/

15.6.1 语法


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、passfailsoftfailtemperrorpermerror。此选项还可以是 - -expect

-v

在 SPF 处理期间,启用详细输出。此选项还可以是 - -verbose

-V

打印当前版本的 SPF 库。此选项还可以是 - -version


-?

打印此用法信息。此选项还可以是 - -help

15.6.2 启用了调试的示例


# /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: ----------------------------------------------------------------

15.7 在 SPF 中使用发件人重写方案 (Sender Rewriting Scheme, SRS) 处理转发邮件

如上所述,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 地址解码。编码则有所不同,应仅对您已知与转发活动关联的信封 From: 地址进行编码。SRS 编码由以下六个新的通道关键字控制:addresssrsnoaddresssrsdestinationsrsnodestinationsrssourcesrsnosourcesrs

要进行 SRS 编码,必须符合以下三个条件:

(1) 当前源通道必须用 sourcesrs 标记(nosourcesrs 是默认设置)。

(2) 当前目标通道必须用 destinationsrs 标记(nodestinationsrs 是默认设置)。

(3) 当前地址在重写时必须匹配标记为 addresssrs 的通道( noaddress 是默认设置)。

只有在符合以上所有条件时才能进行编码。最简单的设置是纯转发操作的设置,其中所有的邮件都从 tcp_local 通道进入或发出,并且所有的非本地地址都需要进行 SRS 处理。在这样的设置中,tcp_local 将使用 sourcesrsdestinationsrsaddresssrs 这三个关键字进行标记。

最后,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 解码期间出现的所有错误。