跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

实战讲解 Nginx client_body_timeout 调优:有效识别并防御慢速 POST 攻击

client_body_timeout是两次TCP数据包间的最大空闲时间,非总上传时限;合理设置需匹配业务:API设15–25s、文件上传设300s(配body大小限制)、移动端设60s;须组合client_body_buffer_size、limit_conn、proxy_read_timeout等协同防御。 client_body_timeout 不是用来限制大文件上传总时长的,设成 300s 并不能让 2GB 文件稳稳传完——它只管“两次发包之间空等多久”,超时就直接断连、返回 408。 client_body_timeout 是什么,不是什么 它监听的是 TCP 数据流中两个有效数据包之间的最大空闲间隔。一旦客户端开始发 body(比如 POST 的第一字节),Nginx 就启动这个计时器;下一段数据没在
client_body_timeout
内到达,连接立即关闭。 它不控制: 整个请求头+body 的总耗时(那是
client_header_timeout
+
client_body_timeout
分段叠加) 后端处理时间(那是
proxy_read_timeout
的事) 文件落盘或缓冲区大小(那是
client_body_buffer_size
和
client_max_body_size
管的) 典型误用:把
client_body_timeout
设为 600s 想“支持大上传”,结果攻击者每 59 秒发 1 字节,照样拖满 worker 连接池。 不同业务场景下怎么设才不误杀也不放行 关键看真实客户端的数据节奏,而不是文件体积本身: 纯 JSON API(无附件):
client_body_timeout 15s
。正常浏览器/APP 在 TLS 握手、DNS 解析后,10 秒内必发完 body CMS 后台表单(含图片 Base64 或小文件):
client_body_timeout 60s
,配合
client_max_body_size 20M
管理后台文件上传(支持百 MB):
client_body_timeout 300s
,但必须加
client_max_body_size 100M
,否则攻击者声明
Content-Length: 10G
就能卡住内存缓冲区 移动端接口(含语音/图片):
client_body_timeout 60s
,网络抖动常见,低于 30s 容易触发批量 408 绝对不要设为
0
或
1s
—— 丢包重传、NAT 超时、中间代理缓存都会导致合法请求被截断。 Nginx 在宝塔面板中轻松管理Nginx高性能Web服务器。提供可视化配置反向代理、负载均衡、SSL证书及HTTP缓存功能,一键优化高并发性能,助您高效搭建稳定、快速的网站运行环境。 下载 单设 client_body_timeout 为什么防不住慢速攻击 它只是防御链上的一环,缺了其他配置,等于只关了一扇窗却留着三扇门: 没调
client_header_timeout
?攻击者可以只发
POST /
就停住,卡在 header 阶段,
client_body_timeout
根本不触发 没配
limit_conn
?一个 IP 开 500 个慢连接,worker_connections 直接打满,新请求全进不了队列 没开
reset_timedout_connection on
?超时后只发 FIN,系统要等四次挥手完成才释放 socket,TIME_WAIT 堆积更快
client_body_buffer_size
设得过大(如 16M)?每个慢连接都占满一块内存,几百个就 OOM 推荐最小闭环组合:
client_header_timeout 15s
+
client_body_timeout 15s
+
reset_timedout_connection on
+
limit_conn perip 10
+
client_max_body_size 20M
。 怎么验证它真正在起作用 别只看配置 reload 成功,用 curl 模拟慢速行为最直接:
curl -X POST http://localhost/api \ -H "Content-Type: application/json" \ --data-binary '{"key":"value"}' \ --limit-rate 50 \ -m 120
其中
--limit-rate 50
强制以 50B/s 发送,若你设了
client_body_timeout 10s
,大概第 10–15 秒就会收到 408;同时检查 Nginx error log 是否出现
client timed out (110: Connection timed out) while reading client request body
。 真正容易被忽略的是:这个超时判断发生在内核 TCP 层收包之后、Nginx 用户态读取之前。如果系统 net.ipv4.tcp_fin_timeout 太短,或中间有 LVS/F5 等设备做了连接复用,实际表现可能和预期偏差较大——得结合 tcpdump 抓包确认 FIN/RST 是否由 Nginx 主动发出。

相关文章