client_header_timeout是Nginx防御慢速头部攻击的核心参数,从首字节起计时至完整请求头接收完毕(\r\n\r\n),超时即断连返回408,不进upstream、不占后端资源;专治分段发头、拖延发头行为,推荐公网设7–10秒,内网3–5秒,并须配reset_timedout_connection on等协同配置。

client_header_timeout 是 Nginx 防御慢速头部攻击(如 Slowloris)最直接有效的手段,它不处理内容、不转发请求,只做一件事:从客户端发来第一个字节起计时,到完整收到 HTTP 请求头(以 \r\n\r\n 结尾)为止;超时即断连并返回 408,不进 upstream、不占后端资源、不记 access log 中的请求行。
这个参数专治“建了连接、只发 GET /、就停住”或“每 10–30 秒补一个伪造 header”的行为,能快速释放被恶意拖延占用的 worker 进程、socket 句柄和内存缓冲区。
它防什么、不防什么
-
防
- TCP 连接建立后,迟迟不发完请求头(如缺 Host:、缺空行)
- 攻击者用多个小包分段发送 header,人为拉长接收时间
-
不防
- 请求体(body)传输慢 → 交给
client_body_timeout - 响应发送慢或客户端读得慢 → 交给
send_timeout - 长连接空闲等待 → 由
keepalive_timeout控制 - 头部内容是否含恶意代码 → 属于 WAF 或应用层职责
- 请求体(body)传输慢 → 交给
推荐配置值(按场景)
标准公网 Web 页面、REST API:设为 7–10 秒
现代浏览器和主流 SDK 通常在 1–3 秒内完成 header 发送,10 秒可覆盖跨境延迟、CDN 抖动,又能拦截每 10 秒才发一次字段的扫描器含 JWT Token、多段 Cookie 或 SSO 头的鉴权网关:设为 10–15 秒
必须同步检查client_header_buffer_size和large_client_header_buffers是否足够,否则缓冲不足会触发重试,反而延长等待内网直连或可信网关后置服务:可压至 3–5 秒
链路稳定、无 NAT 和中间设备干扰,防御强度更高不建议低于 3 秒
老旧 IoT 设备、高丢包移动网络、合规终端可能出现合法头部延迟,过短易误杀
必须配套的关键配置
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;
-
协同其他 timeout 参数
-
client_body_timeout应 ≥client_header_timeout(尤其含Expect: 100-continue的请求) -
keepalive_timeout建议略大于client_header_timeout(如设为 75 秒),防止客户端复用连接时刚发完头就被断开
-
验证是否生效
-
用 telnet 手动模拟:
telnet your-domain.com 80 GET / HTTP/1.1
不输入 Host:、不发空行,等待几秒后观察连接是否被服务器主动关闭
-
或用 curl 限速模拟慢速 header:
curl -X GET http://your-domain.com/ --limit-rate 10 -m 30
检查 error log 是否出现
client timed out while reading client request headers,且状态码为 408
不复杂但容易忽略










