第二章:简单邮件传输协议SMTP的 “Protocol” 部分使用Netcat发送邮件测试信任SMTP有什么问题?正在进行的测试SMTP响应代码和错误消息SMTP 回复代码增强状态代码传送状态通知灰名单反向散射DNS 阻止列表开发DNSBLDNSBL 递送DNSBL 查询和响应Milters邮件转发
电子邮件使用多种协议,但通常只有一种协议会让你满意。您可以控制本地邮件传输协议(Local Mail Transport Protocol —— LMTP)连接的两端。您可以设置古怪的客户端来复制用户的IMAP配置。DNS、TLS,这些都是众所周知的头痛问题。但是,简单邮件传输协议(Simple Mail Transfer Protocol —— SMTP)是所有电子邮件的基础,你不可能构建复制你与之通信的每一个whackadoo环境的测试系统。该协议的简单性是它如此成功和被滥用的重要原因。要运行自己的电子邮件系统,你必须深入了解SMTP的弱点。我们将从使用协议开始,继续滥用协议,并讨论状态消息、灰名单、阻止列表和转发。
与许多原始协议一样,SMTP是纯文本协议。客户端连接到TCP端口25,并与服务器交换仪式化文本。如果客户端和消息通过了服务器的完整性和有效性测试,则服务器接受消息并将其传递给收件人。
我们将使用 netcat(1)
来测试电子邮件。
Netcat需要两个参数:要连接的主机名和端口。它默认使用TCP。我在主机 mail.ratooperatedvehicle.com
上,连接到本地服务器上的端口25,向主机 mail.solveamurder.org
发送邮件。虽然 nc
接受主机名,但您必须通过编号标识端口:
xxxxxxxxxx
$ nc localhost 25
220 mail.ratoperatedvehicle.com ESMTP Postfix
我已连接到Postfix正在侦听的端口25。SMTP服务器的每个响应都以 reply code (回复代码)开头。200范围内的代码用于与服务器的正常通信。220是服务器声明它已准备好开始对话。Postfix还通过主机名、支持的SMTP版本和服务器软件名称进行自我介绍。此服务器使用扩展SMTP(ESMTP),这是自1995年以来的行业标准。
xxxxxxxxxx
EHLO mail.ratoperatedvehicle.com
Postfix已经自我介绍,所以我使用 EHLO
命令做同样的事情是公平的。原始SMTP使用 HELO
命令,但 EHLO
是客户端声明它也使用现代ESMTP的方式。我添加了我正在连接的主机名。
xxxxxxxxxx
250-mail.ratoperatedvehicle.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING
服务器以回复代码 250 进行响应,表示您的请求没有问题。它会确认我的主机名,并随后发送 250 回复代码,列出支持的协议功能。这些特征是什么?
PIPELINING 允许SMTP客户端在要求服务器响应之前组合命令,这在加载的服务器上尤其有价值。
SIZE 功能以字节为单位通知服务器它将接受的最大消息。
VRFY,或 verify ,告诉客户端服务器愿意确认地址是否存在。入侵者可以使用 VRFY 来探测合法帐户,而不会引起系统管理员的注意,因此许多网站都禁用了它。
具有间歇性连接的站点使用 ETRN 要求远程服务器立即重新传输所有排队的邮件。
ENHANCEDSTATUSCODES 功能允许SMTP服务器返回比常见三位数代码允许的更具体的错误。今天互联网上的所有内容都应该支持增强的状态码。
8BITMIME 承诺服务器保留每个字节的第8位。正确的ASCII是一个7位字符集,当字节范围从5位到12位时,这是可以的,具体取决于您的硬件。在90年代,人们普遍认为一个字节是8位。如果服务器没有声明8BITMIME支持,Postfix会将文本编码为引用可打印。
Delivery Status Notifications(DSN)是一种协议,用于目标服务器如何通知发件人存在问题。如果目标服务器接受消息但无法传递,则会使用它。我们将在本章稍后看到示例。
UTF-8 是现代字符编码标准。我们在这笔交易中所做的一切都是老式的ASCII码。 SMTPUTF8 功能允许您执行涉及非ASCII文本的SMTP操作。如果你的电子邮件地址和主机名是中文、西里尔文或阿拉伯语,这就涉及到了。
最后,旧的SMTP要求的邮件一次发送一行。 CHUNKING 允许发件人以更大或更小的块发送消息。
你会看到其他功能,但大多数功能甚至不如 8BITMIME 有用。
现在服务器已经告诉我们它能为我们做什么,我们使用 MAIL FROM
命令确切地声明我们是谁。根据标准,SMTP将向此地址报告任何问题。
xxxxxxxxxx
MAIL FROM:<root@mail.ratoperatedvehicle.com>
250 2.1.0 Ok
同样,250表示所请求的动作是可接受的。2.1.0是新的。这是一个扩展的状态码,提供更多信息。2.1.0表示发件人可以接受。
EHLO和MAIL FROM中提供的信息称为 envelope (信封)。如果接收MTA在接受邮件后出现问题,它会向信封的MAIL FROM地址发送警告。信封信息记录在邮件头中,但默认情况下不会显示给收件人。MAIL FROM地址通常出现在 Return-Path
标头中,但一些MTA使用不可见的 FROM
用户。您需要查看标题以确定系统的功能。如果消息从一个服务器转发到另一个服务器,则消息信封会发生变化。
此服务器接受来自我的电子邮件地址的邮件,因此我可以使用 RCPT TO
(receipt to)命令在另一台服务器上选择收件人。
xxxxxxxxxx
RCPT TO:<mwlucas@mail.solveamurder.org>
250 2.1.5 Ok
250表示此操作是可接受的,扩展状态代码2.1.5声明收件人是可接受。我们现在可以发送我们的信息了。
xxxxxxxxxx
DATA
354 End data with <CR><LF>.<CR><LF>
DATA
命令是您发送消息内容的地方。我们得到回复代码354,它被保留用于接受消息。以用户可见的标题开始您的邮件。留一个空行,将邮件的标题与正文分开。在一行中单独用一个句点结束消息。
xxxxxxxxxx
From: <root@mail.ratoperatedvehicle.com>
To: <mwlucas@mail.solveamurder.org>
Subject: manual email message
I sent this message via netcat, like a rebel!
.
前三行 From
、 To
和 Subject
是邮件客户端显示的内容。在这段时间里,你又回到了主SMTP会话中。您可以直接终止netcat会话,但许多邮件程序会记录这种突然的断开连接,作为可能的网络问题的提示。礼貌点,说再见。
xxxxxxxxxx
QUIT
250 2.0.0 Ok: queued as 899B210471
221 2.0.0 Bye
稍后,我在目标计算机上的帐户将收到一封电子邮件。
我们已经了解了如何将邮件从一个主机发送到另一个主机。但是,如果您让第三台主机参与此事务,会发生什么?我仍然在我的主机 mail.ratooperatedvehicle.com
上,我已经连接到 mail.solveamurder.org
。我们已经完成了最初的问候交流,并开始发送实际邮件。
xxxxxxxxxx
MAIL FROM:<mwlucas@ratoperatedvehicle.com>
250 2.1.0 Ok
我的发件人地址很好。但我要让这个系统向与此无关的主机发送邮件。
xxxxxxxxxx
RCPT TO:<mwl@mwl.io>
454 4.7.1 <mwl@mwl.io>: Relay access denied
哦,新的状态消息!4xx类的状态消息是临时错误。你可以稍后再试。扩展状态代码4.7.1也是新的。前导4也意味着这是暂时的失败,而7表示这是一个安全策略。.1表示此消息未经授权,已被拒绝。你可以稍后再试。它可能不会改变。
这是 mynetworks
和 mynetworks_style
选项的结果。我们已经说过我们信任哪些IP地址。对于我们的初步测试,我们的主机只信任自己。它永远不会为他人转发邮件。
SMTP语言是高度形式化的,你必须在正确的地方使用正确的术语,但它是一种计算机协议。为什么它积累了如此多的厌恶?
因为它很容易被愚弄。考虑以下章节。
x$ nc localhost 25
220 mail.ratoperatedvehicle.com ESMTP Postfix
EHLO mail.ratoperatedvehicle.com
250-mail.ratoperatedvehicle.com
...
MAIL FROM:<mwlucas@mail.ratoperatedvehicle.com>
250 2.1.0 Ok
RCPT TO:<mwlucas@mail.solveamurder.org>
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
From: Emperor Palpatine <ImmortalLord@galacticempire.gov>
To: Loyal Lackey <mwlucas@mail.solveamurder.org>
Subject: Promotion
Congratulations! You have been selected as Lord Vader's new personal assistant. Please notify your next of kin and report for duty.
.
250 2.0.0 Ok: queued as 5D7C5105CB
QUIT
221 2.0.0 Bye
EHLO
、 MAIL FROM
、 RCPT TO
和 DATA
命令都与我们之前使用的完全相同。正是数据内部的东西让一切变得不稳定。标准邮件客户端默认只显示DATA中的邮件头,因此大多数用户会看到此消息来自Emperor Palpatine。如果收件人碰巧为帝国工作,他们可能会出现在他们的新工作中。
在现实生活中,邮件发件人和发件人的标题应该匹配吗?对。他们通常?也是的。他们这样做最好吗?当然!匹配的标题使电子邮件更具可交付性。但他们必须这样做吗?并非如此。
如果我们今天设计一个协议,它就不会像这样工作。但SMTP是早期互联网的遗迹,当时电子邮件是一个奇迹,垃圾邮件发送者收到了空军军官的个性化威胁。SMTP的许多辅助协议减轻或减少了这些缺陷。这就是为什么我告诉你不要与世界共享你的测试服务器。当然,在你有一些基本的保护措施之前,不要告诉任何人它们的存在。
手工测试原始SMTP是邮件管理员教育的一部分,也是比在精神上把宇宙飞船拖出沼泽更好的派对技巧。许多反垃圾邮件系统,包括rspamd,都讨厌手工伪造的电子邮件。如果您经常需要在协议级别测试电子邮件,请调查Swaks(http://www.jetmore.org/john/code/swaks/)。
SMTP服务器的每个响应都包含一个三位数的 回复代码 (reply code 有时称为 响应代码 —— response code )。回复代码正式声明了服务器对您的命令的反应。之后通常会对该回复进行文本解释。回复代码包括 220
(服务已就绪)、250
(请求可接受)和 550
(请求不可接受,把自己扔进sarlaac坑)。接触SMTP的人往往会慢慢从文本解释中吸收响应代码的含义,但每个代码都有特定的形式含义。这篇文章扩展了这一含义,确切地解释了为什么你应该把自己扔进一个坑里。这些代码旨在灵活,易于人类操作员解释。回复代码后的破折号表示后面有更多的回复行,而空格表示此行是唯一的回复。
事实证明,灵活的代码缺乏精度,对文字思维的软件提供的指导不足。此外,响应代码的设计没有留下扩展的空间。开发了一种新的增强邮件系统状态代码系统,以提供精确的错误。增强代码由三个数字组成,如 2.1.5
或 5.7.13
,并立即出现在响应代码之后。
我们将分别查看每组消息。
每次客户端发出SMTP命令时,服务器都会发出一个 reply code ,声明它对该代码的反应。RFC 5321中记录了基本的回复代码,尽管后来的标准定义了偶尔的附加组件。虽然像“我已经做到了”这样的回复是通用的,但表示错误的回复代码通常使用自由形式的文本来定义精确的错误。系统管理员可以更改该文本,但数字必须保持不变。
回复代码是三位数。每个数字都有特定的含义,具体取决于该空间中的数字。这些代码被选择为类似于FTP回复代码,因此一些数字被故意跳过。
第一位数字表示回复的一般类型。
354
,用于告诉客户端开始发送他们的消息文本。第二位数字清楚地说明了响应的类型。将第一位和第二位数字结合起来,找出这是什么类型的回复。
最后一位数字没有跨类别含义,用于更具体地定义回复。这就是为什么221可以是状态报告,而551可以告诉客户去其他地方。
reply codes 最早出现在1982年的RFC 822中。后来的标准在添加新代码的同时保留了旧的回复代码。关于2023年的完整列表,请参阅RFC 5321及其更新,但其中许多代码很少出现。以下是一些最常见的回复代码,它们根据标准的形式描述及其含义:
220 client-hostname Service is ready
你可以继续。
250 client-hostname Requested action okay and completed
无论客户要求什么,都发生了。
354 Start mail input; end with
服务器将接受您的消息。
421 client-hostname Service not available
服务器不仅拒绝继续SMTP命令,而且拒绝继续整个SMTP会话。您需要重新连接才能重试。
450 Requested mail action not taken: mailbox unavailable
用户帐户出现一些临时错误,导致服务器无法完成客户端的命令。
451 Requested action aborted: local error in processing
服务器上有问题。希望系统管理员会注意到存在问题。
452 Requested action not taken: insufficient storage space
服务器磁盘不足。
500 Syntax error, command unrecognized
也许你拼错了RCPT TO。也许一个Wookie敲击了你的键盘。
502 Command not implemented
您请求了服务器不支持的SMTP功能。
550 Requested action not taken: mailbox unavailable
您无法向此人发送邮件,重试也无济于事。
554 Transaction failed
无论你要求什么,都不会发生。今天不是你的日子。走开。
服务器可以将文本更改为更适合错误的内容。我的服务器使用灰名单(第2章)。如果新主机联系他们,他们将收到451错误和消息 Greylisting in action, please come back later 。客户端在收到451时会自动重试,但任何查看日志的系统管理员都会了解发生了什么。
通常用第一位数字来指代错误类别。当有人说“400错误”时,这并不意味着具体的代码是400。没有特定的代码400。它们表示从400-499开始的错误。你也会看到它被写成4xx。
你可以很容易地记住这个简单的三位数代码系统,或者阅读文本并弄清楚发生了什么。每个类别最多支持十类一般错误。
不幸的是,即使按类别划分,现实世界也会出现十多个错误。这就是增强状态代码发挥作用的地方。每个增强代码都由标准严格定义。您可以在回复代码中添加澄清文本,如果您需要新的增强代码,则必须通过IETF和IANA进行工作。每个增强代码由三个数字组成,用句点分隔。
第一个数字是类,它定义了一种通用的消息类型。与回复代码一样,2
表示成功,4
表示持续的暂时性失败,5
表示永久性失败。没有 1
或 3
。
第二个数字是主题,定义了此消息属于系统的哪个部分。与回复代码不同,我们目前有八个值。
0
表示没有其他信息。1
是关于地址的。这是一条关于发件人或收件人地址的消息。2
是关于邮箱的。邮箱错误绝大多数与收件人有关,但在某些情况下,此类消息表明发件人有问题。3
声明此代码与目标邮件系统有关。4
是关于网络和路由的。它与 3
非常相似,只是用于支持LDAP、DNS等邮件系统的服务。5
表示此代码与邮件传递协议有关。6
表示此消息与消息内容有关。这可能是编码错误、内容类型等。7
表示这是安全或策略代码。将类和主题结合起来,可以立即识别出一般类型的问题。如果您发送邮件,服务器以 4.3 开头的增强状态回复,这意味着“目标邮件系统发生了一些事情,但您可以重试。”以 2.1 开头的代码说,“一切正常,但这里有一些关于收件人邮箱的详细信息。” 5.7.anything 声明“根据我们的政策,您不能重试。”任何被政策拒绝的人都可能做了一些事情来获得拒绝,您阻止发送邮件的发件人类型可能会重试,但他们自己也有这个问题。
最后一位数字是枚举的状态代码,表示特定错误。虽然几乎任何主题都可以应用于每个类,但枚举状态代码按主题有不同的定义。枚举状态代码 1
在4.1.1、4.2.1、4.3.1等中意味着完全不同的东西。识别完整状态代码的唯一方法是查看IANA的简单邮件传输协议(SMTP)增强状态代码注册表( Simple Mail Transfer Protocol (SMTP) Enhanced Status Codes Registry ),可在https://www.iana.org/assignments/smtp-enhanced-status-codes/smtp-enhanced-status-codes.xhtml几乎可以肯定的是,你最不讨厌的搜索引擎也会将其编入索引。然而,这里有一些你会看到的更常见的代码。
增强代码通常与回复代码结合出现。请看上一节,例如我们亲手发送邮件。你也会在日志中看到它们。他们开发的一个主要驱动因素是用于交付状态通知。
用户想知道他们发送的电子邮件是否被接收、阅读或误入歧途。传递状态通知(Delivery Status Notifications ——DSN)发挥了这一作用。大多数情况下,这些通知不会返回给人类发件人,而是出现在错误日志或SMTP事务中。设计扩展状态代码的一个目的是支持详细的DSN系统。
邮件发送者可能想知道收件人何时阅读他们的邮件,一些客户端允许用户请求DSN。事实证明,当这些发件人依次收到邮件时,他们并不那么热衷于让别人知道他们已经阅读了他们的电子邮件。许多人在阅读电子邮件时更喜欢隐私。此外,电子邮件客户端只能看到邮件何时打开,而不是收件人何时实际阅读文本。虽然像Microsoft Exchange这样的一些企业系统仍然提供不可靠的“已读回执”通知,但它们不是基于DSN构建的。
您最常看到DSN的地方是邮件系统日志或退回邮件中。DSN始终是增强的状态代码。
电子邮件是在硬件价格昂贵、冗余不在预算范围内的时代设计的。由于硬件不具有容错性,协议必须具有容错性。SMTP保留了400回复代码,专门用于“我现在不接受此邮件,但请稍后重试”。合法的MTA接受该邮件,并在几分钟或一小时后重试,或立即绕过备份MTA。垃圾邮件机器人使用草率的SMTP堆栈,因此可以在数百万个电子邮件地址中进行竞争。一旦他们处理完受害者名单,他们可能会再次尝试联系你。这可能需要几天的时间。在此之前,反垃圾邮件活动家会将它们添加到DNS阻止列表(DNS block list —— DNSBL)中。这就留下了一个显而易见的解决方案:当任何SMTP客户端第一次联系您的MTA时,告诉它稍后回来。保留返回的服务器列表,并从现在开始立即接受他们的邮件。
合法主机将重试。那些非法返回的人不会通过你的反垃圾邮件防御。与阻止列表不同,这种方法被称为 greylisting (灰名单)。
灰名单是一种分裂的技术。当一个网站第一次给你的服务器发邮件时,灰名单会延迟几分钟到几个小时的消息。如果你所在组织的人坚持认为电子邮件是即时的,尽管有所有相反的证据,这是一个问题。如果一些网站使用电子邮件发送仅在十分钟内有效的身份验证码,那就是一个问题。(问题是网站通过不合适的协议传递临时数据,但这仍然是一个问题。)一些域使用大型MTA服务器场,重新发送尝试几乎从不来自同一IP地址。这绝对是个问题。
有些人从灰名单中获得了很好的结果,而且痛苦很小。有些人发现问题大于好处。与系统管理中的所有内容一样,您有权选择您喜欢的痛苦。即使您不使用灰名单,您的电子邮件系统也必须容忍这样做的MTA。灰名单与临时故障无法区分。
灰名单的一个有趣之处在于,你可能会意外地部署它。Postscreen(第9章)包括深度检查功能,这些功能不是故意灰名单,但效果与灰名单无法区分。Rspamd(第14章)实现了有意的灰名单。如果您想要一个更灵活的灰名单策略服务器,请考虑Postgrey(http://postgrey.schweikert.ch/).
如果MTA要拒绝邮件,它应该在SMTP对话期间这样做。您的MTA不应接受邮件,关闭连接,然后向发件人生成一条新邮件,说“抱歉,我无法传递此邮件。”此类邮件称为 backscatter —— 反向散射,而且总是不好的。它甚至可以用作攻击向量!
反向散射通常是垃圾邮件的结果。如果垃圾邮件发送者伪造您的电子邮件地址作为其垃圾邮件的来源,您可能会收到数十或数百条“您的邮件无法送达/令人反感/被禁止”的通知。配置错误也会产生反向散射。
如果你的服务器生成了一封新邮件,收件人是电子邮件的明显来源,那么它很可能是在回复垃圾邮件。这些回复充其量只会惹恼一个完全无关的人,更糟糕的是,你的服务器会被标记为垃圾邮件生成器。对无法送达邮件的自动回复通常包含该邮件,因此您的反向散射将包括最初导致问题的垃圾邮件!
只接受可投递邮件。在初始SMTP连接期间拒绝其余操作。
大多数垃圾邮件来自受恶意软件感染的计算机或垃圾邮件机器人(spambots)。计算机所有者可能不知道感染。大型ISP通常会阻止端口25,以防止受感染的消费者机器喷出垃圾,这对于那些想在家运行MTA但确实可以控制ISP支持负载的知识渊博的人来说很烦人。然而,维护不善的服务器也会受到感染,而且这些服务器的互联网连接未经过滤。
垃圾邮件斗士成立了组织来追踪受感染的宿主。当识别出新的垃圾邮件源时,其IP地址将添加到列表中。系统不断受到攻击,并转化为垃圾邮件源。它们得到了保护和修复,但速度不太稳定。每次主机请求SMTP连接时,您都必须检查阻止列表。这些阻止列表通过DNS分发,称为DNS阻止列表(DNS Block Lists —— DNSBL)。(您还将看到信誉阻止列表——Reputation Block Lists——RBL,但该术语是商标。)通过拒绝来自可靠阻止列表上主机的所有邮件,您可以立即阻止绝大多数垃圾邮件。
这就是问题所在:一个可靠的阻止列表。
这就是互联网。就像任何人都可以运行一个网站一样,任何人都能发布一个阻止列表——而且你无法通过名字来判断。这些项目绝大多数是由愤怒的极客创建的,而且往往超出了他们的初衷和规模。“吃垃圾邮件的猴子”是一个非常值得信赖的列表提供商,而一些看起来像官方的列表应该更恰当地命名为“HTML电子邮件是不道德的,我心怀怨恨”。
如何找到可靠的阻止列表?Spamhaus(https://spamhaus.org)是最大和最著名的,但还有其他的,你不应该只依赖一个。与您的系统管理员同事交谈,看看他们使用谁。您还可以在互联网上找到黑名单测试工具,这些工具通常由商业服务提供,作为说服您外包电子邮件的一部分。这些工具包括他们检查的阻止列表列表列表。我用过MX工具箱(https://mxtoolbox.com)几十年来,但对我来说,摧毁一家公司的最好方法就是在书中提及它,所以四处看看。
DNSBL并不完美。新感染的系统在被识别并添加到列表之前可能会喷出数千个垃圾邮件。添加主机可能是错误的,也可能是由于临时问题。如果您错误配置了MTA并成为开放中继,您将进入一个列表——即使您立即发现错误并在三分钟内修复问题,反垃圾邮件软件也会捕获通过您的主机中继的垃圾邮件并将您添加到这些列表中。
人们还维护着DNSBL列表,如“上周注册的域名”或“垃圾邮件陷阱中识别的域名”。你应该使用哪一个?这完全取决于你的个人垃圾邮件容忍度和你使用的软件。如果你对照DNSBL检查EHLO语句以检查消息体中的域,它将无法正常工作。
每个DNSBL都有自己的编辑政策。您可能需要一个积极的DNSBL来阻止任何可疑的东西,或者一个更宽容的列表。为了演示,我使用Spamhaus ZEN(https://www.spamhaus.org) 和 SpamRATS(https://www.spamrats.com)。对于小型非商业MTA来说,两者都是免费的。检查每个DNSBL提供程序,以获取正确的查询区域来访问列表——记住,从公共解析器查询这些区域是没有用的。
“每当主机发送垃圾邮件时,它都会被添加到阻止列表中”听起来很简单,但它涵盖了许多问题。什么是垃圾邮件?它是如何被识别的?你可以称之为“未经请求的商业电子邮件”,但我收到了垃圾邮件,鼓励我皈依某种特定的信仰。你认为每个人都应该改吃严格的纯素饮食,这可能是非商业性的、真诚的,甚至对人类的持续生存都有好处,但如果你在一小时内将其发送到50万个随机邮箱,那它就是垃圾邮件。
真正的测试是:收件人想要这条消息吗?他们要求了吗?这是正在进行的讨论或关系的一部分吗?
垃圾邮件发送者通过购买列表和抓取网站来收集电子邮件地址。这些列表通常都是过时的电子邮件地址,但卖家并不在乎。如果会议发布了与会者名单及其电子邮件地址,这些地址就会成为垃圾邮件的诱饵。DNSBL维护人员利用这一点来创建垃圾邮件陷阱,即从未发送过邮件也不应该收到邮件的电子邮件地址。他们在专用网页上公布垃圾邮件陷阱地址,垃圾邮件发送者会发现这一点。根据定义,任何发送到垃圾邮件陷阱的东西都是不需要的。发送主机可能会立即被添加到阻止列表中。
人们不再使用的电子邮件地址可以重新部署为垃圾邮件陷阱。如果有人离开一个组织,他们的电子邮件地址被关闭,发往该地址的邮件应该会被退回。负责的记者将停止联系该地址。几年后,发送到该地址的任何内容都可能是垃圾邮件,但不一定是垃圾邮件。一个老朋友可能会时不时地伸出手来,得到一个反弹。一个主机在禁用几个已失效的电子邮件地址几年后试图给它们发电子邮件,几乎可以肯定是在发送垃圾邮件。
垃圾邮件也可以通过邮件内容来识别。如果我们知道某个域名被恶意软件或骗子使用,那么任何在标题或正文中包含该域名的电子邮件都可能是垃圾邮件。
对于可疑行为,阻止列表维护者也可能将主机添加到阻止列表中。一个试图回复它收到的每一条垃圾邮件的服务器让成千上万的系统管理员的生活变得更加困难。这种行为会让你被屏蔽。
最后,还有一种历史悠久的方法,即有人阅读邮件并将其放入垃圾邮件文件夹。可以分析这些消息中的共同元素。
大多数阻止列表都是通过DNS查询的。这就是为什么你的邮件系统必须有自己的递归名称服务器。阻止列表限制了它们从单个IP接受的查询数量,而谷歌的公共解析器很快就会超出这些限制。当限制溢出时,查询要么被忽略,要么总是用“阻止”或“接受”来回答。你的服务器要么欣然接受所有垃圾邮件,要么拒绝所有邮件。
一些阻止列表也通过边界网关协议(Border Gateway Protocol —— BGP)等协议传递。如果你是一位经验丰富的网络运营商,你可以考虑在网络边界添加一个阻止列表BGP提要。阻止已知的垃圾邮件发送者连接到您的网络将保护您网络中的每一台主机。任何了解足够BGP来实现这一点的人都了解风险。对于其他人来说:当你的网络经理说他们不会这样做时,他们有充分的理由。
反垃圾邮件阻止列表是高度动态的,通常不可下载。下载整个阻止列表将是低效的,因为戳破服务器的主机数量只是互联网上产生垃圾邮件的主机的一小部分。您必须配置系统,以便通过支持的方法之一查询列表。我们将专注于DNS查询。
一些阻止列表提供商还提供其他类型的阻止列表,这些阻止列表的变化较慢,并且可能是可下载的。示例包括Spamhaus的“不路由或对等”(Don’t Route Or Peer —— DROP)地址列表,该列表由区域注册表分配给已知的犯罪活动,以及包含犯罪分子子分配的扩展DROP列表。不过,此类阻止列表的内容也包含在更广泛的DNS检查中,因此不需要下载它们。
Postfix支持通过 postscreen(8)
进行DNSBL检查(第9章)。
RFC 5782描述了完整的块列表协议,但以下是基本内容。
DNSBL区域类似于 in-addr.arpa
中使用的反向区域。IP地址以相反的顺序列出,以便更具体的标识符首先出现。这出现在阻止列表区域内。块区的缓存时间很短,因此更改会在一两个小时内分发。假设我使用 spam.mwl.io
区域运行DNSBL。您想检查主机 192.0.2.84
的DNSBL。反转IP地址(84.2.0.192
)并将其粘贴在阻止列表区域的前面。
xxxxxxxxxx
$ dig 84.2.0.192.spam.mwl.io +short
$
无结果(或NXDOMAIN)意味着该地址不在阻止列表中。
xxxxxxxxxx
$ dig 85.2.0.192.spam.mwl.io +short
127.0.0.9
127.0.0.2
127.0.0.4
127.0.0.2
的响应表示此主机在阻止列表中。所有阻止列表的响应都在127/8中,这样如果列表被滥用,就不会损坏网络。其他127/8 IP地址的响应提供了有关此地址被阻止原因的更多详细信息。这些代码是特定于块列表的。不过,您可能会发现一个人类可读的TXT记录,它提供了一个基本原理。
xxxxxxxxxx
$ dig 85.2.0.192.spam.mwl.io +short txt
"Believes that Luke was the hero of Star Wars when it was clearly Marcia Lucas"
再次强调:并非所有块列表都是相等的。
像Postfix这样可靠的MTA是故意简单的。它们不分析消息的内容,甚至不验证SPF和DKIM等附加协议。相反,大多数邮件系统使用邮件过滤器(mail filter或milter)接口将这些任务交给外部守护进程。Milters是为Sendmail创建的,但很快成为Unix标准。milter这个词可能意味着API、程序或过滤器本身。
Milters让专门的、无特权的程序执行特定的消息处理,并就MTA应如何处理消息提供反馈。milter可能会验证SPF,并根据验证结果告诉Postfix接受或拒绝传入消息。milter可以分析消息正文并提供垃圾邮件评分,客户端可以使用该评分来评估消息。Postfix提供了两种调用milters的方法。
一些milters应适用于通过SMTP通过网络到达的邮件。这通常是来自端口25上的外部网络的邮件,但可能包括端口465上的提交。Postfix调用这些 SMTP-only filters 。应检查此类邮件是否符合SPF和DKIM等政策,然后通过防病毒和反垃圾邮件软件进行进一步评估。要将milter应用于每个正在侦听的SMTP服务器,请使用 main.cf 中的 smtpd_milters
选项。如果你想将milter仅应用于特定的服务,例如通过端口25从公众到达的邮件,请在 master.cf 的服务条目中添加 smtpd_ milters
。我们将在本书中看到示例。
并非所有邮件都通过SMTP到达。来自本地主机的邮件通过命令行或类似 cron(8)
的程序到达。来自用户客户端的邮件通过提交服务到达。是的,提交协议使用经过身份验证的SMTP会话,但它是一个与接受来自公众的随机邮件不同的过程(第5章)。提交的邮件通过纯粹的内部非SMTP进程传递到面向公众的端口25 SMTP服务器。正如你不想要求公众对你的端口25邮件进行身份验证一样,你也不想对通过提交到达的邮件应用SPF检查。Postfix调用这些 non-SMTP milters 。它们主要用于向传出邮件添加身份验证信息。使用 non_smtpd_milters
选项配置非SMTP中继器。在第7章中,我们将使用 smptd_milters
将Postfix连接到rspamd。
Milters是外部程序,独立于Postfix则会失败。也许它们崩溃了,或者你正在重新启动它们。默认情况下,当Postfix无法到达milter时,它会以暂时失败的方式回复SMTP请求。如果你发现你有一个错误的milter,它经常崩溃,你可以使用 milter_default_action
来接受消息,即使配置的milter没有应答或不可用:
xxxxxxxxxx
milter_default_action = accept
当你的一个邮件过滤器出现故障时,你也可以永久 reject
收到的邮件,但这会惹恼和混淆外部发件人。
有两种传统的方法可以将收到的消息重新发送给另一个收件人,即跳转 (bouncing) 和转发 (forwarding)。
Bounce 和 server 一样,是一个重载词(overloaded word),根据上下文有多种含义。无法投递的电子邮件从收件人的服务器上弹出。然而,对于用户来说,bouncing 消息就是按照收到的消息重新发送消息,信封中有一个新的发送者,但标题和正文保持不变。收件人看到邮件时,就像他们是原始收件人一样。SPF和DKIM的验证器通常会声明退回的邮件无效,如今许多MTA拒绝接受用户将邮件退回到其他帐户。
Forwarding 会创建一条全新的消息,其中原始消息可以封装为附件或内联,并包括转发者的电子邮件地址和其他信息。SPF和DKIM检查器不评估附件或邮件正文,因此目标服务器可以验证这些邮件。
邮件列表可能被认为是消息转发器,但现代邮件列表会更改邮件头,并为每条消息添加新的身份验证信息。这些邮件不会显示为附件,但也不像被退回的邮件那样与原始邮件完全相同。
现在你可以弄清楚你的邮件系统想告诉你什么了,让我们设置Postfix和Dovecot。