client_body_timeout是两次TCP数据包间的最大空闲时间,非总上传时限;合理设置需匹配业务:API设15–25s、文件上传设300s(配body大小限制)、移动端设60s;须组合client_body_buffer_size、limit_conn、proxy_read_timeout等协同防御。

client_body_timeout 不是“整个上传耗时上限”,而是“两次 TCP 数据包之间允许的最大空闲时间”。这个细节决定它能否真正防住慢速 POST 攻击。
慢速 POST 攻击是怎么利用 client_body_timeout 的
攻击者建立连接后,只发一个 POST 请求头,然后以极低速率(比如每 30 秒发 1 字节)断续发送请求体。如果 client_body_timeout 设为 60s,Nginx 就会一直等待下一段数据,直到超时才释放连接——期间 worker 进程被长期占用,无法服务其他请求。
这种攻击成本极低,但能快速耗尽可用连接数,尤其在未调优的默认配置(60s)下效果显著。
如何设置 client_body_timeout 才算合理
关键不是一味压低数值,而是匹配真实业务节奏,同时留出安全余量:
- 纯 API 接口(JSON 提交,无大文件):设为 15–25s。正常客户端在 TLS 握手、DNS 解析、应用层处理后,10s 内基本完成 body 发送
- 含文件上传的管理后台(如 CMS 表单):设为 300s(5 分钟),但必须配合 client_max_body_size 限制上传上限(例如 100MB),防止攻击者用超大 body 拖长总耗时
- 移动端 App 接口:统一设为 60s,兼顾弱网重传和中间代理延迟,避免因网络抖动误杀合法请求
- 绝对不要设为 0 或过短(如 1–2s),否则会导致 408 频发,尤其在高延迟或丢包链路上
仅靠 client_body_timeout 不够,必须组合防御
单一参数无法彻底解决慢速 POST,需搭配以下配置形成闭环:
- 启用 request body 缓冲:设置 client_body_buffer_size(如 128k)和 client_max_body_size,让小请求体直接进内存,减少磁盘写入开销和等待依赖
- 限制单 IP 连接数:用 limit_conn zone=perip 10; 防止单个 IP 占满所有 worker_connections
- 开启连接限制日志:配合 log_format 定义 $request_time、$upstream_response_time、$status,便于识别长时间卡在 body 阶段的异常连接
- 反向代理场景下同步调优 proxy_read_timeout:避免 Nginx 等待后端响应时又被拖住,该值应略大于后端 P95 处理时长(建议加 20% 余量)
验证是否生效的实操方法
用 curl 模拟慢速 body 发送,观察是否在预期时间内断连:
curl -X POST http://your-domain.com/api --data-binary @/dev/zero --limit-rate 100 -m 60
其中 --limit-rate 100 控制发送速率为 100B/s,-m 60 是客户端总超时。若 Nginx 的 client_body_timeout 为 30s,你大概率会在 30–35s 收到 408 响应,说明配置已起作用。
再查 error.log,确认出现类似 *1023 client timed out (110: Connection timed out) while reading client request body 的日志条目。











