Debian 12(Bookworm)环境下Exim maildir_local_delivery传输报错:受污染路径'Maildir/'不被允许
遇到这个问题我太感同身受了!之前在Debian 12上配置Exim本地投递的时候也踩过一模一样的坑,咱们先把问题理清楚,再一步步解决。
问题场景回顾
你在Debian 10上用的这个maildir_local_delivery传输配置完全正常:
maildir_local_delivery: driver = appendfile group = mail maildir_format = true create_directory = true directory = /home/${local_part}/Maildir/ mode_fail_narrower = false delivery_date_add = true envelope_to_add = true return_path_add = true mode = 0660
但升级到Debian 12(Bookworm)后,Exim日志里就出现了这个报错:
2023-09-18 16:13:01 1qiEzk-0003F9-1M == exampleuser@example.com R=localuser T=maildir_local_delivery defer (-1): Tainted '/home/exampleuser/Maildir/' (file or directory name for maildir_local_delivery transport) not permitted
问题根源
这其实是Debian 12里的Exim默认启用了更严格的路径安全检查机制。${local_part}这个变量属于被Exim标记为「受污染(tainted)」的变量——简单说就是Exim不确定这个变量的内容是否安全,直接用它拼接路径可能存在路径遍历之类的风险,所以新版本就直接阻止了这种用法,而Debian 10的Exim还没有这么严格的限制。
另外看了你贴的/etc/group配置,Debian-exim已经加入了mail组,权限方面是没问题的,核心问题就是路径变量的安全验证。
解决方案
这里给你两种靠谱的解决办法,按需选择:
方法一:使用Exim内置的安全变量(推荐)
把directory配置里的路径改成用${home}变量,这是Exim内置的、已经经过安全验证的变量,会直接获取对应本地用户的家目录路径,完全不会触发tainted警告:
directory = ${home}/Maildir/
修改完重启Exim服务,投递应该就能正常工作了,这也是最安全的做法。
方法二:手动标记变量为安全(谨慎使用)
如果你因为某些原因必须用${local_part}来拼接路径,可以用Exim的untaint函数把变量标记为安全的,修改后的配置如下:
directory = /home/${untaint{local_part}}/Maildir/
⚠️ 注意:这种方式一定要谨慎!只有当你能完全控制本地用户的命名规则(确保不会出现../这类恶意路径字符)的时候再用,不然可能会引入安全风险。
修改配置后记得重启Exim服务,验证邮件投递是否恢复正常。
备注:内容来源于stack exchange,提问作者LetMeSOThat4U

