Sendmail邮件接收处理链、配置执行顺序排查及异常问题咨询
嘿,针对你的两个问题,我来一步步帮你梳理解决办法:
一、如何确定Sendmail中转换和Milters的精确执行顺序
要搞清楚Sendmail里各种转换规则和Milters的执行顺序,这几个方法非常实用:
直接查看配置文件的定义顺序
Milters的执行顺序完全取决于它们在sendmail.mc中用INPUT_MAIL_FILTER指令定义的先后顺序。比如你在mc文件里先写了垃圾检查的milter,再写收件人验证的milter,那前者就会先执行。生成sendmail.cf后,里面以X开头的行就是Milters的定义,顺序和mc文件里一致。用
sendmail -bt调试工具深挖细节
这是Sendmail自带的最强调试工具,执行sendmail -bt进入交互模式后:- 输入
/milter可以直接列出所有已配置的Milters,以及它们的启用状态和执行顺序; - 输入
/parse 不存在的账户@你的域名.com,可以模拟邮件接收的完整流程,从SMTP握手到规则集处理,每一步的转换、Milters调用都会清晰显示出来,你能直观看到哪个步骤先执行。
- 输入
开启详细日志追踪
修改sendmail.mc里的LogLevel参数,比如设为LogLevel=9(最高级别),然后重新生成配置文件并重启Sendmail。之后查看邮件日志(一般是/var/log/maillog或/var/log/mail.log),里面会详细记录每个Milters的调用时间、处理阶段,以及转换规则的执行顺序,能帮你定位每一步的细节。
二、解决已删除账户邮件先过垃圾检查再被丢弃的问题
出现这种情况,大概率是收件人验证的时机晚于垃圾检查Milters的执行时机,导致邮件先经过垃圾扫描,才被判定为收件人不存在。可以从这几个方向调整:
调整Milters的执行顺序
在sendmail.mc里,把负责收件人验证的规则或Milters(比如自定义的收件人检查milter,或者系统自带的收件人验证逻辑)放在垃圾检查Milters的前面定义。比如先写收件人验证的INPUT_MAIL_FILTER,再写垃圾检查的,这样Sendmail会先验证收件人是否存在,再进行垃圾扫描。确保收件人检查在SMTP早期阶段完成
收件人检查最好在SMTP会话的RCPT TO阶段就完成,如果这时候发现收件人不存在,Sendmail会直接返回550 User unknown,不让邮件进入后续的DATA阶段(垃圾检查往往在这个阶段执行)。你可以在sendmail.mc里配置LOCAL_RCPT_CHECK规则集,把收件人存在性检查放在这个规则集里,确保它在Milters之前被调用。排查是否有映射规则导致误判
有时候已删除的账户可能还在别名映射、虚拟用户映射里有残留,导致Sendmail误以为收件人存在。用sendmail -bt执行/alias 已删除账户或者/map virtuser 已删除账户@你的域名.com,检查是否有残留的映射记录,有的话及时清理。调整Milters的触发阶段
有些垃圾检查Milters默认在DATA阶段触发,你可以在INPUT_MAIL_FILTER里加上S=RCPT参数,让它在RCPT TO阶段就执行,不过更合理的还是让收件人检查先执行,避免不必要的资源浪费。
备注:内容来源于stack exchange,提问作者Hack Saw

