识别异常访问需从Nginx日志提取$remote_addr、$status、$request_time、$request、$http_user_agent、$http_referer等字段,结合awk命令实时筛查高频、异常状态、可疑UA等行为并干预。

识别并限制异常访问,关键在于从日志中抓出行为特征,再用 Nginx 原生模块做实时干预——不靠 WAF 也能快速响应。
盯住这几个核心日志字段
确保 access_log 包含以下变量,它们是判断异常的基础:
-
$remote_addr:真实客户端 IP(若走 CDN 或代理,必须配置
set_real_ip_from+real_ip_header X-Forwarded-For还原) - $status:HTTP 状态码,重点关注 403、404、429、503 这类非正常响应
- $request_time:请求耗时,极短(如 10s)都可能异常
-
$request:完整请求行,用于匹配敏感路径(如
/wp-login.php)、编码字符(%2e%2e%2f)、SQL/XSS 关键字 -
$http_user_agent:UA 为空、含
curl、python-requests、masscan、nmap等非浏览器标识 -
$http_referer:为空或为无效地址(如
http://0.0.0.0、http://127.0.0.1)
用命令快速筛出可疑 IP
直接在 /var/log/nginx/access.log 上执行,无需安装额外工具:
- 1 分钟内请求超 30 次的 IP:
awk -v d="$(date -d '1 minute ago' '+%d/%b/%Y:%H:%M')" '$4 > "["d":00" && $4 - 高频访问敏感路径(如登录接口):
awk '$7 ~ /\/login|\/api\/auth|\/admin/ {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -5 - 大量返回 404 的扫描行为:
awk '$9 == 404 {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10 - UA 异常 + 无 Referer 的组合:
awk '$12 ~ /curl|python-requests|Go-http-client/ && $11 == "-" {print $0}' /var/log/nginx/access.log | head -10
用 limit_req 按行为限流
不是封整个 IP,而是对高危动作做速率控制,兼顾防护与可用性:
- 在
http块定义按 IP+路径维度的限流区:limit_req_zone $binary_remote_addr$uri zone=scan_limit:10m rate=2r/m; - 对常见扫描路径加保护:
location ~ ^/(wp-admin|phpmyadmin|\.git|\.env|api/.*login) { limit_req zone=scan_limit burst=3 nodelay; } - 单独限制登录接口频次:
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;,再在location = /login中调用 - 若需区分已登录用户,可用
$cookie_session_id替代 IP,避免误伤
配合 fail2ban 实现自动封禁
手动封 IP 难持续,fail2ban 能监听日志、触发 iptables 封禁,并支持自定义规则:
- 新建 filter:
/etc/fail2ban/filter.d/nginx-scan.conf,正则匹配 UA + 404 + 敏感路径组合 - 在
jail.local中启用该 jail,设置maxretry = 5(10 分钟内)、bantime = 3600 - 重启服务后,用
fail2ban-client status nginx-scan查看拦截状态 - 封禁生效后,从目标 IP curl 测试应超时或返回 403,且日志中不再出现该 IP 请求


















