能防网站扫描,但需手动配置监控nginx日志并定义敏感路径扫描规则,否则默认仅防护ssh/ftp,对web扫描无反应。

Fail2ban 能不能防网站扫描?能,但默认不防
Fail2ban 默认只监控 /var/log/secure 或 /var/log/auth.log,也就是 SSH、FTP 这类服务的登录日志。它根本不会看你的 Nginx 日志,所以哪怕有人用工具扫 /wp-admin/、/phpmyadmin/、/.git/,Fail2ban 也完全没反应。
想让它防网站扫描,必须手动告诉它:去读 /www/wwwlogs/access.log,并且定义“什么样的请求算恶意”。这一步漏掉,装了等于白装。
- 宝塔面板里安装 Fail2ban 后,默认只启用了
[sshd]和[ftpd],[nginx-http-auth]和自定义的站点防护规则都是关闭状态 - 别直接改
/etc/fail2ban/jail.conf—— 更新时会被覆盖;要改就改/etc/fail2ban/jail.local或/etc/fail2ban/jail.d/下的新文件 - CentOS 系统日志路径是
/var/log/secure,Ubuntu/Debian 是/var/log/auth.log,写错会导致规则完全不生效
怎么写一条真正有效的防扫描规则?
核心不是“封 404 多的 IP”,而是“封高频扫敏感路径的 IP”。因为正常用户点错链接也会 404,但攻击者会连续请求几十个管理后台路径,这才是特征。
一个实用的过滤器示例(存为 /etc/fail2ban/filter.d/nginx-scan.conf):
[Definition] failregex = ^<host> -.*"(GET|HEAD).*(/phpmyadmin|/wp-admin|/administrator|/\.git|/\.env|/backup\.zip).*HTTP.*$ ignoreregex =</host>
然后在 jail.local 里启用它:
[nginx-scan] enabled = true filter = nginx-scan logpath = /www/wwwlogs/access.log maxretry = 3 findtime = 60 bantime = 86400 port = http,https
-
maxretry = 3是合理的起点:扫三个高危路径就封,既灵敏又不易误伤 -
findtime = 60表示“1 分钟内”,比默认的 10 分钟更能卡住自动化扫描节奏 - 注意
logpath必须和你实际站点日志路径一致;多站点共用一个日志?没问题;分站日志?得为每个站单独配logpath
封了 IP,怎么确认它真被拦住了?
Fail2ban 封 IP 是通过调用系统防火墙(iptables/firewalld/ufw)实现的,不是改 Nginx 配置。所以不能靠“刷新网页看 403”来验证,得查底层规则。
执行这条命令,看有没有刚封的 IP 出现在输出里:
sudo iptables -L f2b-nginx-scan -n
如果返回 Chain f2b-nginx-scan (1 references) 加一堆 REJECT 行,说明生效了。如果报错 No chain/target/match by that name,大概率是服务没重启,或者 jail 名拼错了。
- 每次修改
jail.local或 filter 文件后,必须运行sudo fail2ban-client reload,不是 restart - 封禁记录存在
/var/log/fail2ban.log,搜Ban关键字就能看到谁被封、为什么封 - 宝塔面板里的 Fail2ban 插件界面,“已封禁 IP”列表只显示当前活跃封禁,过期的不会留痕 —— 别指望它当审计日志用
为什么开了 Fail2ban 还被扫得满屏日志?
常见原因是:规则太宽泛,或触发条件太松,导致大量低频扫描逃过检测;更常见的是——压根没配 Nginx 日志监控,只防了 SSH,结果网站天天被扫,你还以为“安全了”。
另一个隐蔽坑:Nginx 日志格式必须含真实客户端 IP。如果你用了 CDN(比如 Cloudflare),默认 $remote_addr 记的是 CDN 节点 IP,所有请求看起来都来自几个固定地址,Fail2ban 封了也没用。
- 确保 Nginx 配置里启用了
realip模块,并正确设置了set_real_ip_from和real_ip_header X-Forwarded-For - 检查日志是否真有攻击者 IP:用
tail -n 50 /www/wwwlogs/access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -5看访问最多的前 5 个 IP - 封禁时长设太短(比如 1 小时)对持续性扫描意义不大;设太长(比如永久)又怕误伤,
bantime = 86400(24 小时)是较平衡的选择










