Postfix结合Dovecot与简易内容过滤器时always_bcc重复投递问题排查求助
嗨,我仔细看了你的配置和日志,这个重复BCC的问题根源其实出在简易内容过滤器的二次提交逻辑上,咱们一步步捋清楚:
问题原因分析
从你的日志能看到完整流程:
- 初始邮件(DD925380C87)通过smtpd接收后,Postfix先触发
always_bcc规则,把seccopies@mydomain.example加入收件人列表; - 邮件被送到你配置的
filter服务处理,脚本里用sendmail把处理后的邮件重新提交回Postfix(生成新队列项AAFEF380C8D); - 这次二次提交的邮件,Postfix会再次执行全局
always_bcc规则,又给seccopies添加了一次投递,最终导致两份副本。
简单说:你的过滤器相当于把邮件重新发了一遍,两次投递都触发了BCC规则,自然就重复了。
几个可行的解决方案
方案1:修改过滤器脚本,禁用二次提交时的BCC
这是最直接的方法,在重新提交邮件时给sendmail加参数,临时覆盖全局always_bcc配置。修改/var/spool/filter/scripts/filter.sh的最后一行:
/usr/bin/cat | /var/spool/filter/scripts/mailfilter | /usr/sbin/sendmail -G -i -o always_bcc= "$@"
这里的-o always_bcc=会让这次二次投递不再生成BCC副本,只有第一次初始投递会触发规则。
方案2:改用Postfix队列后过滤器(After-Queue Filter)
如果不想修改脚本,可以把过滤器改成队列后处理模式——等Postfix完成所有队列前处理(包括always_bcc)后,再替换From地址。这种模式下过滤器不会重新提交邮件,自然不会重复触发BCC:
- 在
master.cf里保留过滤服务配置,但调整脚本逻辑,直接修改邮件后返回给Postfix,不再调用sendmail; - 在
main.cf里把smtpd的content_filter替换为queue_filter=filter:dummy(队列后过滤的配置项)。
这个方法适合长期优化,低流量场景下完全适用。
方案3:用条件式BCC避免重复触发
把全局always_bcc改成仅对smtpd初始接收的邮件生效,跳过pickup/pipe进来的二次投递。比如在main.cf里用check_recipient_access或header_checks实现条件BCC,但配置相对复杂,不如前两个方案直接。
验证建议
修改配置后发测试邮件,查看日志是否只有一次seccopies的投递记录——应该只有初始队列项触发BCC,二次提交的邮件不再包含seccopies作为收件人。另外,你的mailfilter只修改邮件头From地址,日志里的from=显示原始用户地址是正常的,只要收件人看到的是角色地址就没问题。
备注:内容来源于stack exchange,提问作者Yanko Hernández Álvarez

