在 2015 年 和 2016 年,我将“最佳情侣”奖授予了两个开源命令或程序类型,它们结合起来使我的世界变得更美好。今年,“最佳情侣”奖已转变为“最佳三人组”,因为要解决我着手解决的问题——有效的服务器端电子邮件分类——需要三个软件协同工作。以下是我如何使用 SpamAssassin、MIMEDefang 和 Procmail 这三个常见且免费提供的开源软件包使一切正常工作的方法。
问题
为了更轻松地管理我的电子邮件,我喜欢将收到的邮件分类到几个文件夹中(除了收件箱)。垃圾邮件总是被归档到垃圾邮件文件夹中,我每隔几天会查看一下,以防万一我想要的东西被标记为垃圾邮件。我还将来自其他几个来源的电子邮件分类到特定的文件夹中。其他所有内容默认都归档到收件箱中。
首先简单介绍一下术语:分类是将电子邮件分类并存储到适当文件夹的过程。像 SpamAssassin 这样的过滤器对电子邮件进行分类。MIMEDefang 使用该分类通过在主题行中添加文本字符串将邮件标记为垃圾邮件。这种分类允许其他软件将电子邮件归档到指定的文件夹中。我一直在使用这两个应用程序,我需要软件来完成最后一步——即执行归档的软件。
我在 Thunderbird 中设置了几个电子邮件过滤器,这是我发现的满足我个人需求的最佳客户端。我和我的妻子都在我们的电脑上使用电子邮件过滤器。当我们旅行或使用手持设备时,这些过滤器并不总是有效,因为 Thunderbird——或任何其他带有过滤器的电子邮件客户端——必须在我家中的电脑上运行才能执行过滤任务。我可以在我的笔记本电脑上设置过滤器,以便在旅行时对电子邮件进行分类,但这意味着我必须维护多组过滤器。
我还有一个想要解决的技术问题。客户端电子邮件过滤依赖于在邮件存入收件箱后扫描邮件。由于某些未知原因,有时客户端不会从收件箱中删除(清除)已移动的邮件。这可能是 Thunderbird 的问题(或者可能是我的 Thunderbird 配置问题)。多年来,我一直致力于解决这个问题,但没有成功,即使多次完全重新安装 Fedora 和 Thunderbird 也是如此。
此外,垃圾邮件对我来说是一个主要问题。我有自己的电子邮件服务器,并且使用多个电子邮件地址。我已经使用其中一些电子邮件帐户几十年了,它们已成为主要的垃圾邮件磁铁。事实上,我每天通常会收到 1,200 到 1,500 封垃圾邮件——我的记录是一天超过 2,500 封垃圾邮件——而且数量还在不断增加。
为了解决我的问题,我需要一种基于服务器而不是客户端的电子邮件归档(即,将它们分类到适当的文件夹中)方法。这将解决几个问题:我不需要让电子邮件客户端在我的家用工作站上运行才能执行过滤。我不需要从我们的收件箱中删除或清除邮件——尤其是垃圾邮件。而且我不需要在多个位置配置过滤器——我只需要在一个位置,即服务器上配置它们。
我的电子邮件服务器
大约在 1997 年,当我从 OS/2 切换到 Red Hat Linux 5 时,我选择了 Sendmail 作为我的电子邮件服务器,因为我已经工作中使用它好几年了。从那时起,它一直是我的 邮件传输代理 (MTA),用于商业和个人用途。(我不知道为什么维基百科将 MTA 称为“message”传输代理,而我所有其他参考文献都说是“mail”传输代理。维基百科页面的“Talk”选项卡对此进行了一些讨论,这让我更加困惑。)
我一直在一起使用 SpamAssassin 和 MIMEDefang 来评分和标记收到的电子邮件为垃圾邮件,在主题中放置一个已知的字符串 ###SPAM###,这样我就可以识别和分类垃圾邮件,无论是作为人类还是使用软件。我使用 UW IMAP 用于客户端访问电子邮件,但这与服务器端过滤和分类无关。
是的,我在电子邮件的服务器端使用了许多老式的软件,但它们是众所周知的,运行良好,而且我了解如何让它们完成我需要它们做的事情。
项目需求
我相信在开始项目之前,制定一套明确的需求是必不可少的。根据我对问题的描述,我为此项目创建了五个简单的需求
- 使用已添加到主题行中的标识文本,在服务器端将收到的垃圾邮件分类到垃圾邮件文件夹中。
- 将其他收到的电子邮件分类到指定的文件夹中。
- 规避已移动邮件未从收件箱中删除或清除的问题。
- 保留现有的 SpamAssassin 和 MIMEDefang 软件。
- 确保任何新软件都易于安装和配置。
这组目标意味着我需要一个分类程序,它可以与我已经拥有的部分很好地集成。
Procmail
经过广泛的研究,我最终选择了久经考验的 Procmail。我知道——更多老旧的东西——而且现在几乎不受支持了。但它可以完成我需要它做的事情,并且已知可以与我正在使用的软件很好地协同工作。它稳定且没有已知的严重错误。它可以配置为在系统级别以及个人用户级别使用。
Red Hat 和基于 Red Hat 的发行版,例如 CentOS 和 Fedora,使用 Procmail 作为 SendMail 的默认 邮件投递代理 (MDA),因此甚至不需要安装;它已经在那里了。我的服务器运行 CentOS,因此使用 Procmail 真的是不费吹灰之力。
除了传递电子邮件外,Procmail 还可用于过滤和分类电子邮件。Procmail 规则(称为配方)可用于识别垃圾邮件并将其删除或分类到指定的邮件文件夹中。其他配方也可以识别和分类其他邮件。Procmail 可以用于许多其他事情,除了将电子邮件分类到指定的文件夹中,例如自动转发、复制等等。这些其他任务超出了本文的范围,但理解分类应该让您更好地理解如何完成这些其他任务。
它是如何工作的
将 SpamAssassin、MIMEDefang 和 Procmail 结合在一起用于反垃圾邮件解决方案的方法有很多种,因此我不会深入介绍如何配置它们。相反,我将重点介绍如何集成这三个软件包来实施我自己的解决方案。
收到的电子邮件处理从 SendMail 开始。我在我的 sendmail.mc 配置文件中添加了这一行
INPUT_MAIL_FILTER(`mimedefang', `S=unix:/var/spool/MIMEDefang/mimedefang.sock, T=S:5m;R:5m')dnl
这一行调用 MIMEDefang 作为电子邮件处理的一部分。请务必在对 SendMail 进行任何配置更改后运行 make 命令,然后重新启动 SendMail。(有关更多信息,请参阅 SpamAssassin: A Practical Guide to Integration and Configuration 的第 8 章。)
SpamAssassin 可以在某些应用程序中作为独立软件运行;但是,在这种环境中,它不是作为守护进程运行的,而是由 MIMEDefang 调用的,并且每封电子邮件首先由 SpamAssassin 处理以生成垃圾邮件评分。
SpamAssassin 提供了一组默认规则,但您可以通过修改 /etc/mail/spamassassin/local.cf 文件来修改现有规则的分数、添加自己的规则以及创建白名单和黑名单。这个文件可能会变得非常大;我的文件刚刚超过 70KB 并且还在增长。
SpamAssassin 使用默认和自定义规则集和分数来生成每封电子邮件的总分。MIMEDefang 将 SpamAssassin 用作子例程,并将垃圾邮件分数作为返回代码接收。
MIMEDefang 是用 Perl 编程的,因此很容易破解。我已经破解了 /etc/mail/mimedefang-filter 中代码的最后主要部分,以提供比默认值更精细的过滤细分。以下是我的安装中代码的这一部分的外观(我对代码的这一部分进行了重大更改,因此您的可能与此大不相同)
#####################################################################
# Determine how to handle the email based on its spam score and #
# add an appropriate X-Spam-Status header and alter the subject. #
#####################################################################
# Set required_hits in sa-mimedefang.cf to get value for $req #
#####################################################################
if ($hits >= $req) {
action_add_header("X-Spam-Status", "Spam, score=$hits required=$req tests=$names");
action_change_header("Subject", "####SPAM#### ($hits) $Subject");
action_add_part($entity, "text/plain", "-suggest", "$report\n", "SpamAssassinReport.txt", "inline");
# action_discard();
} elsif ($hits >= 8) {
action_add_header("X-Spam-Status", "Probably, score=$hits required=$req tests=$names");
action_change_header("Subject", "####Probably SPAM#### ($hits) $Subject");
action_add_part($entity, "text/plain", "-suggest", "$report\n", "SpamAssassinReport.txt", "inline");
} elsif ($hits >= 5) {
action_add_header("X-Spam-Status", "Possibly, score=$hits required=$req tests=$names");
action_change_header("Subject", "####Possibly SPAM#### ($hits) $Subject");
action_add_part($entity, "text/plain", "-suggest", "$report\n", "SpamAssassinReport.txt", "inline");
} elsif ($hits >= 0.00) {
action_add_header("X-Spam-Status", "Probably not, score=$hits required=$req tests=$names");
# action_add_part($entity, "text/plain", "-suggest", "$report\n", "SpamAssassinReport.txt", "inline");
} else {
# If score (hits) is less than or equal to 0
action_add_header("X-Spam-Status", "No, score=$hits required=$req tests=$names");
# action_add_part($entity, "text/plain", "-suggest", "$report\n", "SpamAssassinReport.txt", "inline");
}
以下是该代码中更改电子邮件主题行的行
action_change_header("Subject", "####SPAM#### ($hits) $Subject");
实际上,它调用另一个 Perl 子例程来使用我要添加的字符串作为参数来更改主题行,但效果是相同的。主题行现在包含字符串 ####SPAM#### 和垃圾邮件分数(即变量 $hits)。主题行中包含这个已知的字符串使后续过滤变得容易。
修改后的电子邮件返回给 SendMail 以进行进一步处理,SendMail 调用 Procmail 作为 MDA。
Procmail 使用全局和用户级配置文件,但必须创建全局 /etc/procmailrc 文件和个人用户 ~/.procmailrc 文件。文件的结构相同,但全局文件对所有收到的电子邮件进行操作,而本地文件可以为每个用户单独配置。由于我不使用全局文件,因此所有分类都在用户级别完成。我的 .procmailrc 文件很简单
# .procmailrc file for david@both.org
# Rules are run sequentially - first match wins
PATH=/usr/sbin:/usr/bin
MAILDIR=$HOME/mail #location of your mailboxes
DEFAULT=/var/spool/mail/david
# Send Spam to the spam mailbox
# This is my new style SPAM subject
:0
* ^Subject:.*####SPAM####
$HOME/spam
# Political stuff goes here. Must be using my political email address
:0
* ^To:.*political
$HOME/Political
# SysAdmin stuff goes here. Usually system log messages
:0
* ^Subject:.*(Logwatch|rkhunter|Anacron|Cron|Fail2Ban)
$HOME/AdminStuff
# drops messages into the default box
:0
* .*
请注意,.procmailrc 文件必须位于我的电子邮件帐户在电子邮件服务器上的主目录中,而不是我的工作站上的主目录中。由于大多数电子邮件帐户不是登录帐户,它们使用 nologin 程序作为默认 shell,因此管理员必须创建和维护这些文件。另一种选择是更改为登录 shell,例如 Bash,并设置密码,以便知识渊博的用户可以登录到他们在服务器上的电子邮件帐户并维护他们的 .procmailrc 文件。
每个 Procmail 配方都以第一行上的 :0(是的,那是零)开头,总共包含三行。第二行以 * 开头,包含一个条件语句,该语句由 Procmail 与收到的电子邮件中的每一行进行比较的正则表达式 (regex) 组成。如果存在匹配项,Procmail 会将电子邮件分类到第三行指定的文件夹中。在进行比较时,^ 符号表示行的开头。
我的 .procmailrc 文件中的第一个配方将 MIMEDefang 在主题行中识别出的垃圾邮件分类到我的垃圾邮件文件夹中。第二个配方将政治邮件(通过我为各种政治组织志愿工作而使用的特殊电子邮件地址识别)分类到其自己的文件夹中。第三个配方将我从我处理的许多计算机收到的海量系统电子邮件分类到我的系统管理员职责的邮箱中。这种设置使这些电子邮件很容易找到。
请注意使用括号括起要匹配的字符串列表。每个字符串都用竖线(也称为管道符)(|)分隔,管道符用作逻辑“或”。因此,条件行
* ^Subject:.*(Logwatch|rkhunter|Anacron|Cron|Fail2Ban)
读取为“如果主题行包含 Logwatch 或 rkhunter 或 ... 或 Fail2Ban。”由于 Procmail 忽略大小写,因此无需创建查找各种大小写组合的配方。
最后一个配方将所有与另一个配方不匹配的电子邮件放入默认文件夹,通常是收件箱。
将 .procmailrc 文件放在我的主目录中不会导致 Procmail 过滤我的邮件。我必须添加另一个文件,即以下 ~/.forward 文件,该文件告诉 Procmail 过滤我的所有收到的电子邮件
# .forward file
# process all incoming mail through procmail - see .procmailrc for
# the filter rules.
|/usr/bin/procmail
创建或修改 Procmail 配置文件时,无需重新启动 SendMail 或 MIMEDefang。
有关 Procmail 配置和配方创建的更多详细信息,请参阅 SpamAssassin 书籍 和 RHEL 部署指南中的 Procmail 信息。
一些其他注意事项
请注意,MIMEDefang 必须在 SendMail 之前启动,这样它才能创建套接字,SendMail 在套接字中发送电子邮件以进行处理。我有一个简短的脚本(自动化一切!)我用它来以正确的顺序停止和重新启动 SendMail 和 MIMEDefang,以便 local.cf 文件中的新规则或修改后的规则生效。
我已经在我 SpamAssassin 的 local.cf 文件中拥有大量规则和分数修改器,因此,尽管我可以使用 Procmail 本身进行垃圾邮件过滤和分类,但转换所有这些规则需要做很多工作。我也认为 SpamAssassin 在评分方面做得更好,因为它不依赖于单个规则来匹配,而是依赖于所有规则的聚合分数以及来自贝叶斯过滤的分数。
当可以使用已知字符串(例如我已配置 MIMEDefang 放置在主题行中的字符串)非常明确地进行匹配时,Procmail 运行良好。我认为 Procmail 作为垃圾邮件过滤过程中的最终分类阶段比作为完整的解决方案本身效果更好。也就是说,我知道许多管理员仅使用 Procmail 就完成了完整的垃圾邮件过滤解决方案。
现在我有了服务器端过滤,我对电子邮件客户端的选择在某种程度上不太受限制,因为我不再需要执行过滤和分类的客户端。我也不需要一直运行电子邮件客户端来执行过滤和分类。
关于 Procmail 消亡的报道被大大夸大了
在为本文进行研究时,我发现许多 Google 结果(日期从 2001 年到 2013 年)声明 Procmail 已经死了。证据包括损坏的网页、丢失的源代码以及 维基百科 上的一句话,声明 Procmail 已经死了,并链接到更新的替代品。但是,所有 Red Hat、Fedora 和 CentOS 发行版都将 Procmail 安装为 SendMail 的 MDA。Red Hat、Fedora 和 CentOS 存储库都具有 Procmail 的源 RPM,并且源代码也在 GitHub 上。
考虑到 Red Hat 继续使用 Procmail,我使用这款成熟的软件没有任何问题,它可以默默无闻地完成其工作。
资源
- SpamAssassin: A Practical Guide to Configuration, Customization, and Integration 也包含有关 MIMEDefang 和 Procmail 的信息
- 维基百科上的 SpamAssassin
- 维基百科上的 MIMEDefang
- Red Hat 的 Procmail 文档
- Procmail 常见问题解答
3 条评论