防范超大头部请求攻击需控制内存分配:设 client_header_buffer_size 2k 和 large_client_header_buffers 4 8k,总上限32KB;关闭 proxy_request_buffering 和 proxy_buffering;systemd 设 MemoryLimit;用 map 统计异常头长并限流。

巧用 Nginx 内存池预分配机制防范超大头部请求攻击,关键不是“禁用”或“硬挡”,而是让内存分配可控、可预期、不被滥用。Nginx 本身没有传统缓冲区溢出漏洞,但攻击者通过构造超长 User-Agent、伪造的 Cookie、嵌套的 X-Forwarded-For 或恶意 JWT 头,可迫使每个连接预占远超正常所需的内存,最终触发 OOM Killer 杀进程或拖垮服务。
精准控制请求头缓冲区大小
这是最直接有效的防线——在解析阶段就截断,避免进入内存处理流程:
-
client_header_buffer_size 2k;:设为 2KB,覆盖绝大多数标准请求头(含常见鉴权与追踪头) -
large_client_header_buffers 4 8k;:允许最多 4 个大头缓冲区,单个上限 8KB,总头缓冲上限 32KB - 两者相加即为单个连接最大可接受头体积;超出即返回 400 错误,不进 worker 内存池
关闭隐式内存放大行为
某些默认配置会让 Nginx 在反向代理场景中重复读取请求体,导致同一份数据被多次载入内存池:
- 显式关闭代理层二次缓存:
proxy_request_buffering off;(Nginx 1.16+) - 配合
proxy_buffering off;,避免 body 被 proxy buffer + client buffer 双重持有 - 上游启用 keepalive:
upstream backend { keepalive 200; },减少连接重建带来的缓冲开销
绑定系统级内存约束
即使 Nginx 配置合理,失控的 worker 进程仍可能因累积异常请求耗尽 RSS 内存:
- 用
systemd启动时设置MemoryLimit=1G等硬限制,防止单个 worker 溢出拖垮整机 - 开启
open_file_cache_errors on;,快速释放因头过大导致的无效文件句柄,避免 fd 泄漏间接推高内存 - 监控
nginx_process_resident_memory_bytes指标,当某 worker RSS 持续 > 300MB 且请求头平均长度突增,大概率存在头部攻击
配合请求准入层做兜底识别
单纯靠大小限制不够,还需识别异常模式:
- 用
map指令提取并统计请求头长度:map $request_length $header_len { ~^(?<h>.{1000,}) $h; default ""; }</h>,再结合日志分析 - 对高频出现超长
User-Agent或含可疑 Base64/JWT 片段的请求 IP,自动加入limit_conn黑名单 zone - 在 WAF 或前置 LB 层对
Host、Referer等字段做正则过滤,拦截明显畸形头(如含换行符、NUL 字节)


















