Procmail
Procmail 是一个用于过滤、排序和存储电子邮件的程序。它既可以用于邮件客户端,也可以用于邮件服务器。它可以用于过滤垃圾邮件、检查病毒、发送自动回复等。
本文的目标是教授 procmail 的配置。本文假设您已经拥有一个可以(或需要)使用 procmail 的电子邮件客户端(Mutt,nmh 等)或邮件服务器(Sendmail,Postfix 等)。它还假设您至少具备正则表达式的基础知识。本文将仅给出最少的解释,完整的说明请查看 procmailrc(5)。
安装
配置
如果这是电子邮件客户端的配置,配置将保存在 ~/.procmailrc
中;如果将由邮件服务器使用,则保存在 /etc/procmailrc
中。
-t
传递给 procmail
或设置 DELIVERED
环境变量来关闭退回功能 (procmailrc(5))。配置由两个部分组成:赋值 和 规则。
赋值
赋值部分为 procmail 提供变量
PATH=/bin:/usr/bin MAILDIR=$HOME/Mail DEFAULT=$HOME/Mail/inbox LOGFILE=/dev/null SHELL=/bin/sh
规则
规则是主要部分,它们是执行动作的实际过滤器。规则具有以下格式
:0 [flags] [ : [locallockfile] ] <zero or more conditions (one per line)> <exactly one action line>
条件是扩展的正则表达式,带有一些额外的选项。条件始终以星号开头。
动作可以是邮箱名称,也可以是外部程序。
标志和锁文件
对于基本规则,您不需要任何标志。但是,如果您的脚本调用外部命令,则它们可能是必要的。以下是一些最常用的标志列表
- f 将管道视为过滤器。
- w 等待过滤器或程序完成并检查其退出代码(通常忽略);如果过滤器不成功,则文本将不会被过滤。
在 :0
之后使用 :
是为了使用锁文件。如果 2 个或更多 procmail 实例同时工作(如果 2 个或更多电子邮件几乎同时到达可能会发生这种情况),则锁文件是必要的,以防止出现问题。
您可以在 :
之后设置锁文件的名称
条件
条件以星号开头,后跟扩展的正则表达式,例如这个
* ^From.* someperson@\w+.com
动作
动作可以像这样简单
work
在这种情况下,符合条件的邮件将保存在 work
收件箱中。
动作也可以以管道开头,这意味着消息将传递到管道后面的命令的标准输入。例如
| /usr/bin/vendor_perl/spamc
默认情况下,一旦规则的动作完成,处理就结束了。
如果使用了 f 标志,则命令可以更改消息并继续读取规则。在此示例中,SpamAssassin 命令会将标头添加到邮件中,其中包含其垃圾邮件状态级别,稍后可以由另一个规则使用它来阻止它或将其存储在不同的邮箱中。
技巧和诀窍
SpamAssassin
这是一个使用 SpamAssassin 阻止垃圾邮件的示例。您应该已经安装并运行了 SpamAssassin。
# By using the f and w flags and no condition, SpamAssassin is going add the X-Spam headers to every single mail, and then process other recipes. # No lockfile is used. :0fw | /usr/bin/vendor_perl/spamc # Messages with a 5 stars or higher spam level are going to be deleted right away # And since we never touch any inbox, no lockfile is needed. :0 * ^X-Spam-Level: \*\*\*\*\* /dev/null # If a mail with spam-status:yes was not deleted by previous line, it could be a false positive. So its going to be sent to an spam mailbox instead. # Since we do not want the possibility of one procmail instance messing with another procmail instance, we use a lockfile :0: * ^X-Spam-Status: Yes $HOME/mail/Spam
ClamAV
一个使用 ClamAV 杀毒软件的示例。
# We make sure its going to use the sh shell. Mostly needed for mail-only account that have /usr/bin/nologin as shell SHELL=/bin/sh # We will scan the mail with clam using the standard input, and saving the result on the AV_REPORT variable AV_REPORT=`clamdscan --stdout --no-summary - |sed 's/^stream: //'` # We check if the word FOUND was in the result and save "Yes" or "No" according to that VIRUS=`echo $AV_REPORT|sed '/FOUND/ { s/.*/Yes/; q }; /FOUND/ !s/.*/No/'` # formail is a filter that can alter a mail message, while keeping the correct format. We use it here to add/alter a header called # X-Virus with either value Yes or No :0fw | formail -i "X-Virus: $VIRUS" # And if we just added "X-Virus: Yes", we will also add another header with the scan result, and alter the subject, again, with the scan result. # Since we are using the f flag, the mail is going to be delivered anyway. :0fw * ^X-Virus: Yes | formail -i "X-Virus-Report: $AV_REPORT" -i "Subject: [Virus] $AV_REPORT"
将邮件过滤到不同的邮箱
如果同事不断使用转发向您发送笑话和其他非严肃内容,但同时又给您写与工作相关的邮件,您可以将转发的邮件(很可能不是与工作相关的邮件)保存在不同的邮箱中。
:0: * ^From.*coworker@domain.com * ^Subject.*FW: $HOME/mail/jokes
Postfix 管道
要从 postfix 管道传输,请打开 /etc/postfix/main.cf
然后添加
mailbox_command = /usr/bin/procmail -a "$EXTENSION"
在 重新加载 postfix.service
后,电子邮件将被发送到 procmail 进行过滤和传递。
Exim
要与 Exim 一起使用,请在 .forward
文件中调用 procmail
,或编辑 /etc/mail/exim.conf
以直接将其用作本地传递代理
# under "Routers" (order important, define before the "localuser:" router) procmail: driver = accept check_local_user # only invoke procmail for users with a conf file: require_files = $local_part_data:$home/.procmailrc transport = procmail_pipe # under "Transports" (in any order) procmail_pipe: driver = pipe command = /usr/bin/procmail -d $local_part_data return_path_add delivery_date_add envelope_to_add # Next 2 lines unneeded unless using obsolete MBOX files # check_string = "From " # escape_string = ">From " umask = 077 user = $local_part_data group = mail
这已在 Arch 的标准 Exim 4.94-2 软件包上进行了测试。
发送到 Dovecot
要转发到 dovecot,请更改以下赋值
deliver 将是第一次尝试,然后 Default 将是备份。
DELIVER="/usr/lib/dovecot/deliver -d $LOGNAME" DEFAULT="$HOME/Maildir/" MAILDIR="$HOME/Maildir/"
优点是 dovecot 将始终使其数据库保持最新。
然后例如处理垃圾邮件并传递
# deliver spam to spam folder :0 w * ^X-Spam-Status: Yes | $DELIVER -m Spam # deliver to INBOX and stop :0 w | $DELIVER
更多信息可以在这里找到 https://wiki2.dovecot.org/procmail