通过分析Nginx访问日志中request_time明显大于upstream_response_time、高频408状态码、upstream_addr为空等异常组合,可早于告警发现Slowloris攻击;需自定义日志格式并结合error.log中的client timed out记录验证。

直接看访问日志里那些“请求头收得慢、连接空转久、响应拖得怪”的请求模式,比等告警更早发现 Slowloris 类攻击。
盯紧 request_time 和 upstream_response_time 的时间差
Slowloris 不靠大流量,而是让连接卡在 Nginx 层不动。关键线索就藏在这两个字段的异常组合里:
- request_time 明显大于 upstream_response_time(例如 6.8s vs 0.015s):说明请求压根没发完头或体,Nginx 一直在等,后端完全没收到请求;
- 同一 IP 在 2 分钟内多次出现 request_time > 4s 且状态码是 408 或 200/404:408 是 Nginx 主动超时断连,200/404 则可能是攻击者刚好卡在超时前发完,伪装正常;
- upstream_response_time 接近 0,但 $upstream_addr 字段为空或缺失:进一步确认请求根本没走到后端。
筛查低频但高风险的请求行为
攻击者为绕过监控,常把 Slowloris 拆成单次/分钟级请求,但日志中仍有固定痕迹:
- 用命令快速抓出可疑请求:awk '$NF > 4 {print $1, $4, $7, $9, $NF}' /var/log/nginx/access.log | head -20(假设 $NF 是 request_time);
- 筛选长时间空闲连接:awk '$7 ~ /GET|POST/ && $9 == 408 {print $1, $4}' /var/log/nginx/access.log | sort | uniq -c | sort -nr;
- 检查是否集中于特定路径(如 /login、/api),同时 User-Agent 为空或为 “-”、“python-requests” 等非浏览器标识。
结合 error.log 验证超时类型
access.log 只告诉你“慢”,error.log 才告诉你“为什么慢”:
- 搜索 client timed out:对应 client_header_timeout 或 client_body_timeout 触发,是 Slow Headers / Slow Body 的铁证;
- 搜索 upstream timed out:说明问题在后端,不是 Slowloris;
- 搜索 no live upstreams 或 connection refused:排除后端宕机干扰,聚焦连接层问题。
配置日志格式确保能查到关键字段
默认 combined 格式不含时间字段,必须自定义:
- 在 nginx.conf 中添加:log_format attacklog '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time $upstream_response_time $upstream_addr';
- 然后在 server 块中启用:access_log /var/log/nginx/attack.log attacklog;
- 务必包含 $request_time 和 $upstream_response_time,这是判断责任边界的唯一依据。


















