能快速识别缓存系统恶意流量特征:$request_length超长暴露穿透扫描,$content_length异常暗示Webshell上传或伪造预热,$body_bytes_sent持续为0或极小且高频即为空查风暴指纹。

直接用 log_format 配合长度类变量(如 $request_length、$body_bytes_sent、$content_length),能快速识别缓存系统面临的恶意流量特征——不是所有大请求都危险,但异常长度组合往往暴露攻击意图,比如缓存穿透扫描、恶意 payload 注入或伪造的“合法”高并发击穿请求。
关键长度变量及其攻击指向
这些变量不依赖后端响应,Nginx 在请求接收/响应发出阶段即可记录,适合做前置风控:
-
$request_length:整个 HTTP 请求(含 headers + body)字节数。缓存穿透类扫描常伴随超长随机参数(如
?id=999999999999999999999999999999),该值会明显偏离业务常态(如 >2KB) - $content_length:仅请求体大小(POST/PUT 的 body)。Webshell 上传、恶意 JSON 批量查询、伪造的缓存预热请求常在此字段体现异常(如空 body 却带 10MB content-length,或固定 8192 字节反复刷)
- $body_bytes_sent:实际发给客户端的响应体字节数。缓存击穿瞬间若数据库返回空或极小结果,但 Nginx 缓存层未命中又未写入,该值可能持续为 0 或极小(如 2、15),而请求频率极高——这是“空查风暴”的典型日志指纹
定制 log_format 捕获攻击上下文
默认 combined 格式不含这些变量,需显式扩展。推荐配置示例:
log_format cache_attack '$remote_addr [$time_local] '
'"$request" $status $request_length $content_length $body_bytes_sent '
'"$http_user_agent" "$http_referer" "$arg_key"';
说明:
- 保留
$arg_key可直观看被查缓存 key,便于定位是否在扫不存在的 key(如负数、UUID、超长数字) - 加入
$http_user_agent能识别 sqlmap、curl -v、python-requests 等工具指纹,区分人为访问与自动化攻击 - 避免记录
$request_body(需 Lua 且影响性能),靠长度+参数+UA 组合已足够触发告警
用日志命令实时筛查攻击模式
无需导入 SIEM,Linux 命令即可完成轻量级分析:
- 查“长请求+空响应”组合(疑似穿透扫描):
awk '$7 > 3000 && $9 == 0 {print $1, $4, $7, $9}' /var/log/nginx/cache-access.log | sort | uniq -c | sort -nr | head -10 - 查高频小响应(疑似击穿):
awk '$9 0 {print $1}' /var/log/nginx/cache-access.log | sort | uniq -c | sort -nr | head -20 - 查同一 key 被高频查询且响应极短(如 key 不存在):
awk '$12 != "" && $9
联动封禁与响应闭环
发现攻击 IP 后,不能只看日志:
- 用
geo+map+if动态生成黑名单,在 server 块中直接deny对应 IP 段 - 接入 fail2ban,监控上述 awk 规则命中次数,自动调用 iptables 封禁 1 小时
- 对确认为穿透的 key(如全为负数 ID),可在应用层加布隆过滤器白名单,或统一返回 400 并记录,避免穿透到 DB

















