client_header_timeout是Nginx防御Slowloris类慢速头部攻击最直接有效的参数,从首字节起计时至完整请求头(\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、不占后端资源。
按业务链路选合理值
设太短会误杀合法弱网请求,设太长等于放弃防护。应基于真实流量中请求头传输的 P99 耗时设定,而非默认 60 秒:
- 标准公网 Web 页面或 REST API:设为 7 秒。主流浏览器、curl 和 SDK 通常在 1–2 秒内发完全部 header,7 秒可覆盖跨境抖动与 CDN 中转延迟,又能拦截每 10 秒才补一个字段的扫描器
- 含 JWT Token、多段 Cookie 或 SSO 鉴权头的网关:建议 10–15 秒,但必须同步检查
client_header_buffer_size和large_client_header_buffers是否足够,否则缓冲区溢出会触发重试,反而延长等待 - 内网反代或 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 -
client_header_buffer_size 4k;+large_client_header_buffers 4 16k;:确保能容纳常见大 header(如长 Token、多 Cookie),避免因缓冲不足导致异常等待或重试
验证是否真正生效
不能只看 reload 成功,要实测行为:
- 用 curl 模拟慢速头部发送:
curl -X GET http://your-domain.com/ --limit-rate 10 -m 30(限速 10 字节/秒,总超时 30 秒) - 检查 Nginx
error.log是否出现client timed out while reading client request headers - 观察 access log 中状态码是否为 408,且
$request_time接近你设置的 timeout 值(如 6.98s),说明配置已起效 - 运行
netstat -ant | grep :80 | grep SYN_RECV,确认慢速攻击连接无法长期堆积
注意它不管什么
明确边界,避免误配或误判:
- 不管 TLS 握手慢 —— 这是
ssl_handshake_timeout的职责 - 不管请求体(body)传得慢 —— 那由
client_body_timeout控制 - 不管响应发得慢或客户端读得慢 —— 那是
send_timeout和 TCP 层配合的事 - 不管请求头内容是否含恶意代码 —— 属于 WAF 或应用层校验范畴


















