client_header_timeout是防御Slowloris类慢速攻击的第一道闸门,它从TCP连接建立后收到首字节起计时,至完整请求头(含\r\n\r\n)接收完毕为止,超时即断连返回408,不进upstream、不占后端资源。

client_header_timeout 是防御 Slowloris 类慢速攻击的第一道闸门。它不负责处理数据内容,只管“头有没有送完”——从 TCP 连接建立后收到第一个字节开始计时,到完整请求头(含空行 \r\n\r\n)接收完毕为止。超时即断连,返回 408 状态,不进 upstream,不占后端资源。
它到底防什么?看清 Slowloris 的破绽
Slowloris 攻击者会建一堆 TCP 连接,但每次只发一点点请求头(比如每 15 秒发一个 User-Agent: 字段),让 Nginx 一直卡在“等头部收全”的状态。默认 60 秒超时,意味着一个 worker 进程可能被几百个半开连接拖垮。client_header_timeout 就是把这扇门关紧:头不按时交齐,直接请出门。
- 不是防大文件上传,那是
client_body_timeout和client_max_body_size的事 - 不是防响应慢,那是
send_timeout和后端性能的问题 - 真正盯住的是“建了连、发了点、就不动了”的头部拖延行为
怎么设才合理?看业务再下刀
不能一味求小。设太短(如 2s)会误杀弱网用户或某些合规客户端;设太长(如 60s)等于敞开大门。关键看真实请求头抵达耗时的 P99 分位值,再加一点缓冲。
- 普通 Web 页面/REST API:建议 5–10 秒。大多数浏览器和 SDK 在毫秒级就发完头,10 秒足够覆盖高延迟移动网络
- 内网服务或可信网关后:可压到 3 秒,因链路稳定、无 NAT 或中间设备干扰
- 含大量 Cookie 或自定义头的 SSO 场景:先用
log_format记录$request_time和$status,观察正常请求头接收耗时,再定值(通常不超过 15 秒)
配合动作不能少:单靠 timeout 不够硬
timeout 是基础,但要形成防护闭环,需和其他配置咬合:
- 开启
reset_timedout_connection on;:超时后发送 RST 包而非 FIN,更快释放 socket,减少 TIME_WAIT 滞留 - 限制单 IP 初始连接数:
limit_conn addr 10;(配合limit_conn_zone $binary_remote_addr zone=addr:10m;),防攻击者用多个源 IP 扫荡 - 搭配
client_header_buffer_size和large_client_header_buffers:避免因缓冲区过小导致合法大头被截断重试,反而延长等待时间
验证是否生效?用 curl 模拟最直接
不用装工具,一条命令就能测:
curl -v --limit-rate 10 --max-time 30 -X GET http://your-domain.com/其中 --limit-rate 10 强制限速 10 字节/秒,模拟慢发头;--max-time 30 是客户端总超时,确保它不先退出。若 Nginx 配置了 client_header_timeout 5s,你大概率会在第 5–6 秒看到连接被重置,响应码为 408 或直接断连。
再查 Nginx error log,应有类似 client timed out (110: Connection timed out) while reading client request headers 的记录。


















