nginx暴力破解攻击可通过日志中高频失败请求快速识别:集中登录路径、大量401/403状态码、固定ip短时密集访问;需配置real_ip还原真实客户端ip,用map标记可疑请求并接入fail2ban自动封禁。

直接看 Nginx 访问日志就能发现暴力破解攻击,关键不是等出事再翻,而是让日志里“高频失败请求”一眼可见——集中在登录路径、大量 401/403 状态码、固定 IP、短时间密集发包。
确保日志含真实 IP 和关键字段
如果服务器前面有 CDN 或反向代理(比如 Nginx 自身做代理),$remote_addr 可能是内网地址(如 10.x.x.x),必须还原真实客户端 IP:
- 在 http 块中配置:set_real_ip_from 10.0.0.0/8;(按实际代理网段调整)
- 指定头字段:real_ip_header X-Forwarded-For;
- 日志格式至少包含:$remote_addr(或 $http_x_forwarded_for)、$request_uri、$status、$request_method、$http_user_agent
从日志快速定位暴力破解特征
暴力破解不是随机乱扫,它有典型行为模式,用一行 awk 就能筛出来:
- 集中打登录接口:匹配 /login、/auth、/wp-login.php、/api/v1/login 等路径
- 状态码高度集中为 401(未认证)或 403(禁止访问),极少返回 200
- 同一 IP 在 5 分钟内出现 ≥10 次上述组合
- 常见命令示例(查最近 5 分钟):
awk -v d="$(date -d '5 minutes ago' '+%d/%b/%Y:%H:%M')" '$4 ~ d && $7 ~ /\/(login|auth|wp-login\.php)/ && $9 ~ /^40[13]$/ {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr
用 map 模块标记并隔离可疑请求
不一定要立刻封禁,先在 Nginx 内部做轻量识别和限流,避免误伤:
- 定义标记规则(放在 http 块):
map $request_uri $is_login_path { ~*\/(login|auth|wp-login\.php) 1; default 0; }
map $status $is_auth_fail { ~^40[13]$ 1; default 0; } - 组合判断并写入独立日志:
log_format brute '"$remote_addr" "$request_uri" $status $time_local "$http_user_agent"';
access_log /var/log/nginx/brute.log brute if=$is_login_path$if=$is_auth_fail; - 后续可对 /var/log/nginx/brute.log 单独分析或接入 fail2ban
推荐自动封禁方案:Fail2ban + 自定义 filter
手动封 IP 效率低且不可持续,Fail2ban 是生产环境首选:
- 新建 filter:/etc/fail2ban/filter.d/nginx-bruteforce.conf,正则匹配登录路径 + 401/403
- 在 jail.local 中启用:
[nginx-bruteforce]
enabled = true
filter = nginx-bruteforce
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 600
bantime = 3600 - 重启后执行 fail2ban-client status nginx-bruteforce 查看实时拦截情况











