缓冲区限额需与超时和日志记录联动才能防御慢速攻击,单独设置无效;合理配置client_header/body_buffer_size、超时参数及error_log/access_log格式,可暴露并阻断恶意连接,留下可追溯痕迹。

缓冲区限额本身不能直接“防御”慢速攻击,但它配合超时与日志记录,能快速暴露并切断恶意连接,把攻击行为留下可追溯痕迹。关键不在限多大,而在“限额+超时+记录”三者联动。
设置合理的缓冲区上限并强制触发日志
缓冲区限额(如 client_header_buffer_size、client_body_buffer_size)的作用是控制单次内存分配上限。当请求头或请求体超出该值,Nginx 会转用临时磁盘缓存(若启用)或直接拒绝——而这个“拒绝”动作必须被明确记入错误日志,才能用于后续分析。
- 设 client_header_buffer_size 1k,large_client_header_buffers 4 2k:限制头部总大小不超过 8KB,超长请求头会被拒绝,返回 400 错误
- 设 client_body_buffer_size 128k:避免小文件上传全驻内存;超过部分写磁盘,但需确保 client_max_body_size 同步收紧(如设为 10M),防攻击者声明超大 Content-Length
- 必须开启 error_log /var/log/nginx/error.log warn:将 warning 及以上级别写入日志;超限、超时、连接重置等事件默认以 warn 或 error 级别输出
用超时参数激活缓冲区限额的防御效果
只设缓冲区不设超时,攻击者仍可缓慢填满空间,最终耗尽内存或磁盘。限额真正起效,依赖超时机制提前中止传输过程,并让错误日志记录下中断原因。
- client_header_timeout 15s:从连接建立到收完完整请求头,超过即断连,日志中出现 "client timed out" + "while reading client request headers"
- client_body_timeout 20s:开始接收请求体后,两次数据到达间隔超 20 秒即断连,日志中出现 "client timed out" + "while reading client request body"
- reset_timedout_connection on:让 Nginx 发 RST 包立即释放连接,避免 TCP 半开残留;该动作也会在 error.log 中体现为 "connection reset by peer" 类提示
增强日志字段,让错误条目自带上下文
默认 error.log 只记 IP、时间、错误类型,缺乏攻击特征。通过自定义 access_log 格式,把关键判定依据同步落库,便于关联分析。
- 在 http 块中添加:log_format defense '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_user_agent" $request_time $upstream_response_time $connection_requests $request_length';
- 在 server 块中启用:access_log /var/log/nginx/access-defense.log defense;
- 这样每条访问日志都含 $request_length(原始请求字节数)和 $request_time(处理总耗时):慢速攻击常表现为 request_length 小(如仅几百字节)、request_time 极大(>15s),且 status 多为 400/408/503
验证与定位:从错误日志里抓攻击线索
不要等服务异常才查日志。定期扫描 error.log 和 access-defense.log,能提前发现苗头。
- 查高频超时头:grep "reading client request headers" /var/log/nginx/error.log | awk '{print $3}' | sort | uniq -c | sort -nr | head -10
- 查长耗时短请求:awk '$9 > 15 && $10
- 匹配同一 IP 的多次 400+ 超时,基本可判定为 Slow Headers 攻击;若伴随大量 413(Request Entity Too Large),则可能是 Slow Body 配合伪造大 Content-Length










