适用场景
本文面向安全运维工程师、应急响应人员和DevOps团队,讲解如何通过Nginx日志攻击溯源发现入侵痕迹。当服务器疑似被入侵或网站出现异常时,Nginx access.log是最先需要分析的线索来源。本文提供从日志采集到攻击还原的完整方法论和可执行命令。
前置条件
- Linux服务器,Nginx 1.10+ 已启用 access.log(默认路径
/var/log/nginx/access.log) - 具备awk、grep、sort、uniq等基础Linux命令操作能力
- 建议安装GoAccess或ELK Stack进行可视化分析(非必需)
- 建议开启Nginx自定义日志格式以包含更多攻击特征
原理说明
Nginx access.log记录了每一次HTTP请求的完整元数据:来源IP、请求时间、请求方法、URL路径、HTTP状态码、User-Agent、Referer等。攻击溯源就是通过关联分析这些日志字段,还原攻击者的攻击链(Kill Chain):侦察→扫描→利用→提权→横向移动。常见的攻击溯源场景包括:WebShell访问痕迹、扫描器探测行为、暴力破解尝试、SQL注入Payload记录、文件包含尝试等。
操作步骤
第一步:配置增强日志格式
默认的combined日志格式缺少关键信息。在 /etc/nginx/nginx.conf 中启用自定义格式:
http {
# 增强日志格式 — 包含请求体大小、上游响应时间、TLS版本
log_format attack_trace '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time '
'$ssl_protocol $ssl_cipher';
access_log /var/log/nginx/access.log attack_trace;
}
重载Nginx:nginx -t && systemctl reload nginx
第二步:攻击特征快速筛查命令库
以下命令可直接复制到服务器执行:
1. 查找最常见的攻击IP:
# 查看访问量TOP 20的IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# 查看返回404最多的IP(扫描器特征)
awk '$9 == 404 {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
2. 检测恶意扫描行为:
# 查找疑似SQL注入的请求
grep -iE "(union.*select|select.*from|or+1=1|--|%27)" /var/log/nginx/access.log | head -50
# 查找路径遍历尝试
grep -iE "(\.\./|\.\.\|/etc/passwd|/proc/self)" /var/log/nginx/access.log | head -50
# 查找WebShell访问尝试
grep -iE "(cmd|exec|shell|eval|passthru|system)\.(php|asp|aspx|jsp)" /var/log/nginx/access.log | head -50
3. 分���HTTP状态码异常:
# 状态码分布统计
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# 查找403(WAF拦截)最多的IP
awk '$9 == 403 {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
4. 检测爆破行为:
# 查找登录接口(wp-login.php)的频繁访问
grep "wp-login" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -10
# 查找POST请求(表单提交)最多的IP
awk '$6 == "\"POST"' /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -10
5. 分析User-Agent异常:
# 查看所有User-Agent分布
awk -F'"' '{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -30
# 查找已知恶意工具的特征
grep -iE "(sqlmap|nikto|nmap|masscan|acunetix|nessus|openvas|python-requests|curl|wget)" \
/var/log/nginx/access.log | awk '{print $1}' | sort -u
第三步:时间线攻击还原
通过时间维度还原攻击过程:
# 按小时统计攻击频率
awk '{print $4}' /var/log/nginx/access.log | cut -d: -f1-2 | sort | uniq -c | sort -rn
# 提取特定IP的完整访问序列(攻击时间线)
grep "203.0.113.42" /var/log/nginx/access.log | awk '{print $4, $6, $7, $9}' | head -100
第四步:自动化攻击溯源脚本
#!/bin/bash
# /usr/local/bin/attack_trace.sh — 一键攻击溯源报告
LOG="/var/log/nginx/access.log"
REPORT="/tmp/attack_report_$(date +%Y%m%d).txt"
echo "=== 攻击溯源报告 $(date) ===" > $REPORT
echo "" >> $REPORT
echo "--- 异常IP Top 10 (基于404) ---" >> $REPORT
awk '$9 == 404 {print $1}' $LOG | sort | uniq -c | sort -rn | head -10 >> $REPORT
echo "" >> $REPORT
echo "--- 疑似SQL注入请求 ---" >> $REPORT
grep -ciE "(union.*select|or+1=1|%27)" $LOG >> $REPORT
echo "条SQL注入特征请求被记录" >> $REPORT
echo "" >> $REPORT
echo "--- 扫描器User-Agent ---" >> $REPORT
grep -ciE "(sqlmap|nikto|acunetix|nessus)" $LOG >> $REPORT
echo "条扫描器请求" >> $REPORT
echo "" >> $REPORT
echo "--- 爆破尝试统计 ---" >> $REPORT
grep -c "wp-login" $LOG >> $REPORT
echo "次wp-login.php访问" >> $REPORT
echo "报告已生成:$REPORT"
添加执行权限并设置定时任务:
chmod +x /usr/local/bin/attack_trace.sh
# 每天凌晨2点生成报告
echo "0 2 * * * root /usr/local/bin/attack_trace.sh" >> /etc/crontab
配置验证
# 1. 检查Nginx日志格式是否正确生效
tail -1 /var/log/nginx/access.log | awk '{print NF}'
# 输出应包含9+个字段(含ssl_protocol等扩展字段)
# 2. 运行一键溯源报告
bash /usr/local/bin/attack_trace.sh
cat /tmp/attack_report_$(date +%Y%m%d).txt
# 3. 模拟攻击特征后验证检测结果
curl -v "http://yourdomain.com/user?id=1%27%20OR%201=1"
# 再次运行报告,确认SQL注入记录数已增加
常见问题
Q1:日志文件过大(GB级别),直接grep太慢怎么办?
推荐三种方案:(1)使用 ngxtop 实时分析工具;(2)部署GoAccess进行二进制级快速解析:goaccess /var/log/nginx/access.log -o report.html;(3)将日志接入ELK或Loki进行全文索引。如果只是应急响应,先用 tail -n 100000 截取最近10万行再分析。
Q2:攻击者使用代理/CDN,access.log中只有CDN节点IP怎么办?
启用 realip 模块获取真实客户端IP:(1)在Nginx编译时添加 --with-http_realip_module;(2)配置 set_real_ip_from CDN_CIDR; real_ip_header X-Forwarded-For;;(3)如果CDN本身不传递X-Forwarded-For,需联系CDN开通XFF透传或查看CDN日志中的源IP字段。
总结
Nginx日志攻击溯源是安全应急响应的基本功。通过增强日志格式、建立常用分析命令库、自动化报告生成,可以将数小时的排查工作压缩到分钟级别。关键要点:配置符合安全需求的日志格式、建立标准化的分析流程(异常IP→异常状态码→异常请求模式→时间线还原)、定期生成溯源报告。建议将上述命令和脚本纳入运维人员的应急响应手册(SOP),形成常态化安全巡检机制。