Procmail

来自 ArchWiki
注意: Procmail 在 二十年中只发布过一个版本,它的一位作者建议使用其他替代品。[1] 一个替代方案的例子是 courier-maildropAUR

Procmail 是一个用于过滤、排序和存储电子邮件的程序。它既可以用于邮件客户端,也可以用于邮件服务器。它可以用于过滤垃圾邮件、检查病毒、发送自动回复等。

本文的目标是教授 procmail 的配置。本文假设您已经拥有一个可以(或需要)使用 procmail 的电子邮件客户端(Muttnmh 等)或邮件服务器(SendmailPostfix 等)。它还假设您至少具备正则表达式的基础知识。本文将仅给出最少的解释,完整的说明请查看 procmailrc(5)

安装

安装 软件包 procmailAUR

配置

如果这是电子邮件客户端的配置,配置将保存在 ~/.procmailrc 中;如果将由邮件服务器使用,则保存在 /etc/procmailrc 中。

注意: 在测试您收到的示例消息上的 procmail 配置时要小心,因为如果您的配置文件中存在错误,消息可能会自动弹回给发件人。为了避免这种潜在的尴尬情况,请通过将 -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

参见