OpenDKIM配置后,MTA本地邮件DKIM验证正常,但内部远程服务器邮件因body hash不匹配导致验证失败求助
看起来你遇到的核心问题是:MTA本地发送的邮件DKIM验证完全正常,但内部远程服务器通过MTA转发的邮件,虽然OpenDKIM日志显示已成功添加签名,可收件方验证时却提示「body hash did not verify」。我来帮你梳理几个最可能的原因和对应的排查/解决办法:
一、先试试最快速的修复:调整OpenDKIM的规范化模式
你当前的opendkim.conf里设置的是Canonicalization relaxed/simple——其中simple模式对邮件正文的要求极其严格,哪怕多一个空格、换行符格式差异(比如Unix的LF和Windows的CRLF)都会导致哈希不匹配。
建议把这个配置改成:
Canonicalization relaxed/relaxed
relaxed模式会忽略正文里的多余空格、换行符格式差异,对小的内容变动容忍度更高。修改后重启opendkim和postfix,再测试邮件验证情况。
二、排查Postfix是否在转发时修改了邮件内容
你的Postfix配置里启用了canonical_maps = hash:/etc/postfix/canonical,这个配置可能会修改邮件的头部甚至正文内容。如果DKIM签名是在Postfix修改内容之前生成的,那收件方拿到的是修改后的内容,自然哈希不匹配。
- 打开
/etc/postfix/canonical文件,检查是否有会修改邮件正文、From/To等关键头部的规则,如果有,要么暂时注释掉测试,要么调整Postfix的处理顺序,确保canonical_maps的修改在DKIM签名之前完成。 - 另外,检查Postfix是否启用了
header_checks、body_checks这类可能修改邮件内容的配置,如果有,同样暂时禁用测试。
三、确认邮件在传输过程中是否被篡改
内部服务器到MTA的传输过程中,可能被中间设备(比如防火墙、代理)或者内部服务器自身的Postfix配置修改了邮件内容:
- 在内部服务器用
swaks发送一封测试邮件:swaks --to test@gmail.com --server mta.mydomain.com --from test@domain3.co.uk --body "Test body content" - 在MTA上用
tcpdump抓取SMTP端口(25)的流量,导出邮件原始内容,和内部服务器发送的原始内容对比,重点看正文部分是否有差异(比如换行符、空格、额外字符)。
四、检查Milter的执行顺序
如果你的MTA还启用了其他Milter(比如反垃圾邮件、内容过滤工具),要确保OpenDKIM是最后一个执行的Milter。如果其他Milter在DKIM签名之后修改了邮件内容,就会导致哈希不匹配。
查看main.cf里的smtpd_milters和non_smtpd_milters配置,确保inet:localhost:8891(OpenDKIM)排在最后一位。
五、深挖OpenDKIM日志找线索
你的opendkim.conf里已经开启了Logwhy yes,这个配置会记录更多签名/验证相关的细节。可以查看更详细的OpenDKIM日志,看看有没有关于正文修改、哈希计算的提示,比如:
tail -f /var/log/syslog | grep opendkim
说不定能找到为什么同一域名的邮件,本地发的和远程发的哈希结果不同的具体原因。
备注:内容来源于stack exchange,提问作者btongeorge

