nginx 通过增强日志格式(含 $http_x_forwarded_for、$http_referer 等字段)并结合实时分析(如高频404、非常规ua、异常http方法),可精准记录与追踪恶意访问源;再通过多维关联(ip、ua、referer、地理信息、时间规律)及轻量自动化(bash+sqlite)实现闭环追踪与告警。

Nginx 本身不主动“识别”恶意访问,但通过合理配置日志记录 + 后续分析手段,完全可以精准记录并有效追踪恶意访问源。关键在于:让日志包含足够线索,再用结构化方式提取、聚合、告警。
日志格式要带关键字段
默认的 combined 格式已含 IP、时间、URL、状态码、User-Agent 等基础信息,但为提升追踪能力,建议补充以下字段:
-
$http_x_forwarded_for:真实客户端 IP(尤其在有 CDN 或反向代理时) -
$http_referer:来源页面,可发现扫描器跳转链或黑帽 SEO 流量 -
$request_time和$upstream_response_time:区分是慢速攻击还是后端瓶颈 -
$body_bytes_sent:结合状态码判断是否成功下载敏感文件(如.env、wp-config.php) - (可选)JSON 格式输出:便于 ELK 或 Prometheus 直接解析
示例增强型日志格式:
log_format extended '{"time":"$time_iso8601",'
'"ip":"$remote_addr",'
'"xff":"$http_x_forwarded_for",'
'"host":"$host",'
'"url":"$request_uri",'
'"status":"$status",'
'"ua":"$http_user_agent",'
'"ref":"$http_referer",'
'"req_time":$request_time,'
'"bytes":$body_bytes_sent}';
access_log /var/log/nginx/access.log extended;
实时记录高频异常行为
仅记录不够,需让可疑行为“浮出水面”:
-
大量 404 请求:可能是目录爆破或漏洞探测
awk '$9 == "404" {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20 -
非常规 User-Agent:如
sqlmap,nikto,gobuster,masscan, 或空 UA、纯数字 UAgrep -E '(sqlmap|nikto|gobuster|masscan|curl.*libwww|Wget)' /var/log/nginx/access.log
-
高频率低耗时请求:同一 IP 在 1 分钟内请求超 100 次且平均
request_time ,大概率是自动化工具# 提取最近 60 秒的 IP 访问频次(需日志含精确时间) awk -v d="$(date -d '1 minute ago' '+%d/%b/%Y:%H:%M')" '$4 ~ d {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10 -
异常 HTTP 方法:
PUT、DELETE、TRACE、OPTIONS在非 API 接口大量出现awk '$6 ~ /"(PUT|DELETE|TRACE|OPTIONS)/ {print $1, $6}' /var/log/nginx/access.log | head -10
追踪源头需关联多维信息
单看 IP 容易误判(如 NAT 网关、CDN 节点),应交叉验证:
- 对比
$remote_addr与$http_x_forwarded_for:若后者存在且不为空,优先采信后者(需 Nginx 前置可信代理,并配置set_real_ip_from) - 查看
User-Agent+Referer组合:例如Mozilla/5.0 (compatible; Baiduspider)但Referer为空或为钓鱼域名,即存疑 - 结合地理信息:用
geoip2模块或离线库(如geoiplookup)标记非常规地区批量请求(如某非洲小国 IP 一小时扫你全部 WordPress 路径) - 时间规律性:凌晨 2–4 点集中请求,且 URL 带
/phpmyadmin/,/wp-login.php,/admin/,基本可判定为暴力探测
自动化追踪与落库(轻量级方案)
无需上 ELK,一个 Bash + SQLite 就能实现闭环:
- 每 5 分钟执行脚本,提取 TOP 10 异常 IP,写入
malicious_ips.db,附带首次出现时间、总请求数、404 比例、UA 样本 - 下次扫描时比对:若该 IP 72 小时内重复触发,自动加入
deny列表并 reload Nginx - 同时发邮件告警,内容含:IP 归属地(调用
ipapi.co免费接口)、最近 3 条原始日志行、关联的 URL 模式
这样既保留原始证据,又形成可回溯的攻击画像。
不复杂但容易忽略











