如何使用 Postfix 设置垃圾邮件陷阱,以便阻止发送到陷阱地址的客户端向我发送更多垃圾邮件?
答案1
概述
贝叶斯过滤器、模式匹配和 RBL 都是打击垃圾邮件的一部分。此设置旨在增强而不是取代它们。
请注意,我不是灰名单用户。灰名单在理论上很棒,但在实践中却让用户非常恼火。有些人用它取得了巨大的成功。我不是其中之一。
我所做的就是设置一些电子邮件地址(我有大约 10,000 个,但几百个就够了)作为垃圾邮件陷阱。这些地址的列表与各种高流量网站分开链接,机器人可以找到它们,但人找不到。这些地址被收集起来,卖给垃圾邮件发送者,现在我知道垃圾邮件会从哪里来。
Postfix 配置为将发送到这些地址中的任何消息重定向到我的 spamtrap 脚本,该脚本将它们添加到 PF 中的表中,以便来自该客户端的任何进一步消息最终都会进入我的 tarpit。
优点:
- 零假阳性率(或至少尽可能接近)
- 资源廉价
- 在垃圾邮件发送者首次违规后,在防火墙层进行拦截
- 自我修复(陷阱地址 24 小时后过期)
缺点:
- 非即插即用
- 相当多的活动部件
如何?
您的邮件服务器必须能够运行 PF 和 spamd。据我所知,这意味着 OpenBSD 或 FreeBSD。我确信这些说明可以适用于各种 Linux 及其防火墙,但这超出了我的回答范围。
我为 FreeBSD 编写了此代码。OpenBSD 用户应该能够通过更改路径来适应这些步骤。
最后,以上就是 Postfix 2.5+ 的全部内容
表 <spamd> 持久化 表 <local-whitelist> 持久文件“/usr/local/etc/spamd/local-whitelist.txt”
- 从端口安装 spamd
- 创建 /usr/local/etc/spamd/local-whitelist.txt。PF 将读取此文件以生成 <local-whitelist> 表。我建议参考http://www.greylisting.org/whitelisting.shtml针对不应被延迟的地址。示例文件:
127.0.0.1 10.0.0.0/8 # 亚马逊 207.171.168.0/24 207.171.180.0/24 207.171.187.0/24 207.171.188.0/24 207.171.190.0/24 # 美国在线 64.12.137.0/24 64.12.138.0/24 152.163.225.0/24 205.188.139.0/24 205.188.144.0/24 205.188.156.66 205.188.157.0/24 205.188.159.7 # 苹果 17.254.6.0/24 # 易趣 66.135.197.0/24 66.135.209.0/24 # Gmail 64.68.80.0/21 64.233.160.0/19 64.233.162.192/28 64.233.170.192/28 64.233.182.192/28 64.233.184.192/28 66.249.82.192/28 66.249.92.192/28 66.249.64.0/19 66.102.0.0/20 70.89.39.152/29 70.90.219.48/29 70.90.219.72/29 72.14.192.0/18 74.125.0.0/16 209.85.128.0/17 216.239.32.0/19 216.239.56.240/28 # postini 63.146.199.13/32 63.146.199.14/32 63.71.11.123/32 63.71.11.124/32 64.18.0.0/20 67.114.133.222/32 68.123.185.46/32 74.125.148.0/22 204.14.232.0/22 207.126.144.0/20 208.111.151.5/32 208.74.204.5/32 #skynet.be 195.238.2.0/24 195.238.3.0/24 # 雅虎 64.94.237.0/24 66.163.160.0/19 66.196.64.0/18 66.218.64.0/19 66.218.66.0/24 66.218.67.0/24 66.218.69.0/24 69.147.92.0/24 73.30.0.0/16 74.6.0.0/16 206.190.32.0/19 216.34.77.0/25 216.136.226.0/24
重新加载 PF
创建 /usr/local/scripts/get-spamtrapped:
#!/bin/sh
/usr/local/sbin/spamdb | grep TRAPPED | cut -d '|' -f 2
- 创建 /usr/local/etc/spamd/spamd.conf。我建议同时使用 nixspam 和 ualbert.ca 列表,但至少需要 spamtrapped 和 override 列表。(注意:我知道 override 与 PF 的 rdr 规则是多余的 - 我移动了足够多的东西,所以我想要这种双重保护):
全部:uatraps:覆盖:nixspam:覆盖:spamtrapped:覆盖: # 阿尔伯塔大学灰陷阱袭击。 # 地址自出现故障之日起会保留在其中 24 小时。 uatraps:\ :黑色的:\ :msg="您的地址 %A 已将邮件发送至 ualberta.ca 垃圾邮件陷阱\n\ 过去 24 小时内”:\ :方法=http:\ :文件=www.openbsd.org/spamd/traplist.gz: # Nixspam 最近的来源列表。 # 镜像自 http://www.heise.de/ix/nixspam nixspam:\ :黑色的:\ :msg="您的地址 %A 在 nixspam 列表中\n\ 请参阅http://www.heise.de/ix/nixspam/dnsbl_en/了解详细信息”:\ :方法=http:\ :文件=www.openbsd.org/spamd/nixspam.gz: # 被捕获的 IP - 这样我们就可以不使用灰名单来阻止它们 垃圾邮件陷阱:\ :黑色的:\ :msg="您的地址 %A 已将邮件发送到此服务器上的垃圾邮件陷阱\n\ 过去 24 小时内”:\ :方法=执行:\ :文件=在/usr/local/scripts/get-spamtrapped: 覆盖:\ :白色的:\ :方法=文件:\ :文件=/usr/local/etc/spamd/本地白名单.txt:
- 将 spamd 设置为在启动时运行。请注意,您不是在仅黑名单模式下运行,并且当有人尝试向黑名单发送邮件时,您会抛出 5xx 错误。前者是为了让 spamdb 处理存储/过期捕获地址。后者是礼貌的做法。在 /etc/rc.conf 中添加:
obspamd_enable="是" obspamd_flags="-5"
启动 spamd:/usr/local/etc/rc.d/obspamd start
Cronjob 每小时以仅黑名单模式运行一次 spamd-setup。黑名单模式强制其更新 <spamd> pf 表,而不是 spamd 的内部表。由于 spamd 只是缓送和存储数据,因此其他所有内容都需要在 PF 中。(将 XX 替换为您希望它运行的任何分钟)
# spamd 设置 XX * * * * root /usr/local/sbin/spamd-setup -b
- 在你的机器上创建一个 spamtrap 用户。我给他一个主目录,用于将来的扩展:
$ sudo pw useradd spamtrap -s /sbin/lologin -d /home/spamtrap -m -c “垃圾邮件收集器”
- 创建 /usr/local/scripts/spamtrap:
#!/usr/local/bin/bash
# rudimentary checking - more complex checking will be done by
# the pfctl and spamdb commands
ADDRESS=${1%%[!0-9.]*}
if [[ ! ${#ADDRESS} = ${#1} ]]
then
echo "Invalid characters in IP address"
exit 1
fi
if [ ! ${ADDRESS} ]
then
echo "Usage: $0 <address>"
exit 1
fi
/usr/local/sbin/spamdb -t -a ${ADDRESS}
if [ "$?" -ne 0 ]
then
echo "Failed to add ${ADDRESS} to spamdb"
exit 1
fi
/sbin/pfctl -qt spamd -T add ${ADDRESS}
if [ "$?" -ne 0 ]
then
echo "Failed to add ${ADDRESS} to pf"
exit 1
fi
/usr/bin/logger -t spamtrap "Spamtrap caught ${ADDRESS}"
- 在 Postfix 的 /usr/local/etc/postfix/master.cf 中配置新的传输服务。X 标志告诉 Postfix 考虑此邮件的最终投递,以便垃圾邮件发送者收到成功消息。请注意用户 - 它需要对脚本的 sudo 访问权限。
# 垃圾邮件陷阱 spamtrapper unix-nn--管道 标志 = X 用户 = 无人 argv = / usr / local / bin / sudo / usr / local / scripts / spamtrap $ {client_address}
- 添加到 sudoers:
没有人 ALL=NOPASSWD:/usr/local/scripts/spamtrap
- 创建一条传输规则,将所有发送到 spamtrap@localhost 的邮件发送到 spamtrapper 服务。请参阅“postconf transport_maps”以了解要编辑的文件。默认值为 /usr/local/etc/postfix/transport:
spamtrap@localhost spamtrapper
- 重启 postfix。向 spamtrap@localhost 发送几条消息,并验证发送客户端是否已加载到 spamdb 和 <spamd> pf 表中。
$ echo“测试”|邮件 spamtrap@localhost $ spamdb | grep 127.0.0.1 被困|127.0.0.1|1253655172 $ sudo pfctl-qt spamd-T 显示 127.0.0.1 $
对于每个被垃圾邮件陷阱捕获的电子邮件地址,需要发生两件事。首先,它必须解析为实际的邮箱,这样它才不会在 SMTP 对话期间被拒绝。我使用了别名为 spamtrap@localhost 的虚拟用户。其次,它需要匹配 Postfix 中的 check_recipient_access 规则并重定向到 spamtrap@localhost,这样收件人列表中的合法用户就永远不会看到它。我是如何完成这一部分的:
- 添加到/usr/local/etc/postfix/main.cf:
virtual_maps = hash:/usr/local/etc/postfix/spamtrap_maps smtpd_recipient_restrictions = check_recipient_access 哈希:/usr/local/etc/postfix/spamtrap_recipients
- spamtrap_maps 的格式:
[电子邮件保护] 垃圾邮件陷阱
- spamtrap_recipients 的格式:
[电子邮件保护] 重定向 spamtrap@localhost
- 将这些文件添加到你的 Makefile 并测试。
此时,所有向您的垃圾邮件陷阱地址发送邮件的客户端都应添加到 spamdb 和 <spamd>。目前尚未有任何邮件发送到 spamd。要使整个拦截机制生效,请在 /etc/pf.conf 中添加以下内容并重新加载 pf:
<local-whitelist> 到端口 25 没有 rdr proto tcp rdr 将 proto tcp 从 <spamd> 传递到端口 25 -> 127.0.0.1 端口 8025
就是这样。
可能的扩展
修改垃圾邮件陷阱脚本以将消息的副本存储在贝叶斯垃圾邮件语料库中是很简单的事情。
如果您订阅任何 RBL rsync 服务,则可以轻松地将这些邮件的反弹卸载到 spamd。
答案2
好吧,看来你已经有了自己的答案。但不要责怪 postfix-policyd,它比你想象的要灵活得多,因为它提供了几种机制来对抗垃圾邮件:
Policyd 是 Postfix(基于 MySQL)的反垃圾邮件插件,可执行灰名单、基于发件人(信封或 SASL)的限制(针对每个定义时间单位的消息和/或数量)、垃圾邮件陷阱监控/黑名单和 HELO 自动黑名单。
您不需要使用所有那些武器,并且您可能需要在您的武器中设置更多的规则smtpd_recipient_restrictions
。
无论如何,尝试一下(并阅读文档)或建立自己的解决方案 - 这取决于你。
答案3
这OP 提出的解决方案相当复杂。我使用了一种更简单的方法:
步骤 1:设置过滤文件/etc/postfix/spamtraps
这只是一个简单的“匹配列表”:一个正则表达式(用于垃圾邮件陷阱),并在满足该正则表达式时执行以下操作:
/spam(master|trap)?\@.*/i DISCARD 触发 spamtrap /funkyspammer\@.*/i DISCARD 触发垃圾邮件陷阱
根据您的地址进行调整。
步骤 2:设置规则/etc/postfix/main.cf
查找smtpd_recipient_restrictions
区块,并添加相应的规则前您的网络检查(负载较少),但后经过身份验证的用户。例如:
smtpd_recipient_restrictions = permit_sasl_authenticated 允许我的网络 check_recipient_access regexp:/etc/postfix/spamtraps …
步骤 3:重新加载守护进程
当然,您现在需要重新加载 postfix,以使更改生效。根据您的发行版,可以使用service postfix reload
、/etc/init.d/postfix reload
或类似命令来完成此操作。
第四步:阻止垃圾邮件发送者
这是您可能希望考虑的可选步骤:使用Fail2ban,并让它监视您的邮件日志文件。一旦有人发送垃圾邮件,就禁止该 IP(例如 30 分钟,或者 1 小时 - 不要太久,因为垃圾邮件发送者可能会使用动态 IP,而该 IP 很快就会变得“无辜”)。
答案4
如果有人需要步骤 4 的示例脚本,我们开始吧......
grep '[email protected]' /var/log/maillog >/tmp/badips_raw
grep '[email protected]' /var/log/maillog >>/tmp/badips_raw
egrep -o -e "[0-9]{2,3}\.[0-9]{2,3}\.[0-9]{2,3}\.[0-9]{2,3}" /tmp/badips_raw >> /tmp/badips_nu
sort -u /tmp/badips_nu > /tmp/badips
rm -rf /tmp/badips_raw
rm -rf /tmp/badips_nu
while read ip
do
fail2ban-client set postfix-sasl banip $ip
done < /tmp/badips
rm -rf /tmp/badips