client_body_timeout 控制 Nginx 读取客户端请求体时两次数据包到达的最大间隔时间,超时即返回 408;它不管总上传时长或请求头,仅约束 body 数据流节奏,默认 60 秒需根据场景调低防慢速攻击。

client_body_timeout 是什么,它管上传的哪一段
client_body_timeout 控制的是 Nginx 读取客户端 HTTP 请求体(即 POST/PUT 的 body)过程中,两次连续数据包到达之间的最大等待时间。它不作用于请求头,也不管整个上传耗时,只盯住「数据流是否还在稳定进来」。一旦某次接收完一块数据后,超过该值没收到下一块,Nginx 就直接关闭连接,返回 408 Request Timeout。
常见误解是它能限制总上传时长——其实不能。client_max_body_size 管大小,client_body_timeout 管节奏。慢速上传攻击(如 Slowloris 变种)正是靠极低速率发 body 数据,让连接长期卡在读 body 阶段,占满 worker 连接数。
默认值太宽松,生产环境必须调低
默认 client_body_timeout 是 60 秒,对正常用户上传大文件影响不大,但对防御慢速攻击几乎无效。攻击者只要每 59 秒发一个字节,就能无限续命。
- Web 表单提交(JSON / form-data):建议设为
10s~20s,浏览器和主流 SDK 都能稳过 - 移动端 API 上传(小图、日志):
15s足够,网络抖动容忍度已留余量 - 真正的大文件上传(>10MB):不要依赖这个参数控时,改用
proxy_read_timeout+ 后端流式处理,或前端分片上传 - 若后端是 PHP-FPM 或 uWSGI,还需同步检查其对应的读超时(如
request_terminate_timeout),否则 Nginx 断了,后端还挂着
和 client_header_timeout、send_timeout 别混用
这三个 timeout 各守一段链路,错配会导致诡异失败:
-
client_header_timeout:只管请求头(包括 method、path、headers),通常设10s即可。header 极短,不应拖太久 -
client_body_timeout:只管 body 数据块间隔,如上所述 -
send_timeout:管 Nginx 向客户端发响应时的写空闲超时,和上传无关,别误调它来“防上传” - 如果
client_header_timeoutclient_body_timeout,可能 header 没收全就超时,body 根本没机会开始传
典型安全组合:client_header_timeout 10s;,client_body_timeout 15s;,send_timeout 30s;
验证是否生效:抓包 + 错误日志双看
光改配置不验证,等于没调。重点确认两件事:
- 错误日志里出现
client timed out (110: Connection timed out) while reading client request body,说明触发了client_body_timeout - 用
tcpdump抓包,模拟慢速上传(例如用curl --limit-rate 10发一个大 body),观察连接是否在预期时间后被 RST - 注意:如果启用了
proxy_buffering off或后端是长连接协议(如 gRPC),client_body_timeout可能被绕过,此时需在 proxy 层或后端设等效保护
真实攻击中,攻击流量往往夹杂在正常请求里,client_body_timeout 是第一道节奏过滤器,但它无法识别伪造 User-Agent 或合法但恶意的分块上传逻辑——那得靠 WAF 或应用层校验。


















