client_header_timeout和client_body_timeout协同防御慢速攻击:前者限制请求头接收时长(建议15–30秒),后者限制请求体分块间空闲时间(建议12–25秒),二者独立计时、任一超时即断连,配合keepalive_timeout等参数形成分层防护闭环。

这两个超时参数不是独立起作用的,而是配合 HTTP 请求生命周期分阶段卡住慢速攻击者。
client_header_timeout 控制请求头接收窗口
它定义服务器等待客户端发完全部 HTTP 头部(直到遇到两个连续 \r\n)的最长时间。Slow headers 攻击正是靠每秒只发一个字节的 Header 数据,长期悬停在“未收完头”的状态,把连接卡在 reading 阶段。
建议值:一般设为 15–30 秒。政务、金融类接口可压到 10 秒;若业务含大表单或需动态协商头部(如部分 OAuth 流程),不建议低于 8 秒。
关键细节:
- 超时后 Nginx 主动断开连接,不记录 access log,不触发 limit_req 或 limit_conn 计数
- 该超时仅作用于 TCP 连接建立后、首个请求的头部接收阶段,不影响 keepalive 复用连接后的后续请求
- 与 client_max_body_size 无直接关联,但若攻击者伪造极大 Content-Length 却不发 Body,header 阶段仍会先被此参数截断
client_body_timeout 控制请求体接收节奏
它约束的是:头部接收完成后,服务器等待客户端发送请求体(比如 POST 数据、文件上传块)每个数据块之间的最大空闲时间。Slow body 攻击就靠这个间隙——发完头,然后每 10 秒才传一个字节,让连接长期滞留在 reading + reqreading 状态。
建议值:通常设为 12–25 秒。API 类服务推荐 15 秒;含大文件上传的后台管理页,可设为 20 秒并搭配 client_body_buffer_size 和 client_max_body_size 分层控制。
注意点:
- 不是整个 Body 的总上传时限,而是“两次 recv() 调用之间”的间隔上限
- 超时触发后返回 408 Request Timeout,会记入 access log,且已占用的 connection 和 request slot 不会立即释放,需依赖 keepalive_timeout 收尾
- 若使用 proxy_pass,该超时只管 Nginx 到客户端这一段,不影响 Nginx 到 upstream 的读写行为
两者如何异步联动形成防御闭环
它们分别守住请求流程的两个“易卡点”,攻击者很难同时绕过:
- 想用 Slow headers?client_header_timeout 在十几秒内就断掉,连接根本进不了路由匹配和限流逻辑
- 想跳过头、直冲 Body?Nginx 会先等 header 完成,再启动 body 计时器;一旦 header 超时,body 阶段压根不会开始
- 想混用(比如头发得快、体发得慢)?两个 timer 独立运行,任一超时即终止,无需等待对方
- 真实用户极少触达这些阈值——浏览器发完 header 通常在毫秒级,上传 Body 也基本保持持续流速;而攻击工具必须人为拉长间隔才能耗资源,反而暴露自身
配套必须启用的参数
单设这两个 timeout 不够,需同步收紧连接生命周期:
- keepalive_timeout 建议 ≤ 30 秒(默认 75 秒太宽松),防止慢速复用连接持续占位
- reset_timedout_connection on 开启后,超时连接会被主动 reset,比 close 更快释放 fd 和内存
- 配合 limit_conn 和 limit_req,确保即使有少量漏网连接,也无法突破并发与频率红线










