client_body_timeout需按业务场景分设:API接口10–15s、文件上传后台300s、弱网移动端60–120s、流式上传60s,并须配合client_header_timeout、reset_timedout_connection、client_max_body_size等参数协同防御。

要让 client_body_timeout 在网关层真正扛住慢速 POST 攻击,关键不是设一个“看起来很短”的数字,而是让它在不误杀合法请求的前提下,快速释放被恶意拖住的连接资源。
明确它的作用边界:只管“空闲间隔”,不管“总上传时长”
这个参数控制的是客户端发送请求体过程中,两次 TCP 数据包之间的最大等待时间。比如设为 15s,意味着:
- 客户端发完第一个数据块后,15 秒内没发下一块,Nginx 就断连并返回 408
- 哪怕整个请求体声明有 100MB,已传了 99MB,只要最后 1MB 的某两段之间隔了 16 秒,照样超时
- 它不负责限制上传总耗时——那是
client_max_body_size、后端处理能力与网络质量共同决定的
按业务类型分场景设值,避免一刀切
统一设成 5s 或 60s 都容易出问题。合理取值需兼顾真实传输节奏和攻击拦截效率:
- 纯 API 接口(JSON 提交、无文件):建议 10–15s。正常客户端在完成 TLS 握手、DNS 解析和前端序列化后,通常 2–5 秒内就能发出完整 body
- 含文件上传的后台系统(如 CMS、OA 表单):可设为 300s(5 分钟),但必须同步配置
client_max_body_size 100M,防止攻击者用超大声明+极慢发送耗尽缓冲区 - 移动端接口(尤其弱网环境):建议 60–120s。网络切换、休眠唤醒、代理重传都可能导致短暂中断,过严会引发大量重试和失败
- 流式上传或分片上传接口:设为 60s 即可,但要求客户端按约定频率(如每 30 秒)发送心跳数据或分片头,否则仍会被断
必须组合其他参数,单点无效
client_body_timeout 是防御链条中的一环,脱离上下文就形同虚设:
- 配
client_header_timeout 10s:防攻击者卡在头部阶段不发 body,形成双阶段防护 - 开
reset_timedout_connection on:超时后发 RST 而非 FIN,立即回收 socket 句柄,避免堆积 TIME_WAIT - 设
client_max_body_size合理上限:超出直接 413 拦截,不进 timeout 流程;例如 API 设 10M,管理后台设 200M - 调
client_body_buffer_size匹配常见体大小:小接口用 128k,大上传用 2m~4m,避免频繁落盘又不过度占内存 - 加
limit_conn perip 10:限制单 IP 并发连接数,防止攻击者开几百个慢连接打满 worker_connections
验证是否真起效,别只看配置写了没
上线前务必实测,最简单方式是用 curl 模拟慢速行为:
curl -X POST http://your-gateway.com/api --data-binary @/dev/zero --limit-rate 50 -m 120
其中 --limit-rate 50 表示每秒只发 50 字节,-m 120 是客户端总超时。观察 Nginx access log 是否在约 client_body_timeout 值附近返回 408,同时 error log 出现 "client timed out" 提示。再配合 $request_time 和 $status 字段做日志分析,确认超时确实发生在 body 阶段而非后端响应阶段。

















