将 client_header_timeout 设为 5–10 秒可有效防御 slowloris 类慢速头部攻击,它仅计时请求头接收过程(至\r\n\r\n),超时即返回408并立即断连,不占用后端资源;需配合 reset_timedout_connection、连接限速及缓冲区配置形成闭环防护。

将 client_header_timeout 设为 5–10 秒,是防范慢速头部攻击(如 Slowloris)最直接有效的手段。它不判断内容好坏,只严格计时——从 TCP 连接收到第一个字节起,到完整接收到 HTTP 请求头(以 \r\n\r\n 结尾)为止;超时即返回 408 并立即中断连接,不进 upstream、不占后端资源、不记 access log 中的请求行。
明确它的防护边界
这个参数专治“建了连、发一点、就停住”的头部拖延行为:
- 攻击者只发
GET /后长期不补Host:或结尾空行,Nginx 卡在解析头阶段 - 每 10–30 秒追加一个伪造 header 字段(如
User-Agent: a),人为拉长头部接收过程 - 利用默认 60 秒超时,使单个 worker 被数百个半开连接占满,真实用户无法建连
但它不管这些:
- 请求体(body)传输速度 —— 那是 client_body_timeout 的职责
- 整个请求总耗时(如大文件上传)或响应生成时间
- header 内容是否含恶意代码(SQL 注入/XSS)—— 属于 WAF 或应用层校验
- 客户端缓慢读取响应(Slow Read)—— 需靠 send_timeout 和 TCP 层配合
按业务场景推荐配置值
不能统一设成 3 秒或 60 秒,要结合链路稳定性与头部复杂度:
- 标准 Web 页面、REST API:设为 7–10 秒。现代浏览器 TLS 握手后通常 1–2 秒内发完全部 header,10 秒足以覆盖跨境或弱网场景
- 含 JWT Token、多段 Cookie 或自定义鉴权头的后台系统:可放宽至 15 秒,但必须同步检查
client_header_buffer_size和large_client_header_buffers是否足够,否则缓冲不足会触发重试,反而延长等待 - 内网直连或可信网关后置服务:可压至 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),避免因缓冲区溢出导致重复尝试和延迟误判
- 在
log_format中加入$request_time和$status,便于在 access log 中识别长期卡在 header 阶段的请求(status=408且request_time接近你设置的 timeout 值)
验证是否真正生效
别只 reload 配置,要实测行为:
- 用
curl模拟慢速 header:curl -X GET http://your-domain.com/ --limit-rate 10 -m 30
其中--limit-rate 10强制以 10 字节/秒发送,模拟分段发头;-m 30是客户端总超时,确保测试可控 - 检查 Nginx error log 是否出现类似条目:
client timed out (110: Connection timed out) while reading client request headers - 观察 access log 中是否返回
408,且$request_time值接近你设置的client_header_timeout值(例如设为 7 秒,日志中request_time显示 6.98) - 用
telnet your-site.com 80连接后,只输入GET /回车,不发 Host、不发空行,等待约设定值 +2 秒 —— 应看到连接被服务器主动关闭(非客户端超时)










