我收到很多来自某个国家/地区的垃圾邮件。它们在源代码中都有相同的模式。我想编写一个 procmail 规则来自动将所有这些电子邮件移动到我的垃圾邮件文件夹。
垃圾邮件的来源可能如下所示(我添加了“[已编辑]”以保护我的隐私):
Return-Path: <>
X-Original-To: [REDACTED]
Delivered-To: [REDACTED]
Received: from [REDACTED] ([REDACTED] [REDACTED])
by [REDACTED] (Postfix) with ESMTPS id 2AC8E731E799DC
for <[REDACTED]>; Sat, 9 Jul 2022 20:16:41 +0000 (UTC)
Received: from [REDACTED].org ([REDACTED].ru [REDACTED])
by [REDACTED] (Postfix) with ESMTP id 6F1865ECD8
for <[REDACTED]>; Sat, 9 Jul 2022 20:16:40 +0000 (UTC)
[...]
我想做的是查看“已接收”标题并将来自 .ru TLD 的所有内容都扔进垃圾邮件中。
我的尝试是这样的:
:0 H
* ^Received:*\.ru
.Spam/
但是,我是编写 procmail 规则的新手。我怎样才能测试我的新规则以便我知道它是正确的?
procmail
接受来自标准输入的邮件消息,因此将对您通过管道发送给它的任何内容采取行动。理想情况下,您通过管道传输的内容应该与邮件传输代理将发送的内容相同。还要在正确包含新规则之前测试使用自定义规则文件.procmailrc
:Procmail 有一个
-m
选项可让您测试规则文件,而无需在任何地方发送消息;$DEFAULT
如果您的规则都不匹配,它会关闭发送到您的收件箱。该选项要求您传入要运行的规则文件的文件名,并允许您像VERBOSE=yes
在命令行上一样设置变量。也许还可以查看https://www.iki.fi/era/mail/procmail-debug.html (旧但仍然模糊相关)。
对于您的具体规则,它很容易出现误报。请记住,正则表达式引擎将接受任何部分匹配;所以你的规则将触发例如
因为它匹配 substring
.ru
。您可以通过在 之后要求一个单词边界来防止这种情况ru
:.*
还要注意“任何文本”的正则表达式是如何.
匹配任何一个字符的,并*
表示尽可能多地重复前一个表达式,但也接受零重复。(因此,您的尝试将允许零个或多个冒号,Received
但前提是紧随其后的是文字文本.ru
。)您可能可以进一步加强这一点,但是
Received:
标头的标准化程度出了名的差。许多服务器运行 Postfix 或 Sendmail,它们都创建Received:
标头,其中冒号后的第一部分指示from
HELONAME (RDNS [IP]),其中 IP 是实际 IP 地址,RDNS 是反向 DNS 查找的结果(可能为空),HELONAME 是为远程客户端命名,当它使用HELO
orEHLO
命令启动 SMTP 事务时(客户端可以在这里放任何他们想要的东西;有些放明显的伪造品,这是很好的垃圾邮件过滤器!)......而且,许多其他服务器也在运行使用不同格式的不同软件,或鼓励本地管理员配置自己的格式(呃,Exim)。这Received:
每条消息顶部附近的标题来自您最本地的服务器,因此比更远的服务器更可预测和可靠,后者很容易包含完全虚构的信息。无论如何,这最终有点不令人满意。如果您可以说服您的 ISP 在 SMTP 传输期间阻止这些不需要的消息(有效地终止传递尝试,就好像您的邮箱不可用一样),那么效率会高得多。一些提供商向他们的用户提供访问例如 SpamAssassin 的权限,它可以让您阻止俄语中的消息(尽管精度不是很出色;该机制不太擅长区分例如俄语和塞尔维亚语,因此您需要阻止或允许实际上是所有西里尔语言),有些会阻止 IP 级别的流量,因此已知的垃圾邮件发送者甚至无法连接。但作为对抗破坏者的最后一道防线,Procmail 显然总比没有好。