Procmail 是一种通用的电子邮件过滤器,通常用于在消息传递到用户的收件箱之前处理它们。
本章包括以下主题:
- 简单介绍 Procmail
- Procmail 可以执行的典型过滤任务
- 如何在服务器上安装和设置邮件过滤系统,以处理您不愿每天花时间处理的重复分类和存储任务
- Procmail 配方中规则和操作的基本结构
- 如何在我们的食谱中创建和测试规则
- 最后,介绍一些用于执行过滤的示例菜谱
在本章结束时,您将了解过滤过程的基础知识,如何设置系统来执行过滤,以及如何对您自己的邮件执行一些非常简单但非常有用的过滤操作。 所有这些都将帮助你保持对所有你已经或即将收到的邮件。
Procmail 是一个邮件过滤器,它在邮件到达邮件服务器之后,但在最终发送到预期收件人之前执行。 Procmail 的行为由许多用户编写的食谱(或脚本)控制。 每个菜谱可以包含许多模式匹配规则,以便至少根据收件人、主题和消息内容来选择消息。 如果规则中的匹配条件选择该消息作为候选消息,那么 recipe 可能会执行许多操作来将该消息移动到一个文件夹中,回复发送者,甚至在传递之前丢弃该消息。 与规则一样,操作是用户在配方中编写的,可以对消息执行几乎任何操作。
Procmail 主页位于http://www.procmail.org。
1.0 版是在 20 世纪 90 年代末发布的,它已经发展成为基于 unix 邮件系统的最好和最常用的邮件过滤解决方案之一。 Procmail 最初是由 Stephen R. van den Berg(<[[email protected]](mailto:[email protected])>
)设计和开发的。 在 1998 年秋天,意识到自己没有时间维护 Procmail, Stephen 创建了一个邮件列表,用于讨论未来的开发,并委托 Philip Guenther(<[[email protected]](mailto:[email protected])>
)作为维护人员。
自 2001 年 9 月发布的版本 3.22 以来,Procmail 一直很稳定,所以最近的安装都安装了这个最新的版本,这也是我们在本书中使用的版本。
到现在为止,您应该已经建立并运行了电子邮件系统,并发送和接收电子邮件。 您可能已经注册了许多有用的邮件列表,这些邮件间隔不同。 您还应该收到通知您系统状态的消息。 所有这些额外的、低优先级的信息很容易分散你的注意力,妨碍你读那些你需要提前阅读的重要邮件。
如何整理邮件取决于你自己的个人品味; 如果您非常有条理,您可能已经在电子邮件客户端中设置了一些文件夹,并在您阅读邮件后将它们移动到适当的位置。 尽管如此,您可能已经意识到,让系统将一些消息自动存储在与重要电子邮件不同的位置将非常有用。
在设置自动流程时,您需要考虑的是如何识别邮件项的内容。 最重要的指标是邮件发送给了谁,标题或主题行,还有发送者的详细信息。 如果您现在花几分钟时间记录一下您已经如何处理邮件、到达的消息类型以及您如何处理它们,那么您将更清楚地了解您可能想要设置的自动流程。
一般来说,您可能会收到几类不同的消息。
- **邮件列表成员:**来自邮件组或邮件列表的邮件通常很容易从发件人信息或可能从主题行识别。 一些组每隔几分钟发送消息,而其他组可能一个月只发送几条消息。 通常,不同的邮件组项目由不同的信息块标识。 例如,一些组发送消息时使用的“From”地址是真实发送者的地址,而另一些组添加一个假的或系统生成的“From”地址。 例如,有些组可能会自动在“Subject”字段中添加前缀。
- **自动化系统消息:**您的服务器每天会产生大量的消息。 虽然它们通常只发送给系统管理员或根用户,但首先要做的事情之一是确保您收到邮件的副本,以便随时了解系统状态和事件。 这可以通过编辑
/etc/mail/aliases
或/etc/aliases
文件中的默认目的地来实现,具体取决于系统的设置方式。 这些系统生成的消息几乎总是可以识别为来自少数特定的系统用户 id。 这些是典型的root
和cron.
- **未经请求的批量电子邮件:**被识别为垃圾邮件的消息通常被认为不重要。 因此,您可以选择将这些项目移动到一个单独的文件夹,以便以后查看,甚至可以完全丢弃它们。 不建议自动丢弃垃圾邮件,因为任何标识错误的邮件都将永远丢失。
- **个人信息:**来自客户、同事或朋友的邮件通常被认为是重要的。 因此,它通常会被发送到您的收件箱,让您有机会提供一个更及时的回应。 单个消息更难以用过滤器识别,特别是来自新客户或同事的消息,因此不属于刚才讨论的类别之一的消息应该正常传递。
完成本章的工作后,您应该具备了工具和知识,可以开始更详细地检查邮件,并设置一些基本的过滤操作。
您已经设置的基本邮件系统本身具有一些内置功能,可以根据用户设置处理传入邮件。 默认操作是将邮件转到收件箱; 其他选项是自动将所有邮件转发给另一个用户。 假设您在不同的系统上有多个邮件帐户,并希望所有邮件都集中在一个特定的邮件帐户中。 然后,您可以将该邮件发送到特定的文件,或将其传递给程序或应用,以允许它执行自己的工作。
这种设置的缺点是,您的所有邮件都必须遵循一个特定的路径,因此随着时间的推移,已经创建了许多选项来智能过滤邮件。 其中最强大和最受欢迎的是 Procmail。
Procmail 被设计用于处理系统内用户接收到的各种邮件的处理和过滤任务。 过滤只适用于在系统上拥有帐户的用户——不适用于虚拟用户——可以应用于系统范围内的所有用户,或者单个用户可以添加自己的过滤。
对于系统管理员来说,Procmail 提供了一系列的工具,可以将规则和操作应用到系统用户接收到的所有邮件上。 此类行为可能包括出于历史目的或电子邮件内容可能用于某种形式的法律或商业情况的业务中,对所有邮件进行复制。
在本书的其他部分,我们将讨论识别电子邮件传播的病毒和垃圾邮件的方法。 Procmail 可以获取这些进程提供的信息,并根据这些进程添加的信息执行操作,例如将包含病毒的所有邮件项存储在一个安全的邮件文件夹中,由系统管理员检查。
对于系统用户来说,对收到的邮件执行的最常见操作是将其分类到一些有组织的布局中,以便您可以根据感兴趣的主题区域轻松地找到要查找的项目。 一个典型的组织布局可以是一个类似以下的层次结构:
/mailgroups/Procmail
/mailgroups/postfix
/mailgroups/linux
/system/cron
/system/warnings
/system/status
/inbox
如果您计划将邮件保存很长一段时间以供历史参考,那么可能值得添加额外的一层或两层来将邮件划分为年和月。 这使得将来更容易归档或清除旧电子邮件,也意味着搜索和排序将更快。
有时,您可能会收到许多很容易识别的电子邮件,这些邮件需要发送到另一个电子邮件地址的另一个用户。 在这种情况下,您可以设置将电子邮件转发到一个或多个其他电子邮件地址的规则,而不是将文件存储在系统中。 当然,您需要小心确保转发不会最终返回给您,从而创建一个永不结束的循环。
除了不需要任何手动干预外,以这种方式转发邮件比在邮件客户机软件中手动转发邮件有很大的优势。 Procmail 转发的邮件是透明的,对于收件人来说,邮件似乎是直接从原始发送者那里到达的。 然而,如果它是使用邮件客户端转发的,那么它看起来就好像是由进行转发的人或帐户发送的。
当一个地址的所有邮件都需要转发到另一个地址时,更有效的实现方法是使用 Postfix 邮寄系统的别名机制。 Procmail 应该只用于需要对邮件进行智能过滤的情况,这些过滤取决于只能在接收消息时确定的因素。
有些邮件项适合传递给应用,其中应用对电子邮件进行一些处理。 也许它可以读取内容,然后将信息存储在 bug 跟踪数据库中,或者更新客户活动的公司历史日志。 这些更高级的主题将在下一章中简要介绍。
如果要对某些消息发送自动回复,可以设置一个过滤器或规则来发送此类消息。 当你长时间离开办公室的时间度假,假期,或者疾病,有可能建立一个应答服务通知发送者,这将是一段时间你可以回复他们的邮件,也许给他们选择联系方式或要求他们联系另一个人。
仔细组织这样一个特性是很重要的。 你不应该发送这样的回复给一个邮件组或不断地发送重复回复的人,他们已经知道你离开了,但需要给你的信息后,你的返回。 这要求保留消息发送到的地址的日志,以避免重复发送消息。 我们将在下一章研究如何建立这样一个服务。
在使用 Procmail 的所有工作期间,需要记住的一个重要概念是,总是可能同时到达多个邮件消息,所有邮件消息都在竞相被处理。 因此,很有可能同时将两个或多个消息存储在相同的位置——这是造成灾难的原因。 假设两个物品同时到达的简单示例。 第一个邮件打开存储位置并开始写入消息的内容,然后第二个进程执行同样的操作。 由此可能产生各种各样的结果,从一条消息完全丢失,到两个消息存储在一起且完全无法辨认。
为了确保不会发生这种情况,需要观察一个严格的锁定协议,以确保每次只有一个进程可以写入,所有其他应用都需要耐心等待。 Procmail 本身能够强制执行适合于所应用的进程类型的锁定协议,并且在默认情况下,锁定存储邮件的物理文件。
在某些情况下,邮件是由应用处理的,Procmail 可以通过使用规则中的标志来指示使用适当的锁定机制。 这将在第 7 章中详细介绍。
Procmail 可能适合一些非常特定的邮件过滤和处理需求。 在大多数情况下,它的灵活性和能力足以至少在基本水平上执行任务。 这些任务可能是过滤与垃圾邮件相关的电子邮件、过滤掉病毒或运行邮件列表操作。 对于其中的每一个问题,都有许多解决方案,它们超越了仅使用 Procmail 过滤器的能力。 我们将在第 8 章的后面部分研究 SpamAssassin 如何执行垃圾邮件过滤和病毒过滤解决方案。
我们已经提到过,Procmail 只适合在 Procmail 运行的系统上拥有帐户的用户。 然而,值得强调的是,Procmail 无法处理发送给虚拟用户的邮件,这些邮件最终会到达另一个系统。 如果有必要为这样的用户处理邮件,那么可以在系统上创建一个真实的用户帐户,然后使用 Procmail 来执行最终转发,作为过滤过程的一部分。 这并不是一种理想的使用方法,因为如果允许 Postfix 系统完成这项工作,那么它比使用 Procmail 要高效得多。
由于该软件现在已经相当成熟,Procmail 通常可以安装在大多数 Linux 发行版上,并且可以通过使用包管理器来安装。 这是推荐的安装 Procmail 的方法。 如果在您的 Linux 发行版中无法通过包管理器获得它,也可以从源代码安装它。
对于 Fedora 用户,如果 Procmail 还没有安装,安装 Procmail 的简单方法是使用 yum
命令,如下所示:
yum install procmail
对于基于 debian 的用户,您可以使用以下命令:
apt-get install procmail
这将确保 Procmail 的二进制文件正确安装在您的系统上,然后您可以决定如何将其集成到 Postfix 系统中。
Procmail 可以从许多来源获得,但官方发行版是保持的,可以从www.procmail.org获得。 在那里,您可以找到指向许多镜像服务的链接,从这些镜像服务中您可以下载源文件。 本书使用的版本可以从http://www.procmail.org/procmail-3.22.tar.gz下载。
可以通过 wget
命令下载,下载方式如下:
wget http://www.procmail.org/procmail-3.22.tar.gz
下载并解压缩归档文件后,将 cd
解压缩到目录中,例如 procmail-3.22
。 在开始构建和安装软件之前,很有必要阅读一下 INSTALL
和 README
文档。
对于大多数 Linux 系统,可以通过以下步骤减少最简单的安装方法:
-
运行
configure
实用程序,通过运行configure
命令来创建正确的构建环境:$ ./configure
-
配置脚本完成后,可以运行
make
命令构建软件可执行文件:$ make
-
The final step, as
root
, is to copy the executables into the correct position for operation on the system:# make install
最后一步,将软件安装到 /usr/local
目录。
在所有阶段,您都应该检查流程输出是否有任何重大错误或警告。
对于大多数遵循说明的人来说,在本书中,您将是您正在管理的机器的系统管理员,并且可能会应用安装来处理系统上所有用户的所有邮件。 如果你不是管理员,或者你希望系统中只有有限的人可以使用 Procmail 的特性,你可以为个人用户安装 Procmail。
如果您安装 Procmail 是为了自己使用,或者只为服务器上的少数人安装,最常见的方法是直接从服务器上主目录的 .forward
文件中调用 Procmail 程序(这个文件需要全世界都可以读)。
当使用 Postfix 作为 MTA 时, .forward
中的条目应该是这样的:
"|IFS=' ' && exec /usr/bin/procmail -f- || exit 75 *#username*"
引号是必需的,用户名应该代替您的用户名。 其他 MTA 的语法可能不同,因此请参阅 MTA 文档。
您还需要在主目录中安装一个 .procmailrc
文件——这个文件保存 Procmail 将用于过滤和发送电子邮件的规则。
如果您是系统管理员,您可以决定全局安装 Procmail。 这样做的好处是用户不再需要 .forward
文件。 只要在每个用户的 HOME
目录中有一个 .procmailrc
文件就足够了。 在这种情况下,操作是透明的——如果 HOME
目录中没有 .procmailrc
文件,那么邮件将照常传递。 【5】
可以创建一个全局 .procmailrc
文件,该文件在用户自己的文件之前生效。 在这种情况下,您需要小心确保配置中包含以下指令,以便使用最终用户的特权而不是根用户的特权来存储消息。
DROPPRIVS=yes
这也有助于防止系统安全性中的弱点。 该文件通常以 /etc/procmailrc
的形式存储在 /etc
目录中,其目的是在将所有用户添加到系统中时为他们提供一组默认的个人规则。 在骨架帐户中配置一个 .procmailrc
文件,供系统的 add user
功能使用,这是值得的。 有关如何设置它的信息,请参阅 Linux 文档。
将 Procmail 集成到 Postfix 系统很简单,但是,与任何其他配置更改一样,必须小心。 Postfix 运行用户 ID 为 nobody 的所有外部命令,比如 Procmail。 因此,它将无法向用户 root
发送邮件。 为了确保仍然收到重要的系统消息,您应该确保配置了一个别名,以便将所有打算发送给根用户的邮件转发给将读取邮箱的真实用户。
要为根用户创建别名,必须编辑适当的 alias
文件,通常可以在 /etc/aliases or /etc/mail/aliases
中找到。
如果您无法找到该文件,使用以下命令:
postconf alias_maps
别名文件中的条目应该如下所示,在冒号(:)和电子邮件地址的开头之间只有一个制表符,并且没有尾随空格:
root: [email protected]
创建文本条目之后,应该运行 newaliases
命令将文本文件转换为一个数据库文件,以便 Postfix 读取。
值得为可能接收邮件的任何其他系统帐户添加其他别名。 例如,你可能会得到一个类似以下的 aliases
文件:
# /etc/aliases
postmaster: root
nobody: root
hostmaster: root
usenet: root
news: root
webmaster: root
www: root
ftp: root
abuse: root
noc: root
security: root
root: [email protected]
clamav: root
对于 Procmail 在系统范围内传递邮件,有必要修改 Postfix main.cf
文件,以指定负责实际传递的应用。
编辑 /etc/postfix/main.cf
文件,添加如下一行:
mailbox_command = /path/to/procmail
当进行了更改后,您需要使用以下命令指示 Postfix 文件已经更改:
postfix reload
后缀通过使用一些环境变量导出关于邮件包的信息。 通过替换所有对 shell 有特殊意义的字符(包括下划线字符中的空白),修改变量以避免任何 shell 扩展问题。 下面是导出的变量列表及其含义:
|变量
|
意义
|
| --- | --- |
| DOMAIN
| 正文右边的 @
在收信人地址中 |
| EXTENSION
| 可选 address-extension 部分 |
| HOME
| 收件人的主目录 |
| LOCAL
| 收件人地址中 @
左边的文本,例如 $USER+$EXTENSION
|
| LOGNAME
| 接收方的用户名 |
| RECIPIENT
| 整个收信人地址 $LOCAL@$DOMAIN
|
| SENDER
| 完整的发送地址 |
| SHELL
| 收件人的登录 shell |
当一个邮件项到达并传递给 Procmail 程序时,操作序列遵循一组格式。 它首先加载各种配置文件,以获取为特定用户设置的规则。 然后,这些规则依次对消息进行测试,当形成合适的匹配时,应用该规则。 一些规则在完成时终止,而其他规则返回控制,以便可以根据潜在处理的剩余规则评估消息。
系统范围的配置通常在 /etc/procmailrc
中进行,而个人配置文件通常存储在用户的主目录中,称为 .procmailrc
。 各个规则可以存储在单独的文件中,也可以组合成多个文件,然后由主 .procmailrc
文件作为邮件过滤过程的一部分包含进来。 通常,这些文件将存储在主目录的 Procmail
子目录中。
配置文件中的条目按照基本布局以简单的文本格式生成。 注释是允许的,并由以下的文本组成 #
字符; 空行被简单地忽略。 规则本身不需要以任何特定的格式进行布局,但是为了便于维护和可读性,最好使用一致和简单的格式编写规则。
Procmail 配置文件的内容可以分为三个主要部分:
-
Variables: Information necessary for Procmail to do its work may be assigned to variables within the configuration file in a manner similar to how they are used in shell programming. Some of the variables are obtained from the shell environment that Procmail is running in, others are created by Procmail itself for use within the scripts, while other variables can be assigned within the script itself. An additional use for variables is to set flags as to how Procmail itself should operate.
在大多数脚本中可以设置一些有用的变量:
PATH=/usr/bin: /usr/local/bin:. MAILDIR=$HOME/Maildir # Make sure it exists DEFAULT=$MAILDIR/ # Trailing / indicates maildir format mailbox LOGFILE=$HOME/procmail.log LOG=" " VERBOSE=yes
- 变量
VERBOSE
用于影响所执行的日志记录级别,而LOG
变量中嵌入的NEWLINE
是有意为之,目的是使日志文件更易于阅读。 - 第 7 章还包括一个简短的脚本,它显示 Procmail 中分配的所有变量。
- 变量
-
**注释:**一个
#
字符和以下所有字符直到NEWLINE
将被忽略。 这不适用于不能注释的条件行。 空行被忽略,可以与注释一起使用,以记录配置并提高可读性。 你应该评论你的规则,因为你写的规则可能在 6 个月的时间里没有检查手册就无法解释。 -
Rules or recipes: Recipe is a common name for rules we create. A line starting with a colon (:) marks the beginning of a recipe. A recipe has the following format:
:0 [flags] [ : [locallockfile] ] <zero or more conditions (one per line)> <exactly one action line>
:0
是早期 Procmail 版本遗留下来的。:
后面的数字最初是用来表示规则中包含的操作数量,现在 Procmail 解析器会自动计算出这个数字。 然而,出于兼容性的目的,:0
是必需的。
假设我们从订阅的特定邮件组接收大量邮件。 这些邮件很有趣,但并不重要,我们更喜欢在闲暇时阅读它。 主题是“神秘的怪物”,所有从这个邮件列表发出的电子邮件都有一个“收件人”地址<[[email protected]](mailto:[email protected])>
。 我们决定为这些邮件创建一个特殊的文件夹,并将所有邮件复制到这个文件夹中。 这是一个简单的规则,你可以很容易地复制和修改,以便将来处理你自己的邮件。
下面是一个从用户的主目录中获取的非常简单的 .procmail
文件的示例副本,目的是解释 Procmail 配置的一些基本特性。 规则本身被设计为将发送到某个电子邮件地址<[[email protected]](mailto:[email protected])>
的所有邮件存储在一个名为 monsters
的特殊文件夹中。 大多数邮件会发送给包括你自己在内的许多人,“收件人”地址可以提供邮件内容的有用指示。 例如,邮件可能被发送到位于 [email protected]
的分发列表,您需要对该电子邮件进行优先级排序。
花一些时间阅读文件的内容,然后我们将依次分解每个部分并分析其功能。
#
# Here we assign variables
#
PATH=/usr/bin: /usr/local/bin:.
MAILDIR=$HOME/Maildir # Make sure it exists
DEFAULT=$MAILDIR/ # Trailing / indicates maildir format mailbox
LOGFILE=$HOME/procmail.log
LOG="
"
VERBOSE=yes
#
# This is the only rule within the file
#
:0: # Anything to [email protected]
* ^TO_ [email protected]
monsters/ # will go to monsters folder. Note the trailing /
要详细研究这个文件,我们可以从定义语句开始,在这些语句中,变量被分配了特定的值。 这些值将覆盖 Procmail 已经分配的任何值。 通过执行这个手动分配,我们可以确保路径针对脚本操作进行了优化,并且我们可以确定正在使用的值,而不是假设 Procmail 可能分配的值。
PATH=/usr/bin: /usr/local/bin:.
MAILDIR=$HOME/Maildir
DEFAULT=$MAILDIR/
LOGFILE=$HOME/procmail.log
LOG="
"
VERBOSE=yes
这些设置指令给 Procmail 定义了一些基本参数:
PATH
指令指定了 Procmail 在哪里可以找到它可能需要执行的任何程序。MAILDIR
指定将存储所有邮件项的目录。 这个目录应该存在。DEFAULT
定义了如果没有为单个规则定义特定位置,邮件将存储在何处。 按照 Postfix 章节中关于选择邮箱格式的建议,末尾的/(斜杠)向 Procmail 表明它应该以 Maildir 格式发送邮件。LOGFILE
是存储所有跟踪信息的文件,这样我们就可以看到发生了什么。
接下来我们有以 :0
开始的食谱说明。 第二个 :
指示 Procmail 创建一个锁文件,以确保每次只向该文件写入一条邮件消息,以避免消息存储的损坏。 单行规则可以分解如下:
*:
所有的规则行都以*
开头。 这就是 Procmail 知道它们是规则的方式。 每个配方可能有一个或多个规则。^TO_:
这是一个特殊的 Procmail 内置宏,它搜索大多数可以包含您的地址的报头,例如To:, Apparently-To:, Cc:, Resent-To:
,等等,如果它找到了地址<[[email protected].](mailto:[email protected].)>
就会匹配。
最后一行是操作行,默认情况下,它指定了 MAILDIR
变量指定的目录中的一个邮件文件夹。
Maildir 格式的邮箱的文件夹名称上必须有尾随斜杠,否则邮件将以 unix mbox 格式发送,这是快递 imap 不支持的。 如果使用 IMAP,文件夹名称也应该以。 (句点),因为句点字符被指定为层次分隔符。
Procmail 允许您将规则和食谱组织到多个文件中,然后依次处理每个文件。 这使得管理规则和在需求变化时开关规则变得更加容易。 对于第一个测试用例,我们将创建一个用于测试的特殊规则集,并将所有规则组织在主目录的子目录中。 通常,子目录称为 Procmail
,但您可以使用自己的名称。
我们将从一个简单的个人规则开始,并针对单个用户进行测试。 在本章的后面,当我们介绍了所有的基础知识,并且您熟悉了创建和设置规则的过程后,我们将展示如何开始将规则应用到所有系统用户。
几乎所有关于编程的书籍都是从一个非常简单的“hello world”示例开始的,以展示编程语言的基础知识。 在本例中,我们将创建一个简单的个人规则,该规则处理用户收到的所有电子邮件,并检查主题是否包含单词“hello world”。 如果邮件主题包含这些特定的单词,则邮件消息将存储在一个特殊的文件夹中。 如果它不包含这些神奇的单词,邮件将存储在用户的正常收件箱中。
当您在生产环境中工作时,一定要确保正在编写和测试的规则不会干扰您的日常邮件活动。 控制这种情况的一种方法是创建一个专门用于测试新规则的特殊文件,并且只在实际执行测试工作时将其包含在 Procmail 处理中。 当您对规则操作感到满意时,您可以将它移动到它自己的特定文件中,或者将它添加到其他类似或相关的规则中。 在本例中,我们将为测试规则创建一个名为 rc.testing
的新文件。 在 $HOME/Procmail
目录下,使用您喜欢的编辑器创建文件 rc.testing
并输入以下行:
# LOGFILE should be specified early in the file so
# everything after it is logged
LOGFILE=$PMDIR/pmlog
# To insert a blank line between each message's log entry,
# Use the following LOG entry
LOG="
"
# Set to yes when debugging; VERBOSE default is no
VERBOSE=yes
#
# Simple test recipes
#
:0:
* ^Subject:.*hello world
TEST-HelloWorld
到目前为止,您可能已经开始认识到规则的结构。 这一项的分解如下。
前几行设置了适用于我们的测试环境的变量。 因为它们是在测试脚本中分配的,所以它们只会在脚本被包含在处理中时应用。 当然,一旦我们排除了测试脚本,测试设置就不会被应用。
匹配所有以字符串 Subject:
开头且包含字符串 hello world
的行。 我们故意不使用像 test
这样的字符串,因为少数系统可以剥离出看起来是测试消息的消息。 记住,Procmail 的默认操作是独立于情况的,因此我们不需要测试所有的变体,比如 Hello World.
最后一行指示 Procmail 将输出存储在 TEST-HelloWorld
文件中。
在 $HOME/Procmail
目录下创建 testmail.txt
,使用您喜欢的编辑器创建文件 testmail.txt
,并输入以下行:
From: [email protected]
To: [email protected] (self test)
Subject: My Hello World Test
BODY OF TEST MESSAGE SEPARATED BY EMPTY LINE
与包含候选字符串的 rc.testing
规则相比,主题行是大小写混合的,以便演示大小写不敏感匹配。
在 Procmail
目录中运行以下命令将生成调试输出:
formail -s procmail -m PMDIR=. rc.testing < testmail.txt
在静态测试期间,我们将前面命令中的变量PMDIR
定义为当前目录。
运行该命令后,您可以查看日志文件中的错误消息。 如果一切正常,您将看到文件 TEST-HelloWorld
的创建,其中包含 testmail.txt
的内容,并在日志中显示以下输出。
procmail: [9060] Mon Jun 8 17:52:31 2009
procmail: Match on "^Subject:.*hello world"
procmail: Locking "TEST-HelloWorld.lock"
procmail: Assigning "LASTFOLDER=TEST-HelloWorld"
procmail: Opening "TEST-HelloWorld"
procmail: Acquiring kernel-lock
procmail: Unlocking "TEST-HelloWorld.lock"
From [email protected] Mon Jun 8 17:52:31 2009
Subject: My Hello World Test
Folder: TEST-HelloWorld 194
如果 Subject
行不包含相关匹配短语,您可能会在日志中看到以下输出:
procmail: [9073] Mon Jun 8 17:53:47 2009
procmail: No match on "^Subject:.*hello world"
From [email protected] Mon Jun 8 17:53:47 2009
Subject: My Goodbye World Test
Folder: **Bounced** 0
您需要编辑您的 .procmailrc
配置文件。 这里可能已经有一些条目了,所以在进行任何更改之前,有必要对文件进行备份。 确保以下行包含在文件中:
# Directory for storing procmail configuration and log files
PMDIR=$HOME/Procmail
# Load specific rule sets
INCLUDERC=$PMDIR/rc.testing
有些行被故意用 #
注释掉了。 如果我们以后需要做一些更详细的调试,这些可能是必需的。
使用以下命令,给自己发送两条消息:
echo "test message" | mail -s "hello world" $USER
标题行中应该包含字符串 hello world
,而不应该包含这个特定的字符串。
检查邮件时,您应该发现主题中包含关键字的邮件已存储在 TEST-HelloWorld
邮件文件夹中,而其他邮件则保留在正常邮件收件箱中。
如果这一切都正确地工作了—恭喜! 你正在整理你的邮件。
如果它没有像预期的那样工作,我们可以做一些简单的事情来找出问题所在。
与任何编程过程一样,如果一开始它不起作用,检查代码以确保在编辑阶段没有引入明显的错误。
如果没有突出显示任何内容,可以查看 Procmail 创建的日志文件。 在本例中,日志文件名为 ~/Procmail
目录下的 pmlog
。 要查看最后几行,请使用以下命令:
tail ~/Procmail/pmlog
在下面的例子中,由于缺少了 :0
,所以规则行被跳过:
* ^Subject:.*hello world
TEST-HelloWorld
这会产生以下错误:
procmail: [10311] Mon Jun 8 18:21:34 2009
procmail: Skipped "* ^Subject:.* hello world"
procmail: Skipped "TEST"
procmail: Skipped "-HelloWorld"
这里没有遵循规则 :0:
的存储指令
:0:
* ^Subject:.*hello world
这会产生以下错误:
procmail: [10356] Mon Jun 8 18:23:36 2009
procmail: Match on "^Subject:.* hello world"
procmail: Incomplete recipe
使用 ls
命令检查 ~/.procmailrc
、 ~/Procmail/*
文件和 ~/ home
目录的权限。 规则文件应该由所有者以外的用户可写,并且应该具有类似以下权限:
rw-r--r—
主目录应该具有如下权限,其中 ?
可以是 r
或:
drwx?-x?-x
当您创建更复杂的规则时,或者如果您仍然有问题,您需要启用 Procmail 的全日志功能。 为此,您需要从 ~/.procmailrc
文件中的行中删除注释 #
,以便按如下方式启用它们:
# Directory for storing procmail configuration and log files
PMDIR=$HOME/Procmail
# LOGFILE should be specified early in the file so
# everything after it is logged
LOGFILE=$PMDIR/pmlog
# To insert a blank line between each message's log entry,
# add a return between the quotes (this is helpful for debugging)
LOG="
"
# Set to yes when debugging; VERBOSE default is no
VERBOSE=yes
# Load specific rule sets
INCLUDERC=$PMDIR/rc.testing
现在重新发送这两个示例消息,并检查日志文件中的输出信息。 日志文件应该指出需要研究的一些问题领域。
以下在 .procmailrc
文件中插入的配方将确保最后收到的 32 条消息都存储在 backup
目录中,确保在配方包含错误或有意外副作用的情况下,有价值的邮件不会丢失。
# Create a backup cache of 32 most recent messages in case of mistakes.
# For this to work, you must first create the directory
# ${MAILDIR}/backup.
:0 c
backup
:0 ic
| cd backup && rm -f dummy `ls -t msg.* | sed -e 1,32d`
现在,我们将假设这是有效的,在下一章中,我们将详细分析配方,看看它到底是如何工作的和它做了什么。
为了充分利用 Procmail 的功能,有必要花些时间了解典型电子邮件消息的基本结构。 随着时间的推移,结构变得越来越复杂,但它仍然可以被分解成两个离散的块。
消息体与消息头之间用一个空行分隔(所有消息头必须在连续的行上,因为在空行之后的任何消息头将被认为是消息体的一部分)。
消息体本身可以是通常由简单 ASCII 字符组成的简单文本消息,也可以是使用称为MIME的编码部分的复杂组合。 这使得电子邮件能够传输所有形式的数据,从简单的文本、HTML 或其他格式化的页面,并包括信息,如附件或嵌入式对象,如图像。 MIME 编码的讨论超出了本书的范围,并且对于您可能在邮件过滤中遇到的大多数流程来说,MIME 编码不是必需的。
如果您决定尝试处理消息体中保存的数据,那么一定要记住,您看到的邮件程序的输出可能与原始邮件消息中传输的实际数据非常不同。
邮件头是电子邮件中包含的允许各种邮件组件发送和处理消息的标记。 邮件头的典型格式是简单的两部分结构,由一个以 :
结尾的关键字组成,然后是分配给该关键字的信息。 邮件头提供了大量信息,包括如何创建电子邮件、使用何种邮件程序创建消息、消息来自谁、应该发送给谁以及如何到达您的邮箱。
以下邮件标头与从 freelancers.net
众多邮件列表中的一个收到的电子邮件有关。 电子邮件最有用的标识特性是主题行,因为大多数其他邮件组对讨论的其他标题使用相同的值。
前面的示例包含大量的标头,这些标头是由邮件从发件人到收件人的过程中经过的许多进程插入的。 然而,有少量的键头对于处理电子邮件非常有用,并且在大量的菜谱中使用。
所有不以 X-
开头的标题都由相关的标准权威机构指定特定的功能。 关于它们的更多信息可以在RFC(征求意见)822文档http://www.ietf.org/rfc/rfc0822.txt中找到。 【5】
以 X-
开头的头是用户定义的,只适用于特定的应用。 然而,有些应用可能与其他应用使用相同的头标记,但原因不同,所提供的信息的格式也不同。
为了帮助您理解 Procmail 规则的工作方式,我们将介绍几个简单但非常有用的规则集的设计和设置。 当您发现过滤传入邮件的更特定需求时,这将帮助您开始设计自己的规则集。
所有这些示例都基于从 Freelancers 邮件列表(之前的示例标题取自该列表)接收到的邮件消息。 它们都得到了相同的结果,再次证明了编程问题没有一个正确的解决方案。
这个标题解释了谁是电子邮件的发起者。 可以使用各种格式,并由人类可读和计算机可读的信息项的各种组合形成。 当您查看了几封电子邮件后,您将开始看到不同的邮件系统和软件可以使用的各种模式。 这个标题的实际格式并不重要,因为您需要生成匹配特定电子邮件的规则。
From: Do Not Reply <[email protected]>
该字段由将消息发送给其接收者的最终传输系统添加。 该字段旨在包含关于地址和返回到消息的发起者的路由的确定信息。
Return-Path: <[email protected]>
大多数邮件列表使用 Return-Path
标题:
:0:
* ^Return-Path: <[email protected]>
freelancers//
这是一种方便地过滤邮件列表项的有用方法。 在这里, ^
字符执行一个特殊的功能,指示 Procmail 从新行开始开始匹配过程。 这意味着包含嵌入在行中间的短语的行不匹配。 Procmail 的默认操作是,如果在标头或邮件正文的任何地方找到字符串,则返回一个匹配项,这取决于将脚本设置为搜索的位置。
邮件通常发送给电子邮件“收件人:”或“抄送:”标题中列出的一个或多个人员。 像 From:头一样,这些地址可能有几种格式。 这些标头对所有邮件收件人都可见,并允许您查看列出的所有公共收件人。
还有第三种收件人头,它不像“To:”和“Cc:”那么常见,但在批量邮件中经常使用。 这是密件抄送:(盲抄送)。 不幸的是,顾名思义,这是一个盲头,因此信息不包含在实际的头信息中,因此无法进行处理。
Procmail 有许多特殊的内置宏,可以用来标识邮件项。 特殊规则 ^TO_
用于搜索所有可用的目的地标头。 规则必须准确地写成四个字符,不带空格,且 T
和 O
都要大写。 要匹配的短语必须紧跟在 _
之后,不能有空格。
:0:
rule setsCc header, filtering by* ^[email protected]
freelancers/
主题行通常包含在电子邮件的标题中,除非发件人决定完全不包含主题行。
主题:FN-PROJECTS 自由网页设计师
在本例中,发送到这个特定列表的所有邮件项目都以短语“FN-PROJECTS”开头,因此有时适合进行过滤。
当邮件列表向主题行添加前缀时,此前缀可能适合于过滤:
:0:
* ^Subject: FN-PROJECTS
freelancers//
现在,我们已经介绍了设置规则、分析电子邮件的所有基础知识,并大致了解了所有处理操作的交互方式,接下来我们将查看两个系统范围的过滤、测试和操作示例。
在第 9 章中,我们将看到如何将一个完整的病毒检查系统集成到后缀邮件体系结构中。 这将执行准确的病毒签名识别,并将适当的标志添加到邮件标题中,以指示邮件中是否存在病毒。 然而,如果不可能设置这样的系统,该规则将提供另一种更残酷的方法来阻止所有带有可执行附件的电子邮件。
如果将以下内容放在 /etc/procmailrc
中,它将影响系统中包含某些类型文档作为附件的所有邮件。
# Note: The whitespace in the [ ] in the code comprises a space and a tab character
:0
* < 256000
* ! ^Content-Type: text/plain
{
:0B
* ^(Content-(Type|Disposition):.*|[ ]*(file)?)name=("[^"]*|[^ ]*)\.(bat|cmd|com|exe|js|pif|scr)
/dev/null
}
规则以习惯的 :0
指令开始。
适用的条件如下:
首先,确保我们只过滤小于 256kb 的消息。 这主要是为了提高效率,大多数垃圾邮件都小于这个大小。 如果病毒体积更大,显然可以增加它,但系统的负载可能会更高。
下一行说我们也只看那些 MIME 类型的消息(也就是说,不是纯文本),因为附件,根据定义,不能包含在纯文本消息中。
我们在花括号之间有一个子过滤器。 :0B
表示我们正在处理消息的主体,而不是消息头。 我们必须这样做,因为附件在主体中,而不是在头文件中。 然后,我们寻找具有作为可执行文件 MIME 标题签名的行。 如果你愿意,你可以修改文件名扩展名; 这些只是通常用来传播病毒的。
本例中的操作是,如果匹配,则将此消息发送给 /dev/null
。 注意,这意味着发送者不会收到消息反弹或错误消息; 信息被丢弃,再也不会被看到。 当然,您可以将邮件存储在一个安全的位置,并指定某人监控帐户,以获取不包含病毒的有效邮件。 对于这个问题的更优雅的解决方案,请记住检查第 9 章。
随着高速、始终在线的互联网连接的不断增加,人们开始发送越来越大的电子邮件信息。 从前,签名文件中超过四行被认为是不礼貌的,现在人们高兴地包含图像和壁纸,发送 HTML 和文本版本的电子邮件,而没有意识到他们发送的消息的大小。
在 Inbox 中存储如此大的消息会大大增加搜索邮件消息的处理开销。 一个简单的解决方案是将超过一定大小的所有消息移动到一个超大文件夹中。 这可以通过使用以下规则非常简单地实现,该规则查找大小超过 100,000 字节的消息并将其存储在 largemail
文件夹中。
:0:
* >100000
largemail/
这个规则的缺点是,您的用户需要记住定期查看收件箱和 largemail
文件夹。 一个更优雅的解决方案将允许您复制邮件的前几行以及标题和主题行,并将其存储在 Inbox 中,并通知您需要检查完整的版本。 这样的解决方案可以在下一章末尾的例子中看到。
在本章中,我们已经发现了 Procmail 的一些基础知识。 到目前为止,您应该已经熟悉了 Procmail 用来加载菜谱的各种文件、过滤的核心原则以及可用的选项。 我们还分析了电子邮件,设置了个人和系统范围的过滤器,并研究了一些简单的测试、日志记录和调试选项,这些选项将帮助我们更有效地管理公司的邮件。
我们只是触及了可能的表面,但希望这个小小的尝试已经为您提供了关于如何处理和过滤您的日常过载的电子邮件的大量想法。 它可能已经给了你更多的想法,更高级的过滤器和下一章将提供更多的建议和解释如何着手设置这些。