client_header_timeout的核心目标是秒级识别并切断恶意拖延连接,从首字节到达至请求头解析完成(\r\n\r\n)超时即返408,防slowloris类攻击,不防慢传体、慢读响应或tls握手慢;推荐公网设7–10秒,网关10–15秒,内网3–5秒,须配套reset_timedout_connection、连接限速及缓冲区配置。

设置 client_header_timeout 的核心目标,是让 Nginx 在请求头读取阶段就快速识别并切断恶意拖延连接,避免 worker 进程、socket 句柄和内存缓冲区被长期占用。它不靠后端配合、不等业务逻辑,纯在事件循环内做“秒级裁决”。
明确它的作用边界和触发时机
这个参数只管一件事:从 TCP 连接上收到第一个字节(含 TLS 握手完成后的首个 HTTP 字节)起,到完整解析出请求头(以 \r\n\r\n 结尾)为止的总耗时。超时即返回 408 并断连,不进 upstream、不记完整 access log、不占后端资源。
- 它防的是“建了连、发 GET /、就停住”,或每 15 秒补一个
User-Agent的 Slowloris 类攻击 - 它不防慢传 body(那是
client_body_timeout的事)、不防慢读响应(send_timeout)、也不防 TLS 握手慢(要用ssl_handshake_timeout) - 计时起点是首字节抵达,不是 TCP 握手完成时刻——所以 TLS 延迟已自然包含在内
按场景设合理阈值,兼顾防护与兼容
设太短会误杀弱网用户;设太长等于放弃防护。应参考真实流量中请求头传输的 P99 耗时,而非拍脑袋。
- 标准公网 Web 页面或 REST API:推荐 7–10 秒。覆盖浏览器、curl、主流 SDK 的正常行为,也能拦截每 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 -
缓冲区匹配实际头部大小:如业务使用长 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 秒),防止客户端复用连接时刚发完头就被断开 -
send_timeout控制响应发送间隔,一般设为 10–30 秒,避免长连接空等











