Postfix配置本地虚拟用户邮件转发时,如何实现To头自动替换且不修改From头?
我完全懂你现在的痛点——手动维护virtual和smtp_header_checks两个文件太容易出错了,毕竟没人能保证每次改完转发规则都记得同步头替换规则,搞不好哪天就出现转发地址和邮件头显示不一致的问题。其实Postfix本身就提供了更优雅的解决方案,不用重复维护配置,还能完美满足你的需求:保留原始From头,自动把To头替换成真实收件人,同时只需要维护一份转发规则。
核心思路:用动态查询替代硬编码
你现在的问题是把转发规则和头替换规则硬编码成了两份,我们可以利用Postfix的${lookup}指令,让smtp_header_checks直接读取virtual映射表中的配置,这样只需要维护/etc/postfix/virtual这一个文件就行。
具体配置步骤
保持
virtual映射表不变
你已经在/etc/postfix/virtual里配置好了转发规则,继续用它就行:root user1@domain.tld, user2@domain.tld后续要加其他虚拟用户的话,直接在这里追加规则,不用动其他文件。
修改
smtp_header_checks实现动态替换
把你原来硬编码的头替换规则,改成通过${lookup}查询virtual映射表的动态规则:/^To:.*root@myhost.domain.tld.*/ REPLACE To: ${lookup lmdb:/etc/postfix/virtual {root}}这个规则的意思是:匹配任何To头包含
root@myhost.domain.tld的邮件,自动查询virtual映射表里root对应的真实地址,然后替换To头内容。如果你的虚拟用户不止root一个,还可以写个更通用的正则,匹配所有本地虚拟用户:
/^To:.*(\w+)@myhost.domain.tld$/ REPLACE To: ${lookup lmdb:/etc/postfix/virtual {$1}}这样不管是发给
admin@myhost.domain.tld还是foo@myhost.domain.tld,只要在virtual表里有对应规则,To头都会自动替换成真实收件人。重新加载Postfix配置
先确保virtual表的索引文件是最新的(如果刚修改过virtual文件的话):postmap /etc/postfix/virtual然后重新加载Postfix:
systemctl reload postfix
为什么这个方法更好?
- 只维护一份配置:所有转发规则都在
virtual文件里,改一次就同时生效转发和头替换,彻底避免同步错误。 - 完美保留From头:这个规则只会替换To头,原始的
From: root@myhost.domain.tld会完整保留,完全符合你要识别发送来源的需求。 - 支持多收件人:如果
virtual里配置了多个收件人(比如root对应两个邮箱),${lookup}会自动返回所有地址,To头会正确显示多个收件人。
额外说明
你之前提到考虑过alias_maps,其实如果启用local服务(在master.cf里取消local相关行的注释),用/etc/aliases也能实现类似效果,但既然你已经用了virtual_alias_maps的方案,上面的动态查询方法更贴合你的现有配置,不用改动太多。
备注:内容来源于stack exchange,提问作者StinGer

