fail2ban自定义报警动作需在/etc/fail2ban/action.d/下创建.conf文件,含[definition]段,明确定义actionban(封禁时执行)、actionunban等,用、等占位符动态注入值;敏感参数(如webhook token、邮箱)应通过[init]段传入,避免硬编码;外部命令须用绝对路径,并添加timeout、返回码判断及日志重定向以保障可靠性。

Fail2ban 的 action.d 目录里怎么写自定义报警动作
Fail2ban 封 IP 后自动发邮件、发微信或调用 webhook,核心是写一个自定义 action,放在 /etc/fail2ban/action.d/ 下。它不是改 jail.local 就能触发的“开关”,而是要明确定义“封禁时执行什么命令”。action 文件本质是模板:Fail2ban 会把 <ip></ip>、<failures></failures>、<time></time> 这类占位符替换成真实值,再执行你写的 shell 命令。
常见错误是直接在 actionstart 或 actionban 里写死邮箱或 token——这样不安全也不灵活。正确做法是把敏感参数抽出来,通过 action.d/xxx.conf 的 [Init] 段落传入,再在动作中引用 <name></name> 占位符。
- 文件名必须以
.conf结尾,比如alert-mail.conf - 必须包含
[Definition]段,并定义actionstart、actionban、actionunban(至少前两个) -
actionban是关键:封禁 IP 时唯一被执行的动作,报警逻辑放这里 - 所有外部命令(如
curl、mail)必须绝对路径,Fail2ban 不加载用户环境变量
用 curl 发送企业微信/钉钉 webhook 怎么避免超时和失败
Webhook 调用失败不会中断 Fail2ban 流程,但默认无重试、无日志,容易误以为“没发出去”。直接写 curl -s -X POST ... 在高并发或网络抖动时大概率丢告警。
推荐加三重保险:
- 用
timeout 5包裹curl,防止卡住整个 fail2ban-server 进程 - 检查
curl返回码:if [ $? -eq 0 ]; then ... else logger -t fail2ban "webhook failed for <ip>"; fi</ip> - 把
curl日志重定向到/var/log/fail2ban-alert.log,方便排查 403、414 等响应体问题
示例片段(截取 actionban):
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
actionban = timeout 5 curl -s -X POST \
-H 'Content-Type: application/json' \
-d '{"msgtype": "text", "text": {"content": "Fail2ban blocked <ip> after <failures> attempts at <time>."}}' \
'<webhook_url>' >> /var/log/fail2ban-alert.log 2>&1 || \
logger -t fail2ban "alert-webhook: curl failed for <ip>"</ip></webhook_url></time></failures></ip>
邮件报警为什么收不到?重点查这四个地方
用 mail 或 sendmail 发邮件失败,90% 不是配置错,而是权限和路径问题。
- Fail2ban 进程默认以
root运行,但mail命令可能依赖用户级 MTA 配置(比如~/.mailrc),root 用户下往往不存在 - 别用
mail -s "..." admin@example.com,必须用printf构造完整邮件头:printf "To: admin@example.com\nSubject: Fail2ban Alert\n\nIP <ip> blocked.\n" | sendmail -t</ip> - 确保
sendmail或msmtp已安装且可执行:which sendmail输出应为/usr/sbin/sendmail - 如果用
msmtp,需给root用户单独配/root/.msmtprc,并设权限chmod 600 /root/.msmtprc
怎么让同一个 IP 多次触发只报一次警
默认情况下,每次 failregex 匹配都会触发一次 actionban,同一 IP 在冷却期内反复尝试,就会重复报警。这不是 bug,是设计如此——但多数人不需要刷屏告警。
解决思路是加一层“去重锁”:
- 用
ipset记录已报警的 IP:ipset create alerted hash:ip timeout 86400(存 24 小时) - 在
actionban开头加判断:ipset test alerted "<ip>" > /dev/null || { ipset add alerted "<ip>" && YOUR_ALERT_COMMAND; }</ip></ip> - 注意:必须确保
ipset命令存在,且ipset模块已加载(lsmod | grep ip_set)
这个逻辑不能放在 shell 函数里,必须 inline 写进 actionban 字符串,否则 Fail2ban 不解析变量。
真正难搞的是时间窗口和并发——ipset 本身线程安全,但如果你用文件锁或临时文件做标记,就很容易漏报或死锁。










