Postfix配置Milter后被拒邮件仍经过Milter引发邮件轰炸性能问题的咨询
首先,这种情况其实是Postfix默认行为导致的,但我们可以通过调整配置来优化,让被提前拦截的邮件尽量不经过Milter,减轻负载。我来帮你分析一下并给出具体的调整方案:
为什么被拒邮件还是会经过Milter?
Postfix默认会在SMTP连接建立后就初始化Milter会话,哪怕后续在RCPT TO阶段拒绝了收件人(比如“User unknown”或者policy service拒绝),虽然不会传递邮件内容,但Milter还是会处理连接级别的交互。如果遇到邮件轰炸,大量这样的短连接也会让Milter不堪重负。另外,如果你的某些拒绝规则位置靠后,导致部分邮件进入了DATA阶段才被拒绝,那Milter自然会处理完整的邮件内容,进一步增加负载。
具体优化方案
1. 让Postscreen提前拦截更多垃圾邮件
你的配置里已经启用了Postscreen,但可以加强它的DNSBL检查,在SMTP会话的最早期(甚至在发送220问候之前)就拦截恶意IP,根本不会进入smtpd处理流程,自然不会触发Milter。修改你的postscreen_dnsbl_sites配置:
postscreen_dnsbl_sites = list.dnswl.org*-1, zen.spamhaus.org*5, bl.spamcop.net*2, b.barracudacentral.org*3
同时调整阈值(根据你的需求调整):
postscreen_dnsbl_threshold = 3
这样,累计DNSBL分数达到3的IP会被直接拒绝,不需要进入后续的SMTP交互。
2. 调整收件人限制规则的顺序,尽早拒绝无效收件人
看你的smtpd_recipient_restrictions配置,把基础的无效收件人检查规则提前,确保在允许本地网络或执行其他检查前,先过滤掉明显无效的请求:
smtpd_recipient_restrictions = # postfwd check_recipient_access hash:/etc/postfix/reject-abandoned-mailboxes, check_recipient_access hash:/etc/postfix/reject-over-quota-mailboxes, # Defer email sent to unverified domains, unless it's our # special email address for verifying the domain. check_recipient_access hash:/etc/postfix/defer-unverified-domains, reject_non_fqdn_recipient, reject_invalid_hostname, reject_unknown_recipient_domain, permit_mynetworks, reject_unauth_pipelining, reject_unauth_destination, check_policy_service inet:127.0.0.1:10040
这样,无效的收件人会在最早期被拒绝,不会进入后续的步骤,也不会触发Milter的内容处理。
3. 配置Milter协议版本,让Postfix更早终止Milter会话
确保你的Milter支持Milter协议版本6(大部分现代Milter服务比如OpenDKIM、SpamAssassin Milter都支持),然后在main.cf中添加:
milter_protocol = 6 milter_default_action = accept milter_connect_timeout = 5s milter_command_timeout = 10s
协议版本6允许Postfix在SMTP会话的更早阶段(比如RCPT TO阶段)与Milter交互,并且在拒绝收件人后立即终止Milter会话,减少不必要的资源占用。超时参数可以防止Milter因响应缓慢而占用过多连接。
4. 验证relay_recipient_maps的有效性
你的配置里已经设置了relay_recipient_maps = hash:/etc/postfix/relay-recipient-maps,确保这个映射文件已经正确编译(运行postmap /etc/postfix/relay-recipient-maps),并且包含了所有允许接收邮件的收件人。Postfix会在RCPT TO阶段检查这个映射,不在里面的收件人会被直接拒绝,不会进入DATA阶段。
最后验证
调整完配置后,记得重新加载Postfix:
postfix reload
然后可以通过查看Postfix日志(/var/log/mail.log或类似路径)来确认,被拒绝的邮件是否在早期阶段就被拦截,并且Milter的日志里没有对应的处理记录。
备注:内容来源于stack exchange,提问作者Jamie McClelland

