为你的Mail Server增加SPF记录

什么是SPF
就是Sender Policy Framework。SPF可以防止别人伪造你来发邮件,是一个反伪造性邮件的解决方案。当你定义了你的domain name的SPF记录之后,接收邮件方会根据你的SPF记录来确定连接过来的IP地址是否被包含在SPF记录里面,如果在,则认为是一封正确的邮件,否则 则认为是一封伪造的邮件。关于更详细的信息请参考RFC4408(http://www.ietf.org/rfc/rfc4408.txt

如何增加SPF记录
非常简单,在DNS里面添加TXT记录即可。登陆http://www.openspf.org/wizard.html 在里面输入你的域名,点击Begin,然后会自动得到你域名的一些相关信息。
a 你域名的A记录,一般选择yes,因为他有可能发出邮件。
mx 一般也是yes,MX服务器会有退信等。
ptr 选择no,官方建议的。

a: 有没有其他的二级域名?比如:bbs.extmail.org和www不在一台server上,则填入bbs.extmail.org。否则清空。
mx: 一般不会再有其他的mx记录了。
ip4: 你还有没有其他的ip发信?可能你的smtp服务器是独立出来的,那么就填入你的IP地址或者网段。
include: 如果有可能通过一个isp来发信,这个有自己的SPF记录,则填入这个isp的域名,比如:sina.com
~all: 意思是除了上面的,其他的都不认可。当然是yes了。

好了,点击Continue…..
自动生成了一条SPF记录,比如extmail.org的是
v=spf1 a mx ~all
并且在下面告诉你如何在你的bind里面添加一条
extmail.org. IN TXT “v=spf1 a mx ~all”

加入你的bind,然后ndc reload即可。
检查一下:
dig -t txt extmail.org

SPF 简介

SPF 诞生于2003年,它的缔造者 Meng Weng Wong 结合了反向 MX 域名解析(Reverse MX) 和 DMP (Designated Mailer Protocol) 的优点而付予了 SPF 生命。

SPF 使用电子邮件头部信息中的 return-path (或 MAIL FROM) 字段,因为所有的 MTA 都可以处理包含这些字段的邮件。不过微软也提出了一种叫做 PRA (Purported Responsible Address)的方法。PRA 对应于 MUA (比如 thunderbird) 使用的终端用户的地址。

这样,当我们把 SPF 和 PRA 结合起来的时候,就可以得到所谓的“Sender ID”了。Sender ID 允许电子邮件的接收者通过检查 MAIL FROM 和 PRA 来验证邮件的合法性。有的说法认为,MAIL FROM 检查由 MTA 进行,而 PRA 检查由 MUA 来完成。

事实上,SPF 需要 DNS 以某种特定的方式来工作。也就是必须提供所谓的“反向 MX 解析”记录,这些记录用来解析来自给定域名的邮件对应的发送主机。这和目前使用的 MX 记录不通,后者是用来解析给定域名对应的接收邮件的主机的。 SPF 有哪些需求?

要想用 SPF 来保护你的系统,你必须:

  1. 配置 DNS,添加 TXT 记录,用于容纳 SPF 问询的信息。
  2. 配置你的电子邮件系统(qmail, sendmail)使用 SPF,也就是说对服务器上每封进入的邮件进行验证。

上述第一步要在邮件服务器所属的域名服务器上进行调整,下一节中,我们将讨论这个记录的细节内容。你首先需要确定的一点是你的域名服务器(bind,djbdns)所使用的语法。但别担心,SPF 的官方网站提供了一个很好用的向导来指导你如何添加记录。

SPF 的 TXT 记录

SPF 记录包含在一个 TXT 记录之中,格式如下:

v=spf1 [[pre] type [ext] ] … [mod]

每个参数的含义如下表所示:

参数 描述 v=spf1 SPF 的版本。如果使用 Sender ID 的话,这个字段就应该是 v=spf2 pre 定义匹配时的返回值。

可能的返回值包括: 返回值 描述 + 缺省值。在测试完成的时候表示通过。 表示测试失败。这个值通常是 -all,表示没有其他任何匹配发生。 ~ 表示软失败,通常表示测试没有完成。 ? 表示不置可否。这个值也通常在测试没有完成的时候使用。 type 定义使用的确认测试的类型。

可能的值包括: 候选值 描述 include 包含一个给定的域名的测试
以 include:domain 的形式书写。 all 终止测试序列。
比如,如果选项是 -all,那么到达这条记录也就意味着测试失败了。但是如果无法确定,可以使用"?all"来表示,这样,测试将被接受。 ip4 使用 IPv4 进行验证。
这个可以以 ip4:ipv4 或 ip4:ipv4/cidr 的形式使用。建议使用这个参数,以减少域名服务器的负荷。 ip6 使用 IPv6 进行验证。 a 使用一个域名进行验证。
这将引起对域名服务器进行一次 A RR 查询。
可以按照 a:domain, a:domain/cidr 或 a/cidr 的形式来使用。 mx 使用 DNS MX RR 进行验证。
MX RR 定义了收信的 MTA,这可能和发信的 MTA 是不同的,这种情况基于 mx 的测试将会失败。
可以用 mx:domain, mx:domain/cidr 或 mx/cidr 这些形式进行 mx 验证。 ptr 使用域名服务器的 PTR RR 进行验证。
这时,SPF 使用 PTR RR 和反向图进行查询。如果返回的主机名位于同一个域名之内,就验证通过了。
这个参数的写法是 ptr:domain exist 验证域名的存在性。
可以写成 exist:domain 的形式。 ext 定义对 type 的可选扩展。如果没有这个字段,那么仅使用单个记录进行问询。 mod 这是最后的类型指示,作为记录的一个修正值。

修正值 描述 redirect 重定向查询,使用给出的域名的 SPF 记录。
以 redirect=domain 的方式使用。 exp 这条记录必须是最后一条,允许给出一条定制的失败消息。

IN TXT "v=spf1 mx -all exp=getlost.example.com"

getlost IN TXT "You are not authorized to send mail for the domain"

嘿!我是 ISP

ISP 实施 SPF 可能对于他们处于漫游状态(roaming)的用户带来一些麻烦,当这些用户习惯使用 POP-before-Relay 这样的方式处理邮件,而不是 SASL SMTP 的时候问题就会出现。

嗯,如果你是一个被垃圾邮件、地址欺骗所困扰的 ISP 的话,你就必须考虑你的邮件策略、开始使用 SPF 了。

这里是你可以考虑的几个步骤。

  1. 首先设置你的 MTA 使用 SASL,比如,你可以在端口 25 和 587 使用它。
  2. 告诉你的用户你已经使用了这个策略(spf.pobox.com 给出了一个通知的例子,参见参考文献)。
  3. 给你的用户一个宽限期,也就是说,把你的 SPF 记录加入到域名服务器之中,但使用“软失败”(~all)而不是“失败”(-all)。

这样,你就保护了你的服务器、你的客户和整个世界免受垃圾邮件之类的困扰了。

SPF 的官方站点上有很多信息,还等什么呢?

有什么需要担心的?

SPF 是一个对于欺骗的完美保护。但它有一个局限:传统的邮件转发方式不再有效了。你不能仅仅从你的 MTA 接受邮件并简单地重新发送它了。你必须重写发送地址。常见的 MTA 的补丁可以在 SPF 的网站找到。换句话说,如果你把 SPF 记录加入到了域名服务器,你就必须更新你的 MTA 来进行发送地址改写,即使你还没有对 SPF 记录进行检查。

结论

你可能觉得 SPF 的实施有点难以理解。不过这确实不算复杂,而且还有一个不错的向导来帮你完成这个转换(参见参考文献)。

如果你被垃圾邮件所困扰的话,SPF 将可以帮助你,保护你的域名免受伪造邮件地址的影响,你所要做的仅仅是在域名服务器上添加一行文本并配置你的电子邮件服务器而已。

SPF 的优点有很多。不过,像我对一些人所说的,这不是一夜之间就可以达到的,SPF 的好处将通过日积月累来表现出来,当其他人都使用它的时候就能明显地看到了。

我也提到了 Sender ID,这和 SPF 有关,但我没有去解释它。可能你已经知道原因了,微软的策略一向如此—软件专利。在参考文献中,你可以看到 openspf.org 对于 Sender ID 的立场声明。

domainkey的应用

Domainkeys 是由雅虎公司推出的一项确保电子邮件来源的真实性和内容的完整性的技术,它能让电子邮件服务商确定某封信是否真实的来自某个域和帮助他们的用户免受“钓鱼 欺诈邮件“的损害,比如用户常收到伪造这些机构的诈骗邮件,然后索取用户的信用卡卡号和密码。 而对于金融机构等公司也有保护用户的交易信息,提高用户满意度,减少客服咨询处理量和品牌保护的作用。

Domainkey的工 作原理是:发信域的负责人首先生成一对公私钥用于对它发出的邮件进行签名,公钥需要部署到公共的DNS 服务器上供所有收信方查询。而私钥则用于加密自己发出的信。这样只有含有用这个私钥加密后的字符串的邮件才是该域发出的邮件。收信方在收到邮件时,可以通 过公用DNS查询它的公钥,然后用该域的公钥来解密验证收到的邮件。如果验证是正确的,这封信就被投递到用户的邮箱里;如果验证失败,邮件将会被丢弃或者 标志。这样用户在所收到的邮件就能确保邮件确实是该域发出。

Domainkey的验证过程:例如user@a.com发送给 user@b.com,a.com的mta会在每封发出的邮件里根据私钥生成一个签名.当b.com的mx服务器在接收邮件时会根据发送方邮件头里的签名 查出selector(即s字段,用于签名.例如dk),则b.com的mx会查找dk._domainkey.b.com的txt记录得到公钥.然后使 用公钥对签名进行核实。

注意:Domainkey是在接收方邮件运营商支持的情况下才有效。否则对接收双方是没有意义的。

1、生成私钥和公钥
a、生成rsa的1024位私钥:
#openssl genrsa -out rsa.private 1024
#cat rsa.public
—–BEGIN PUBLIC KEY—–
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4HNUwh80iMCNlAL3wk8IUvJ+G
VblmXpW0AAoEOrcLkBqgYIgFY8Zh1nXrDMqH06/q0vaPN/tlDtgWchaQkFKoJeE9
QvLvq9dRDKJmosW9FfOevtRY31Bti7smaBZsev9n3g305ON6fOR02al8Kr7mxV8d
U0fkJhe8oym/IWIBBwIDAQAB
—–END PUBLIC KEY—–
b、根据私钥生成公钥:
openssl rsa -in rsa.private -out rsa.public -pubout -outform PEM

2、添加域名txt记录:
s1024._domainkey.yourdomain.com. TXT “k=rsa; t=y; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4HNUwh80iMCNlAL3wk8IUvJ+GVblmXpW0AAoEOrcLkBqgYIgFY8Zh1nXrDMqH06/q0vaPN/tlDtgWchaQkFKoJeE9QvLvq9dRDKJmosW9FfOevtRY31Bti7smaBZsev9n3g305ON6fOR02al8Kr7mxV8dU0fkJhe8oym/IWIBBwIDAQAB; n=A 1024 bit key;”
注:yourdomain.com是指你的所在域,如果你的邮件地址为user@a.com;则为a.com.
rsa为你的加密类型;
p=”MIGf……”,是上述第1步生成的公钥.
3、在MTA上添加domainkey的支持
1、qmail:这个可以按照下面链接(http://jeremy.kister.net/howto/dk.html)来做即可。
2、sendmail:这个可以按照下面链接(http://bbs.chinaunix.net/viewthread.php?tid=797739)来做即可。
3、ironport:这个可以按照下面链接(https://support.ironport.com/DKConfig/AsyncOS_4.6_User_Guide-21-3.html)来做即可。
4、lyirs:这个可以按照下面链接(http://www.lyris.com/help/lm_help/10.0/Content/setting_up_and_using_domainkeys.html)来做即可。
5、postfix:这个可以按照下面链接(http://bbs.chinaunix.net/viewthread.php?tid=1115806)来做即可。