client_body_timeout只控制两次发包间空闲超时,不控总上传时长;设10–15s防API慢速POST,后台上传可设300s但须配client_max_body_size等协同防御。

client_body_timeout 不是用来限制“上传花了多久”,而是卡在“两次发包之间空等了多久”。它真正起效的场景,是客户端已发完 HTTP 头、开始传请求体后,突然停住不发数据——Nginx 就在这段静默期倒计时,超时即断连并返回 408 Request Timeout。响应挂起,本质是 worker 进程被这类连接长期占住,无法处理新请求。
它防什么、什么时候开始计时
这个参数只在以下条件全部满足时才启动计时:
- 请求头已完整接收(含
Content-Length或Transfer-Encoding: chunked) - 头尾之间有空行,且客户端已开始发送 body 数据
- Nginx 等待下一段 TCP 数据包的到来——不是从第一个字节算总时间,而是盯“上一段和下一段之间隔了多久”
攻击者正是利用这点:发完 POST /api 和头后就卡住;或每 25 秒才发一个字节。若你设为 60s,Nginx 就会傻等满 60 秒才释放连接,期间该 worker 无法服务其他请求。
按业务类型设合理值
统一设成 5s 或 60s 都容易出问题。关键看真实传输节奏和网络容忍度:
- 纯 API 接口(JSON 提交、无文件):10–15 秒。浏览器或主流 SDK 通常 1–3 秒内就开始发 body,留出余量防偶发延迟
-
管理后台文件上传(如 CMS 表单):300 秒(5 分钟),但必须同步配置
client_max_body_size 100m,否则攻击者可声明大体积却极慢发送,耗尽缓冲或磁盘空间 - 移动端接口(含图片/语音):60–120 秒。弱网切网、App 休眠唤醒易造成短暂中断,过短会导致大量误杀
- 流式或分片上传接口:设为 60 秒即可,但需由业务层约定心跳机制(如每 30 秒发一次分片头或保活包),否则仍会被断
单靠它完全无效,必须组合防御
慢速 POST 是链式攻击,只调 client_body_timeout 相当于锁门不关窗:
-
配
client_header_timeout 10s:防攻击者只发POST /就停住,卡在 header 阶段不进 body 流程 -
开
reset_timedout_connection on:超时后直接发 RST 包,立刻回收 socket 句柄,避免堆积 TIME_WAIT -
设
client_max_body_size合理上限:超出直接返回 413,不走 timeout 流程;API 建议 10–20M,后台可放宽至 100–200M -
用
limit_conn perip 10:限制单 IP 并发连接数,防止攻击者开几百个慢连接打满 worker_connections -
反向代理场景下,
proxy_read_timeout要略大于后端 P95 响应时间(建议 +20%):避免 Nginx 卡在等后端时又被拖住
验证是否真生效
别只看配置写了没,要实测:
- 用
curl -X POST http://host/api --data-binary @/dev/zero --limit-rate 50 -m 60模拟慢速发送(每秒 50 字节),观察是否在设定值附近返回 408 - 查 Nginx error log,确认出现
client timed out (110: Connection timed out) while reading client request body - 用
ss -i或tcpdump观察连接是否在超时后被 RST 中断,而非自然 FIN 关闭

















