最轻量可靠的初步识别手段是用 log_format 记录 $request_length,需搭配 $request_method、$content_length、$status、$http_user_agent、$remote_addr 和 $time_local 等字段以区分合法上传与恶意攻击,并结合业务设定 request_length 合理阈值进行监控。

直接用 log_format 记录 $request_length 是最轻量、最可靠的初步识别手段,尤其适合定位异常大的 POST 攻击包。关键不在“记录”,而在“设计日志结构 + 设置合理阈值 + 关联上下文字段”。
在 log_format 中显式包含 request_length 和关键辅助字段
仅记录 $request_length 不够,必须搭配能说明请求性质的字段,否则无法区分是合法大文件上传还是恶意攻击。推荐基础组合:
-
$request_length:整个请求(含 headers + body)原始字节数,真实反映客户端发送数据量 -
$request_method:确认是否为 POST -
$content_length:Header 中声明的 body 长度,与$request_length对比可判断 header 是否被伪造或 body 是否被截断 -
$status:快速过滤出失败响应(如 400、413),这些往往是缓冲区拒绝的直接结果 -
$http_user_agent和$remote_addr:用于聚类分析来源,识别扫描器或 bot 特征 -
$time_local:保留时间精度,便于关联错误日志或监控曲线
示例配置:
log_format attack_detect '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $content_length';设置业务可接受的 request_length 上限并监控偏离
没有绝对“异常”,只有相对业务不合理。先明确你系统允许的最大合法 POST 包大小:
- 普通表单提交:通常
- 图片上传接口:可能 5–20MB,取决于业务限制
- API 批量导入:可能 50–100MB,但应有明确文档和鉴权
在 Nginx 配置中通过 client_max_body_size 主动设限(例如 client_max_body_size 20m;),再结合日志,筛选出 $request_length > 25m 的条目——这类请求大概率未进业务逻辑,已被 Nginx 拦截返回 413,但其原始包长仍会记入 $request_length,正是攻击特征。
用日志分析快速定位攻击模式
将 access log 接入 ELK、Loki 或 SLS 后,可用如下查询逻辑聚焦问题:
- 查超大 POST:
request_method:"POST" and request_length > 30000000(30MB) - 查高频小包+大包混合:
remote_addr: "192.168.1.100" | stats count() by request_length | sort request_length desc,看是否存在大量集中在某几个异常长度的请求簇 - 查空响应+大请求:
request_length > 5000000 and body_bytes_sent == 0 and status == 400,典型 header 泛洪或畸形 body 导致 400 Bad Request,但客户端已发巨量数据
注意:若需获取实际 POST body 内容做深度检测(如 SQL 注入特征),需启用 ngx_http_lua_module 并在 log_by_lua_block 中读取 ngx.var.request_body,但务必同步调大 client_body_buffer_size 和 client_max_body_size,且仅限调试环境短期开启,生产慎用——有性能与隐私风险。
关联错误日志确认是否触发缓冲区保护机制
当发现大量高 $request_length 请求时,立刻检查 Nginx error log:
- 出现
client intended to send too large body→ 确认client_max_body_size是否过小,或攻击者正试探上限 - 出现
request header or cookie too large→ 攻击可能集中在超长 Cookie 或自定义 Header,需检查large_client_header_buffers - 同一 IP 短时间内大量 400/413 → 可直接配合
limit_req拦截,无需等业务层处理

















