Fail2ban默认不防护HTTP管理后台,因其仅监控系统日志(如/var/log/auth.log),而Web登录失败记录在Nginx/Apache错误或访问日志中;必须配置匹配的日志路径、自定义filter及正确正则规则,否则无法识别POST暴力请求。

Fail2ban 本身不直接支持 HTTP 管理后台(如 WordPress 登录页、phpMyAdmin、自建 admin.php)的防护,必须配合自定义 filter 和正确日志路径才能生效——否则它根本“看不见”那些 POST 请求失败。
为什么默认 fail2ban 不拦管理后台暴力破解
Fail2ban 默认只监控系统服务日志(/var/log/auth.log、/var/log/secure),而 Web 后台的登录失败通常记录在 Web 服务器日志里:/var/log/nginx/error.log、/var/log/apache2/error.log 或应用自定义日志(如 /var/www/myapp/logs/login.log)。没有匹配规则,fail2ban 就像没装摄像头。
常见错误现象:
-
fail2ban-client status nginx-http-auth显示 0 banned IPs,但grep "401" /var/log/nginx/access.log | tail -20明显有大量异常 POST - 手动触发一次错误登录,
sudo fail2ban-regex /var/log/nginx/error.log /etc/fail2ban/filter.d/nginx-http-auth.conf返回 0 matches
配置 nginx + fail2ban 拦截 /admin/login 的暴力请求
以 Nginx + 自建 PHP 后台为例,假设登录失败时返回 HTTP 401 且日志中含 "POST /admin/login HTTP/1.1" 401,需三步打通链路:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 确保 Nginx 记录足够信息:在
server块中启用log_format并包含$request和$status,例如:log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent';
- 写一个专用 filter:
/etc/fail2ban/filter.d/admin-login.conf,内容为:[Definition] failregex = ^<host> -.*"POST /admin/login HTTP/1\.1" 401 ignoreregex =</host>
- 在
/etc/fail2ban/jail.d/admin.local中启用 jail:[admin-login] enabled = true filter = admin-login logpath = /var/log/nginx/access.log maxretry = 4 findtime = 600 bantime = 1h port = http,https
注意:logpath 必须指向实际写入登录失败记录的日志文件;若后台用 JSON 日志或写入 stderr,则需调整 failregex 或先用 awk 转成文本行。
避免误封和漏判的关键点
分布式暴力破解常来自不同 IP 轮询,单 IP 尝试次数可能压在阈值以下。光靠 maxretry 不够,得叠加行为识别:
- 启用
backend = systemd(而非默认auto)可捕获 journald 中的 PHP-FPM 错误,补全日志盲区 - 对高危路径(如
/wp-login.php)建议用recidivejail:被封过一次的 IP 再犯就永久拉黑,配置项为bantime = -1 - 务必把运维出口 IP 加进
ignoreip,否则改配置时自己把自己踢出;测试阶段先设bantime = 60,确认无误再调长 - Web 层已有 WAF(如 Cloudflare)时,
fail2ban看到的$remote_addr是 WAF 回源 IP,此时必须用X-Forwarded-For—— 需在 Nginx 中加set_real_ip_from并改failregex匹配该 header
真正难的不是写正则,而是确认日志里确实留了能区分“真实用户输错”和“脚本扫密码”的痕迹;如果后台静默失败(不返回 401,也不记日志),fail2ban 就无从下手——这时得先改应用代码,至少打点日志。










