$request_length 是 nginx 完整接收请求后记录的原始字节数,真实反映客户端发送的全部数据量,包括请求行、所有 header 和 body;其异常偏高且不规则分布时,往往预示 slow body 等静默攻击,会独占 worker 连接、拖慢吞吐。

$request_length 是 Nginx 在完整接收请求后立即生成的原始字节数指标,它真实反映客户端发来的全部数据量——包括请求行、所有 header(如超长 Cookie、伪造 X-Forwarded-For)、以及整个 body。当这个值异常偏高且呈现不规则分布时,往往不是业务上传行为,而是正在悄悄耗尽 worker 连接、拖慢整体吞吐的“静默型”攻击路径。
为什么不规则大体积请求会直接损耗 worker 吞吐
Worker 进程在收到完整请求前无法释放连接。一个 $request_length > 5MB 的 POST 请求,若由 Slow Body 方式分 30 秒断续发送,就会独占一个 worker 连接长达半分钟;而 Nginx 默认 worker_connections 通常为 1024,仅需 35 个此类请求并发,就可让全部连接处于“接收中”状态,新请求只能排队等待或直接超时(status=499/504)。这类损耗不触发错误码,但 $request_time 显著高于 $upstream_response_time,是典型吞吐衰减信号。
- 超长 URL + 大量 query 参数(GET 请求 $request_length > 10KB)→ 触发解析开销与缓冲区复制
- 单请求携带数百 KB 的 Cookie 或自定义 header → 绕过 client_max_body_size 限制,却填满 header buffer
- 非上传路径(如 /login、/api/v1/submit)出现 >2MB 的 POST → 基本可判定为 payload 填充试探
配置带上下文的日志格式,锁定损耗源头
必须显式启用含关键字段的日志格式,避免信息缺失:
log_format throughput_probe '$remote_addr [$time_local] "$request" $status $body_bytes_sent '
'$request_length $request_time $upstream_response_time '
'"$http_user_agent" "$http_x_forwarded_for" $host';
关键点:
- $request_length 放固定列(建议第9列),便于 awk 或日志平台按位置提取
- 同时保留 $request_time(总接收耗时)和 $upstream_response_time(转发后耗时),差值大说明卡在接收阶段
- 记录 $host 和 $http_x_forwarded_for,区分多租户或代理穿透场景
用时间窗口+分布特征识别“不规则”模式
单纯看单次长度易误判。真正威胁 worker 吞吐的是**短时高频、大小混杂、路径异常**的组合:
- 同一 IP 在 60 秒内:≥3 次 $request_length ∈ [500KB, 2MB] + ≥1 次 >5MB → 表明试探性填充已升级
- 某 URI(如 /graphql)在 5 分钟内 $request_length P95 突升 300%,但 $body_bytes_sent 中位数
- 多个不同 $host 下,相同 UA(如 curl/8.10.1)集中发起 $request_length > 1MB 的 POST → 扫描器集群特征
可用以下命令快速筛查:
awk -v now=$(date -d '1 minute ago' '+%d/%b/%Y:%H:%M') \
'$0 ~ now && $9 > 1048576 && tolower($4) ~ /post/ {print $1, $4, $7, $9}' \
/var/log/nginx/access.log | sort | uniq -c | sort -nr
结合限流与动态基线做轻量干预
日志发现只是起点,需联动 Nginx 原生能力降低 worker 压力:
- 对高风险路径(如 /login、/api/*)单独设置
client_header_buffer_size 8k; large_client_header_buffers 4 16k;,防 header 膨胀 - 用 map 构建基础拦截:
map $request_length $block_large {<br> ~^[2-9][0-9]{6,}$ 1; # ≥2MB<br> default 0;<br> }
再配合limit_req zone=bursty burst=1 nodelay;控制高频大请求速率 - 将日志中确认的恶意 IP 写入临时黑名单文件,通过 include 加载到 server 块中:
deny 192.168.3.12;
不复杂但容易忽略











