
我們有一個 header_checks 正規表示式傳遞給「清理」過程,但如果它位於多行上,它不會將標頭作為單一標頭進行處理。
header_check(將標頭值傳遞給 FILTER):
/^X-OurHeader:\s+(.*?)/ FILTER $1
master.cf:
cleanup_service. unix n - y - 0 cleanup
-o header_checks=regexp:/etc/postfix/header_check
失敗的多行標題範例:
X-OurHeader: a_special_filter_command:my.sub.domain
b.mail.whatever.com
多行之前的原始完整標題是:
X-OurHeader: a_special_filter_command:my.sub.domainb.mail.whatever.com
傳遞給 FILTER 的結果是:a_special_filter_command:my.sub.domain
並且缺少第二行中剩餘的主機名稱b.mailwhatever.com
。
如果我將 header_check 更改為此,那麼它會捕獲下一行:
/^X-OurHeader:\s+([\s\S]*)/ FILTER $1
然後 $1 捕獲組包含第二行,但捕獲的文字中仍然有一個空格(可能是換行符),因此這不起作用。看起來像這樣:
X-OurHeader: a_special_filter_command:my.sub.domain b.mail.whatever.com
使用第一種方法查看日誌,我們看到
postfix/cleanup[123456]: 27429A1FE8: filter: header X-OurHeader: a_special_filter_command:my.sub.domain? b.mail.whatever.com
有沒有人可能建議的替代方法?最終目標是我們用需要發送到過濾器的特殊 cmd:hostname 值標記標頭,但希望支援將 hdr 值分解為長標頭的多行以滿足「長度應該 < 78英寸標準。
答案1
如果您知道或可以確保只有一定數量的變化,請添加額外的表達式來單獨捕獲這些變化/..:(.*) (.*)$/ -> /..:$1$2/
- 如果沒有空格,後綴將繼續下一個表達式,因此通過將複雜的匹配放在前面來保持模式簡單。
如果不是,但仍在正規表示式的範圍內,可能有一種方法鍊式多次查找。從我的頭腦中,我無法拼湊出完整的內容,但如果它在您的發行版上可用並且完全有效,那麼文件應該會有所幫助,從手冊header_checks
和DATABASE_README
文件開始。
pipemap:{pcre:/extract/category.pcre,pcre:/map/category/to/filter/command.pcre}
基本概念:首先獲得大致方向(例如MYFILTER: $1
),然後才應用必要的編輯以使其成為有效的後綴命令,仔細確保所有輸入都會導致有效的輸出(MYFILTER: (valid1|valid2) -> FILTER host:port
加上後備行MYFILTER:
-> FILTER: default:port
)
如果你做不到這一點,通常當你想做的事情對於正規表示式和 header_checks 來說太強大時,你會升級到圖靈完整性:
足夠動態的尋找。例如,如果您喜歡 SQL,那應該會為您帶來一些可讀性/可維護性不會那麼差的東西。小心多次查找產生的意外邏輯結果
header_checks = sqlite:/path/to/definition.conf pcre:/remaining/simpler/rules.pcre
米爾特/策略守護程序。他們甚至可能調用外部二進位檔案而不重定向訊息。根據您目前想法的下一個 FILTER 的介面,這可能或多或少方便。
我也相信有辦法讓 postfix 正確運輸如果需要的話,透過 header_checks 的多個實例發送給定的訊息,但我不推薦該路由,它不能與其他(或多或少動態的)路由決策很好地混合。