调整 client_header_timeout 是阻断慢速头部攻击(如 slowloris)最直接有效的手段,它从首字节起计时至\r\n\r\n结束,超时即返408并秒级释放资源;公网设7秒、网关10–15秒、内网3–5秒,须配套 reset_timedout_connection on、limit_conn 和缓冲区调优。

调整 client_header_timeout 是阻断慢速头部攻击(如 Slowloris)最直接有效的手段。它不依赖后端、不进 upstream,只在 Nginx 事件循环内完成“秒级裁决”:从客户端发来第一个字节起计时,到完整收到 \r\n\r\n(空行)为止;超时即返回 408 并立即断连,worker 进程、socket 句柄和内存缓冲区随之秒级释放。
按业务链路设定合理阈值
不能统一设成 3 秒或 60 秒,需结合真实链路特征与头部复杂度:
- 标准公网 Web 页面或 REST API:设为 7 秒。主流浏览器、curl 和 SDK 通常在 1–2 秒内发完全部 header;7 秒可覆盖跨境延迟、CDN 中转抖动,同时能卡住每 10 秒补一个字段的扫描器
-
含 JWT Token、多段 Cookie 或 SSO 鉴权头的网关服务:设为 10–15 秒。须先开启 access log 记录
$request_time和$status,观察 P99 头部接收耗时,再加 2–3 秒缓冲;上限不建议超过 15 秒 - 内网反代、Kubernetes Ingress 后置服务:可压至 3–5 秒。链路稳定、无 NAT、无中间检测设备,防御强度更高;但低于 3 秒易误杀老旧 IoT 设备或高丢包移动终端
必须配套的三项基础加固
单设 client_header_timeout 效果有限,需在事件循环层面形成闭环防护:
-
reset_timedout_connection on;:超时后主动发送 RST 包中断连接,跳过四次挥手,立即释放 socket 句柄和内核连接槽位,避免 TIME_WAIT 滞留 -
连接数限制:添加
limit_conn_zone $binary_remote_addr zone=perip:10m;和limit_conn perip 10;,防攻击者用多个 IP 绕过 timeout 机制 -
缓冲区匹配实际头部大小:若业务使用长 Token 或多段 Cookie,建议设为
client_header_buffer_size 4k;和large_client_header_buffers 4 16k;;否则缓冲区溢出会触发重试或异常等待,反而延长连接占用时间
验证是否真正生效
不能仅靠 nginx -s reload 成功就认为配置起效,需实测模拟慢速行为:
- 用 curl 模拟慢速头部发送:
curl -X GET http://your-domain.com/ --limit-rate 10 -m 30(限速 10 字节/秒,总超时 30 秒) - 观察是否在设定 timeout 值(如 7 秒)内返回 408,并检查 error log 是否出现
client timed out日志 - 配合 log_format 在 access log 中加入
$request_time和$status,筛选出status=408且request_time接近 timeout 值的请求,确认是头部阶段被拦截
明确它防什么、不防什么
避免误配或过度依赖:
- ✅ 防:“建了连、发 GET /、就停住”,或每 10–30 秒补一个伪造 header 字段的 Slowloris 类攻击
- ✅ 防:攻击者用小包分段发送 header,人为拉长接收时间,挤占并发连接池
-
❌ 不防:请求体(body)传输慢 → 应由
client_body_timeout控制 -
❌ 不防:客户端缓慢读响应 → 属
send_timeout范畴 -
❌ 不防:TLS 握手慢 → 必须用
ssl_handshake_timeout(Nginx 1.19.0+) - ❌ 不校验 header 内容是否含恶意字段 → 属 WAF 或应用层职责











