Procmail规则适配编码Subject头失败求助
修复Procmail处理DMARC报告时的编码Subject匹配问题
问题背景
原有Procmail规则可正常处理DMARC报告,但当Subject头被Base64编码时,规则会失效。尝试解码Subject后匹配的方案出现执行错误:日志显示跳过目标邮件,且邮件被错误投递到Folder: SUBJECT=Subject:路径下。
原始正常规则
:0 * ^To:.*anonymized * ^Subject:.*Report domain: anonymized Submitter: [^ ]* Report-ID: { LOG="1" :0 cw * ^To:/.+ | /etc/procmail/process_dmarc_report.sh "$MATCH" }
尝试的错误规则及问题
以下规则可正确解码Subject,但会触发投递错误:
:0 * ^Subject:.*=\?utf-8\?B\? SUBJECT=`formail -cXSubject: | perl -MMIME::Base64 -ne 's/^=\?utf-8\?B\?(.*?)\?=$/print decode_base64($1)/e'` :0 E SUBJECT=`formail -cXSubject:` :0 * ^To:.*anonymized * SUBJECT ?? Subject:.*Report domain: anonymized Submitter: [^ ]* Report-ID:.* { LOG="1" :0 cw * ^To:/.+ | /etc/procmail/process_dmarc_report.sh "$MATCH" }
问题根源
- 变量赋值被识别为投递路径:Procmail中直接写
VAR=...``会被当作邮件投递目标,这是邮件被投递到SUBJECT=Subject:的核心原因。 - 解码逻辑不严谨:未处理
Subject:前缀,且仅覆盖了纯Base64编码的场景。 - 匹配规则冗余:解码后的
SUBJECT变量已无Subject:前缀,规则中保留该前缀会导致匹配失败。
修复后的规则
# 解码Subject头,处理UTF-8 Base64编码的情况 :0 hw * ^Subject:.*=\?utf-8\?B\? { # 提取Subject内容并解码,自动去除Subject:前缀 SUBJECT=`formail -c -x Subject: | perl -MMIME::Base64 -ne ' s/^=\?utf-8\?B\?(.*?)\?=$/$1/; print decode_base64($_) '` } :0 E hw { # 非编码Subject,直接提取内容(去除Subject:前缀) SUBJECT=`formail -c -x Subject:` } # 匹配目标邮件并处理DMARC报告 :0 * ^To:.*anonymized * SUBJECT ?? ^Report domain: anonymized Submitter: [^ ]* Report-ID:.* { LOG="Processing DMARC report" :0 cw * ^To:/.+ | /etc/procmail/process_dmarc_report.sh "$MATCH" }
关键修复说明
- 用花括号包裹变量赋值:避免Procmail将变量赋值识别为投递路径。
- 使用
formail -x Subject::小写-x参数自动去除Subject:前缀,简化后续处理。 - 添加
hw标志:h限定仅处理邮件头,w确保命令执行完成后再进行后续匹配,保证变量赋值生效。 - 修正匹配规则:移除
Subject:前缀,直接匹配解码后的纯文本内容。
内容的提问来源于stack exchange,提问作者Chris972
相关产品推荐
相关产品推荐

