应改造nginx access_log为结构化json格式,包含真实ip、敏感路径标识、目标id等字段,并结合error_log联动分析,才能系统化识别sql注入、路径遍历等攻击行为。

直接用 access_log 查攻击痕迹,靠命令行能快速定位多数异常,但想系统化识别 SQL 注入、路径遍历、暴力扫描等行为,得搭配结构化日志格式 + 分析工具链。关键不是“有没有工具”,而是日志能不能支撑分析——原始 combined 格式太模糊,字段缺失、IP 不真实、无法标记风险动作,再强的工具也难挖出有效线索。
先让 access_log 可分析:四步改日志格式
默认日志不带真实客户端 IP、没请求意图标识、URL 混着参数、状态码孤立存在,分析时只能靠猜。必须重定义 log_format:
- 用 $realip_remote_addr 替代 $remote_addr,并配 set_real_ip_from,确保 CDN 或反向代理后仍能拿到真实攻击源 IP
- 用 map 指令预标高危行为,比如匹配 /admin/、/api/v1/users、/wp-login.php 等路径,生成 $is_sensitive 字段值为 1
- 对含 ID 的 URL(如 /api/v1/posts/123),用正则捕获数字部分存为 $target_id;对登录请求,提取 $arg_username 而非记录明文密码
- 输出为 JSON 格式,字段清晰可解析:log_format json '{ "@timestamp": "$time_iso8601", "clientip": "$realip_remote_addr", "method": "$request_method", "uri": "$uri", "status": $status, "ua": "$http_user_agent", "is_sensitive": $is_sensitive, "target_id": "$target_id" }';
轻量排查:几条命令揪出典型攻击特征
不用上 Hadoop 或 ELK,日常巡检用 shell 就能发现 80% 的可疑行为:
使用tbot机器ID身份文件配合tsh CLI,通过Teleport访问控制SSH登录托管主机或执行远程命令。
- 查高频探测 IP:统计 5 分钟内访问 404 超 30 次的 IP,大概率是目录爆破或漏洞扫描
awk -v d="$(date -d '5 minutes ago' +'%d/%b/%Y:%H:%M')"' '$4 > "["d && $9 == "404" {print $1}' /var/log/nginx/access.json | sort | uniq -c | sort -nr | head -10 - 找 SQL 注入痕迹:匹配常见 payload 特征,如 %27%20OR、union select、information_schema
grep -E "(%27%20OR|union[[:space:]]+select|information_schema)" /var/log/nginx/access.json - 盯越权访问:同一 clientip 在 1 分钟内访问了 5 个以上不同 $target_id,且路径属于 /api/v1/users/、/api/v1/orders/ 等资源接口
awk '$12 != "" && $12 ~ /^[0-9]+$/ {a[$1,$12]++} END {for (i in a) if (a[i] > 5) print i}' /var/log/nginx/access.json | cut -d' ' -f1 | sort | uniq -c | sort -nr
进阶分析:用现成工具做规则化检测
手动 grep 终究覆盖有限。推荐两类实用方案:
- 脚本化快筛:用 Python 或 Bash 写轻量检测脚本,内置规则库(如检测 /etc/passwd、/proc/self/environ、.git/config 等敏感路径访问),支持读取 JSON 日志并输出带时间戳的攻击摘要,适合应急响应
- 可视化流水线:部署开箱即用的 Nginx 安全日志分析系统(如基于 Hadoop + Node.js 的方案),自动完成采集→正则匹配(SQLi/XSS/路径遍历)→IP 风险评分→前端看板展示。它不只告诉你“有攻击”,还会标出攻击频率、地域热力、高频 UA、关联 Referer,真正把日志变成情报
联动 error_log 提升判断准确率
access_log 告诉你“谁在敲门”,error_log 告诉你“门有没有被撞开”。两者结合才能确认是否成功利用:
- 当 access_log 中某 IP 大量请求 /phpinfo.php,同时 error_log 出现 open() "/var/www/html/phpinfo.php" failed (2: No such file or directory),说明是试探性扫描
- 若同一 IP 在 access_log 中触发 200 状态码访问 /wp-config.php,而 error_log 记录 PHP Warning: include(/wp-config.php): failed to open stream,极可能已读取到配置文件内容
- 建议用 request_id 或时间戳范围(误差控制在 3 秒内)做两日志关联,避免误判时间漂移










