fail2ban与nginx日志集成防爬虫的核心是精准识别异常扫描行为(如低ua、高404、集中扫敏感路径),而非泛化封禁高频访问;需确保日志含真实ip、状态码、路径及ua,自定义failregex匹配工具ua或敏感路径404,并设maxretry=3、findtime=60、bantime=7200实现分钟级精准封禁。

Fail2Ban 与 Nginx 日志集成防爬虫,核心不是封“所有高频访问”,而是精准识别异常扫描行为——比如低 UA、高 404、集中扫敏感路径等。它不替代限速(如 limit_req),而是作为日志层的“事后清剿”,专打绕过前端防护的顽固爬虫。
确保 Nginx 日志能暴露爬虫特征
Fail2Ban 只能从日志里“看”行为,日志没记录,它就无从判断。
- 日志格式必须含:真实客户端 IP(非 CDN 节点)、HTTP 状态码、请求路径、User-Agent
log_format crawler '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; access_log /var/log/nginx/access.log crawler; - 若用 CDN(Cloudflare/宝塔CDN),必须启用
real_ip模块还原真实 IP:
在http{}块中添加:set_real_ip_from 103.21.244.0/22; # Cloudflare IPv4 网段示例,按实际填 real_ip_header CF-Connecting-IP; # 或 X-Forwarded-For
- 宝塔用户:网站 → 设置 → 配置修改 → 勾选「获取真实 IP」
编写针对爬虫的 Fail2Ban 过滤器
默认规则对爬虫无效,需自定义匹配特征。新建 /etc/fail2ban/filter.d/nginx-crawler.conf:
[Definition]
failregex = ^<host> -.*"(GET|HEAD) /(\.env|\.git/config|backup\.zip|wp-config\.php|phpmyadmin) HTTP.*" 404
^<host> -.*"Mozilla/5.0.*python-requests|curl|wget|sqlmap|nmap|masscan.*" .*" 200
^<host> -.*"(GET|HEAD) /.*.(php|asp|jsp|exe|sh|pl) HTTP.*" 404
ignoreregex = ^<host> -.*"/health" | ^<host> -.*"Googlebot|BingBot|YandexBot"</host></host></host></host></host>
说明:
- 第一行匹配扫敏感文件返回 404(
.env、wp-config.php等) - 第二行匹配工具类 UA(
sqlmap、nmap、python-requests)发的 200 请求 -
ignoreregex排除健康检查和主流搜索引擎,避免误封
配置 Jail 规则并控制触发强度
在 /etc/fail2ban/jail.d/crawler.local 中添加:
[nginx-crawler] enabled = true filter = nginx-crawler logpath = /var/log/nginx/access.log maxretry = 3 findtime = 60 bantime = 7200 action = iptables-multiport[name=nginx-crawler, port="http,https"]
关键参数含义:
-
maxretry = 3:1 分钟内触发 3 次匹配即封(爬虫试探通常密集) -
findtime = 60:时间窗口设为 60 秒,比爆破更短,适应扫描节奏 -
bantime = 7200:封禁 2 小时,足够打断自动化脚本周期 -
action限定只封 HTTP/HTTPS 端口,不影响 SSH 或数据库连接
验证与上线前检查
- 测试正则是否生效:
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-crawler.conf
- 重启并查看状态:
sudo systemctl restart fail2ban sudo fail2ban-client status nginx-crawler
- 手动模拟一次扫描(如
curl -A "sqlmap/1.0" http://yoursite/.env),再查是否被 ban:sudo fail2ban-client get nginx-crawler banned
不复杂但容易忽略











