nginx需通过自定义log_format、map映射状态码与拦截原因、条件access_log及error_log联动,将return/deny/限流等拦截行为显式记录为可分析日志,并结合fail2ban实现自动封禁。

访问日志本身不直接记录“被拦截的请求”,因为 Nginx 默认只记录成功进入处理流程(即未被 return、deny 或限流模块丢弃)的请求。要让安全策略调整有据可依,关键在于**把拦截行为显式落地为可分析的日志条目**——这需要组合使用日志格式定制、条件记录和响应状态码标记。
用自定义日志格式标记拦截动作
在 http 块中定义一个带拦截标识的日志格式,例如:
log_format security '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" "$blocked_reason"';
其中 $blocked_reason 是一个自定义变量,需配合 map 指令动态赋值:
map $status $blocked_reason {
403 "ip_deny_or_auth_failed";
405 "method_not_allowed";
429 "rate_limit_exceeded";
default "-";
}
然后在 server 或 location 块中启用该日志:
access_log /var/log/nginx/security.log security;
让限流和拒绝规则产生可识别日志
Nginx 的 limit_req 和 deny 默认返回 503/403,但不区分原因。可通过以下方式增强可追溯性:
- 对敏感路径(如
/admin、/api)单独配置access_log,并搭配if或map标记来源 - 用
error_log记录拒绝事件:在location中添加error_log /var/log/nginx/deny.log notice;,配合deny all;时会写入拒绝 IP 和时间 - 将限流触发也映射为日志字段:扩展上面的
map,加入limit_req触发判断(需结合$limit变量或自定义变量逻辑)
过滤并聚合高危请求特征
安全日志的价值在于快速识别攻击模式。建议在日志中重点捕获以下字段并定期分析:
-
异常 User-Agent:如
sqlmap、nmap、curl -v等工具指纹,可用map提取并标记为ua_suspicious -
可疑查询参数:如含
union select、javascript:、onerror=的$args,可设if判断并写入$attack_type - 高频失败请求:同一 IP 在短时间内大量 403/429,是暴力探测或扫描迹象,适合用日志分析工具(如 GoAccess、ELK)做 IP 统计
与 Fail2Ban 等工具联动
仅靠日志无法自动响应。推荐将安全日志作为 Fail2Ban 的输入源:
- 配置 Fail2Ban 的
filter,匹配security.log中的"rate_limit_exceeded"或"ip_deny" - 设置
action自动更新iptables或 Nginx 的deny列表(通过 include 文件热重载) - 这样日志既是审计依据,也是自动化封禁的触发器











