Postfix限制规则逻辑调整需求及SASL暴力破解防护方案咨询
我完全理解你对Postfix当前规则逻辑的不满——这种“匹配即终止”的OR模式在防范SASL暴力破解时确实显得不够严谨,毕竟我们都希望通过多层验证构建更坚固的防御体系,而不是让攻击者侥幸绕过后续限制。下面我来拆解你的问题,给出可行的解决方案:
一、先聊聊Postfix为什么用“匹配即停止”的逻辑
Postfix的限制链设计成顺序执行、匹配即返回,本质是为了性能与灵活性:不同场景下可以快速匹配到合适的规则(比如信任的内网直接放行,不用走后续检查),减少不必要的计算开销。但这种设计确实和你想要的“多层强验证”需求冲突,不过我们可以通过自定义规则类和分阶段检查来实现类似AND的效果。
二、实现“需通过所有指定限制”的AND逻辑
要让攻击者必须通过所有你设定的验证步骤,核心是把不同类型的检查分散到Postfix的不同连接阶段,或者用自定义限制类来封装必须全部满足的条件:
方案1:利用多阶段限制链实现分层验证
Postfix的不同smtpd_*_restrictions参数对应不同的连接阶段,每个阶段的检查都必须通过才能进入下一个环节,天然就是AND逻辑:
# 客户端连接阶段:先做IP黑名单/白名单、RBL检查 smtpd_client_restrictions = permit_mynetworks, reject_rbl_client zen.spamhaus.org, reject_rhsbl_reverse_client dbl.spamhaus.org # HELO/EHLO阶段:检查HELO域名的RBL smtpd_helo_restrictions = reject_rhsbl_helo dbl.spamhaus.org # 发件人声明阶段:检查发件人域名的RBL smtpd_sender_restrictions = reject_rhsbl_sender dbl.spamhaus.org # 收件人声明阶段:最后做SASL认证,所有前置检查通过后才允许认证通过 smtpd_recipient_restrictions = permit_sasl_authenticated, reject
这样攻击者必须依次通过:IP检查 → HELO检查 → 发件人检查 → SASL认证,任何一步失败都会被拒绝,完全符合你要的多层验证需求。
方案2:自定义限制类强制多条件同时满足
如果你希望把多个条件打包成一个“必须全部通过”的规则,可以用smtpd_restriction_classes自定义限制类:
# 定义一个自定义限制类,里面的规则必须全部满足(只有所有permit条件都匹配,最后才不会被reject) smtpd_restriction_classes = strict_access strict_access = permit_mynetworks, permit_sasl_authenticated, reject_rhsbl_helo dbl.spamhaus.org, reject_rhsbl_reverse_client dbl.spamhaus.org, reject_rhsbl_sender dbl.spamhaus.org, reject_rbl_client zen.spamhaus.org, reject # 客户端限制链直接调用这个自定义类 smtpd_client_restrictions = strict_access
注意:这个类里的规则逻辑是:只有当客户端在mynetworks并且通过SASL认证并且所有RBL检查都通过,才会被放行;否则只要有一步不满足,就会触发后续的reject。
三、除了Fail2ban,更硬核的SASL暴力破解防护方案
如果你觉得Fail2ban是“治标不治本”的补丁,这些方法能从根源强化SASL防护:
- 限制SASL认证机制:禁用明文认证(比如plain、login),只保留加密的强认证机制,比如CRAM-MD5、DIGEST-MD5或者OAUTH2。修改
smtpd_sasl_security_options:smtpd_sasl_security_options = noanonymous, noplaintext - 动态限制认证尝试次数:结合Postfix的
check_client_access和脚本,监控SASL失败日志,当某个IP失败次数超过阈值时,临时加入黑名单。比如在main.cf里添加:
然后写个脚本定时扫描smtpd_client_restrictions = check_client_access hash:/etc/postfix/dynamic_blacklist, ...其他规则...mail.log,提取SASL失败的IP,更新dynamic_blacklist并执行postmap /etc/postfix/dynamic_blacklist。 - 限制SASL认证的IP范围:只允许信任的IP段尝试SASL认证,其他IP直接拒绝或者要求更严格的验证:
在smtpd_client_restrictions = check_client_access hash:/etc/postfix/sasl_allowed_ips, rejectsasl_allowed_ips里添加允许的IP:192.168.1.0/24 OK,其他IP默认拒绝。 - 启用SASL认证日志并监控:确保Postfix记录详细的SASL认证日志,修改
main.cf:
然后用监控工具实时追踪认证失败次数,及时发现异常攻击。smtpd_sasl_authenticated_header = yes syslog_name = postfix/smtpd
备注:内容来源于stack exchange,提问作者Digital Joe George

