408状态码本身不表示攻击,但集中异常出现往往是慢速HTTP攻击信号,需结合IP频率、请求头特征、超时时间及连接模式综合识别与拦截。

408 状态码本身不表示攻击,但当它在日志中集中、异常地出现时,很可能是慢速 HTTP 攻击(如 Slowloris)的信号。关键不是“有没有 408”,而是“谁在什么条件下反复触发 408”。识别和拦截需结合日志特征、时间模式与上下文行为,而非单看状态码。
看来源 IP 是否高频且低质量
真实用户偶发 408 可能因弱网或中断,但攻击者会批量建连、只发零星头部、长期卡住。排查时重点关注:
- 同一 IP 在 1 分钟内触发 ≥5 次 408,且 user_agent 为空、为爬虫标识(如 python-requests、curl)、或高度雷同
- 该 IP 的请求 无 referer、无 cookie、URI 固定(如全为 / 或 /favicon.ico)
- 连接建立后,仅发送少量字节(如 20–100 字节),且间隔规律(如每 10–15 秒发一行头)
查请求头接收耗时是否远超正常值
Nginx 默认 client_header_timeout 60s,但健康请求头通常在毫秒级完成。若日志中开启 $request_time 和 $upstream_response_time,可比对:
- 408 请求的 $request_time 接近或等于 client_header_timeout 值(如 9.98s / 10s),说明卡在等头部收全
- $upstream_response_time 为 “-” 或极小(如 0.000),证明请求根本没发到后端——这是 Slow headers 的典型特征
- 用 log_format 加入
$time_iso8601 $remote_addr "$request" $status $bytes_sent $request_time,再用 awk/grep 快速聚合分析
盯住连接生命周期异常模式
慢速攻击的本质是“长连接+低流量”,要从连接维度抓异常:
- 检查 Nginx error.log 中是否频繁出现 "client timed out while waiting for request" —— 这是 client_header_timeout 触发的明确提示
- 对比 access.log 中该 IP 的 连接复用情况:大量短连接(connection: close)或无 keep-alive 头,但又密集建连
- 若使用了
limit_conn,观察是否频繁 hit limit_conn zone 的 reject 记录;若未启用,此时正是加限的好时机
配合配置快速拦截,不止于识别
识别只是第一步,必须闭环动作才能真正防御:
-
收紧超时:将
client_header_timeout设为 5–10s(普通站)或 3s(内网/可信链路),比默认 60s 更早关门 - 强制 RST 断连:
reset_timedout_connection on;,避免 FIN-WAIT 状态堆积 - 限制初始连接:
limit_conn_zone $binary_remote_addr zone=perip:10m;+limit_conn perip 10;,防单 IP 扫荡 - 缓冲区匹配:
client_header_buffer_size 1k;+large_client_header_buffers 4 2k;,避免合法大头被截断重试反而延长等待

















