一、問題背景
在管理郵件伺服器時,Fail2Ban 常用於封鎖惡意連線或暴力破解行為。
Rico 在 CentOS 7(Fail2Ban v0.11.2 / Python 2.7)環境下執行以下指令測試 Postfix 過濾器:
fail2ban-regex /data/docker/mailsys/postfix/alpine-3.22.1/log/postfix.log /etc/fail2ban/filter.d/postfix-pipelining.conf -v
卻出現錯誤訊息:
ConfigParser.InterpolationMissingOptionError:
Bad value substitution: key: __prefix_ipv4
二、問題原因
Fail2Ban 的過濾器(filter)會引用一些共用變數,如:
%(__prefix_ipv4)s, %(__prefix_ipv6)s, %(__prefix_line)s
這些變數定義在 /etc/fail2ban/filter.d/common.conf。
但在某些舊版(如 0.11.x for CentOS 7)中,__prefix_ipv4 和 __prefix_ipv6 並未被定義,
導致過濾器解析失敗。
三、修正方法
✅ 方法一:改用 <HOST>(推薦)
Fail2Ban 內建 <HOST> 巨集,自動辨識 IPv4 與 IPv6。
修改 /etc/fail2ban/filter.d/postfix-pipelining.conf:
[INCLUDES]
before = common.conf
[Definition]
_daemon = postfix(-.*)?/smtpd
failregex = ^%(__prefix_line)s(?:postfix/(?:smtpd|submission/smtpd)\[\d+\]: )NOQUEUE: lost connection after CONNECT from .*?\[(?P<host><HOST>)\].*$
ignoreregex =
測試:
fail2ban-regex /data/docker/mailsys/postfix/alpine-3.22.1/log/postfix.log /etc/fail2ban/filter.d/postfix-pipelining.conf -v
若輸出顯示:
Failregex: 10 total
Lines: 293 lines, 0 ignored, 10 matched
即代表成功命中。
✅ 方法二:手動補上變數(若不想改 regex)
在 filter 開頭自行定義:
__prefix_ipv4 = (?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)){3})
__prefix_ipv6 = (?:[0-9A-Fa-f:]+)
四、延伸:建立 Postfix 過濾器防護
建立 jail 設定 /etc/fail2ban/jail.d/postfix-pipelining.local:
[postfix-pipelining]
enabled = true
filter = postfix-pipelining
logpath = /data/docker/mailsys/postfix/alpine-3.22.1/log/postfix.log
port = smtp,submission,465,587
maxretry = 3
findtime = 10m
bantime = 1h
ignoreip = 127.0.0.1/8 ::1 你的公司白名單IP
banaction = iptables-multiport
重新載入:
fail2ban-server reload
fail2ban-client status postfix-pipelining
五、進階:擴充另一個過濾器 postfix-noqueue-connect
以下是修正版過濾器:
[INCLUDES]
before = common.conf
[Definition]
_daemon = postfix(-.*)?/smtpd
failregex = ^%(__prefix_line)s(?:postfix/(?:smtpd|submission/smtpd)\[\d+\]: )?NOQUEUE: lost connection after CONNECT from (?:\S+)?\[(?P<host><HOST>)\]
ignoreregex =
建立 jail:
[postfix-noqueue-connect]
enabled = true
filter = postfix-noqueue-connect
logpath = /data/docker/mailsys/postfix/alpine-3.22.1/log/postfix.log
backend = auto
port = smtp,submission,465,587
maxretry = 3
findtime = 10m
bantime = 1h
六、結論
修正後,Fail2Ban 成功抓取並封鎖來自多個惡意 IP 的 Postfix 嘗試連線。
使用 <HOST> 巨集可避免舊版 common.conf 缺失問題,
並確保過濾器在不同版本間仍具相容性與穩定性。