我有一个(Linux)邮件服务器,它包括postfix
接收邮件,amavisd-new
用于内容过滤(使用clamav
和SpamAssassin
),以及dovecot
用于递送和 IMAP。
我想进行设置,以便每次将电子邮件发送到特定邮箱时都会触发脚本。脚本不一定需要知道有关邮件内容或标题的任何信息。我知道至少有几个选项:
使用
postfix
内置过滤。设置标题检查,将发往此邮箱的所有电子邮件重新路由到我的脚本,然后脚本可以将其传递回postfix
。这里的缺点是这一切都发生在过滤之前,所以即使电子邮件在投递前被阻止,我的脚本也会被触发。如果我没有正确amavis
执行电子邮件的传递,还可能会有性能损失和丢失电子邮件的风险。postfix
将我的脚本作为内容过滤器添加到
amavis
。与之前相比,这可能在性能上有所改进,而且似乎是一个更好的地方。不幸的是,它仍然受到在对消息做出通过/不通过决定之前执行的影响。此外,我无法找到amavis
详细说明应该如何完成此操作的文档,并且配置文件并没有真正得出结论。
似乎最后的dovecot
递送步骤是仅获取过滤邮件的最佳位置,但我不确定是否有办法实现这一点。
有什么建议吗?我忽略了什么吗?
编辑:忘了补充,我想避免轮询类型的解决方案(查看日志、IMAP 客户端脚本等)
答案1
我发现了另一个可能被证明是足够好的解决方案的选项:在消息从 传递到 时劫持postfix
它dovecot
。
对于postfix
,我更改了 中的以下几行master.cf
:
dovecot unix - n n - - pipe
flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/dovecot-lda -d $(user)@$(domain)
到:
dovecot unix - n n - - pipe
flags=DRhu user=vmail:mail argv=/scripts/emaildeliverycheck.py $(user)@$(domain)
/scripts/emaildeliverycheck.py
然后像下面这样创建(Python 3.4):
#!/usr/bin/python3
from sys import argv, stdin, exit
from subprocess import Popen, check_call, CalledProcessError
# Define recipients that should trigger the script here
notifyusers = ('[email protected]',
'[email protected]')
recipient = argv[1]
if recipient in notifyusers:
# Run the script. Use Popen so that we don't have to wait for the
# script to finish
Popen(['/scripts/myscript.py', recipient])
try:
# Now pass the email to dovecot-lda. Use check_call because we *do*
# want to wait for it to finish
check_call(['/usr/lib/dovecot/dovecot-lda', '-d', recipient], stdin=stdin)
except CalledProcessError as error:
# Propagate any error codes back to Postfix
exit(error.returncode)
Postfix 的pipe
进程将电子邮件最终传递给上述脚本,而不是直接传递给dovecot-lda
。脚本根据列表检查收件人(在命令行上传递,因此它根本不需要查看消息),如果匹配,则触发另一个脚本。然后它将消息通过管道传输到 ,dovecot-lda
后者应该无法分辨它不是直接从 Postfix 获取的,并将退出状态传播回进程pipe
。
初步测试效果不错。这只会给我发送经过过滤的电子邮件,这正是我想要的。
答案2
我将其用作procmail
本地投递代理。这允许使用适用于用户的规则进行广泛的过滤。应该可以配置 postfix 以使用 procmail 进行过滤,并根据需要投递电子邮件。
procmail
具有将过滤器应用于标题、内容或两者的广泛功能。您可以使用任何程序作为过滤器,因此您应该能够为发送给指定用户的每封电子邮件触发脚本。