邮件服务(二):安全、认证和垃圾邮件
背景
邮件服务系列博文中第一篇博客介绍了邮件服务的基本知识,了解了邮件是如何从发件人的邮件客户端经过不同的传输协议传送到收件人的邮件客户端的。这只是邮件的基本功能实现,但如果发生如下情况,整个邮件系统的生态环境将被扰乱:
- 被不法分子利用邮箱服务器发送垃圾邮件
- 被其他人伪造域名邮箱发送邮件
- 被中间人窃取账号密码、甚至重要邮件信息(中间人攻击)
- 即使自己拥有邮箱服务器的权限,无限制的滥用这个权利给其他邮箱发送邮件也是不好的
为了防止以上的种种情况,电子邮箱体系引入了更多的协议和机制。本文对此做浅显的总结,如有出错,还请指出和补充。
PTR
PTR(pointer record)是 DNS 记录中的一种。与 A 记录相反,它记录的是由 IP 到 FQDN(fully qualified domain name)的映射。
PTR 并非由 DNS 服务提供商控制,而是通过 IP 提供商来设定。比如博主使用 linode 的 VPS,独立 IP 由 Linode 提供,于是 PTR 也是由 Linode 给予的权限来做设定。
在 DNS 中设置 PTR 能增加邮件的非垃圾邮件权重(不同垃圾邮件黑名单判定机构有不同的判定规则,其中 PTR 是公认的指标之一)。
更多信息参考:Checking FQDN, Reverse-DNS/PTR, MX record
SPF
SPF(Sender Policy Framework)也是一种 DNS 记录。通过查询发送邮件者的 IP 地址和发送来的邮件地址做对比,进行简单的邮件验证。域名的管理员通过 SPF 记录或 TXT 记录来规定这个域名下哪些 IP 地址是“允许”发送邮件的,这样如果有人用别的 IP 地址来伪造发送的话,收件方可以根据 SPF 来选择拒收这些邮件。
最初的邮件系统没有考虑到各种安全因素,SPF 是在之后的发展过程中提出的。为了兼容不支持 SPF 记录的 DNS 服务器(本博客所使用的 DNSPod 就不支持 SPF 记录。),允许用 TXT 记录来表达 SPF。OpenSPF 建议在这段过渡时期同时添加 SPF 记录和 TXT 记录。
SPF 记录的语法规则见链接。这里给出一个简单的例子:
v=spf1 a mx -all
其中spf1
是版本号;a
代表把 A 记录对应的 IP 加入信任列表;mx
说明把这个域名上的 MX 记录所对应的服务器加入信任列表;-all
代表将不是从信任列表发出的邮件强制拒绝(hard fail)。
值得注意的是,经过测试发现 Gmail 并没有对 hard fail 的邮件执行拒绝,只是在 web 界面做出了一些提醒。这里有一篇相关的讨论:链接。
更多资料参考:如何给域名设置 SPF 记录
DKIM
DKIM(DomainKeys Identified Mail)是一种电子邮件的验证技术,使用非对称加密为邮件提供了签名与验证的功能。一般来说,发送方会在电子邮件的标头插入 DKIM-Signature 及电子签名,它们由私钥加密。而接收方则透过 DNS 查询得到公开密钥后进行验证。
DKIM 是由 DomainKeys 所改进的协定,大多数的运作方式与 DomainKeys 相同。在 2007 年 2 月时,DKIM 被列入互联网工程工作小组(IETF)的标准提案,并于同年 5 月成为正式标准。
传输协议
通过标准的 TCP/IP 做 SMTP 传输,没有任何安全保障,信息容易被截获。为了保证数据的安全,可以使用 SSL/TLS 提供加密链接。对于 IMAP 和 POP3 使用 SSL 加密尚可接受,而 SMTP 会遇到兼容性问题:POP3 和 IMAP 至于 MRA 和 MUA 有关,而使用 SMTP 协议的 MTA 会与其他的 MTA 沟通,除非全世界所有 MTA 节点同时升级为 SSL/TLS 加密的通信协议,否则会出现部分邮件无法中继的状况。
STARTTLS 很好的解决了这一问题。STARTTLS 是明文传输协议的扩展,它允许在明文连接的基础上将连接升级为加密连接,而不是使用另外一个加密接口。
一般的,邮箱服务器各协议端口设定如下:
- IMAP:明文端口 143,加密端口 993
- POP3:明文端口 110,加密端口 995
- SMTP:明文端口 25,SSL 加密端口 465,STARTTLS 加密端口 587
关于 SSL、TLS 和 STARTTLS 的区别,参见链接。
查看邮件原始信息
随着邮件在网络中的中转,邮件头会被加入许多必要信息。理解邮件头能帮助理解邮件服务的整个系统,在遇到垃圾邮件时,也可以助于定位问题所在。
GMAIL 的 Web 端可以查看邮件的详细信息。在邮件内容框里,点击右上角的更多选项,选中 Show original,如图:
下面展示 linode 发送给 someuser@gmail.com 的一封邮件的原始信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
- Delivered-TO: 发送的目的地邮箱地址。
- Received: 这个字段可以用来追踪邮件的传送路径。字段的基本格式为 from A by B for C。其中 A 为发送方,B 为接收方,C 为收件人邮箱地址。由于邮件可能经过多个 SMTP 服务器中继,故可以有多个 Received 字段。在邮件头中,以自底向上的顺序阅读它们。对于这封邮件,传送路径为:li114-242.members.linode.com -> mail2.linode.com -> mx.google.com -> 10.182.81.197 -> 10.114.246.38.
- Received-SPF: 用于记录 SPF 查询来验证邮件的安全性,参考 SPF Received Header
- Return-Path: 邮件的回复地址,来自于 SMTP 中得
mail from:
命令。 - Date: 邮件的发送时间。
- From: 客户端显示的发件人地址,可以跟 Return-Path 中得地址不同。
- To: 客户端显示的收件人地址。
实际上,Google 估计到 IP 地址为敏感信息,某些情况下会隐藏发送邮件标头中得发件人 IP 地址(资料链接)。
不同的客户端对这一功能做了不同的实现。比如 QQ 邮箱以前是能够查看邮件原始信息的,而现在已经关闭了这一功能。
第三方邮件服务
邮件服务器的基本功能实现虽然看起来简单,但为了让系统拥有足够的稳定性、邮件送达率,还是得付出不小的努力来与复杂的网络环境做斗争。许多公司为了集中注意力于自己的核心业务,会剥离出邮件发送的业务,使用第三方的邮件服务。国内国外涌现了不少第三方的邮件服务解决方案。自己没有相应的使用经验,谨贴出两个不错的介绍,供大家参考: