精准记录401/403风险指纹需定制log_format(含$remote_addr、$status、$http_authorization等关键字段),限定location作用域,并用log_by_lua_block补充后端X-Auth-Error头,实现轻量、准确、低开销的风险日志采集。

要精准记录遭遇 401(未认证)和 403(已认证但无权限)拦截的客户端风险指纹,关键不是“过滤日志”,而是从源头定制日志格式 + 精确作用于触发这两类状态的上下文。Nginx 本身不判断业务逻辑,但它能可靠捕获响应状态码和请求元数据——只要配置得当,就能把真正可疑的访问行为单独、清晰地落盘。
明确日志目标字段:只留关键风险指纹
401/403 请求的核心风险特征是:IP 地址、请求时间、URI 路径、HTTP 方法、User-Agent、Referer,以及是否携带有效凭证(如 Token 头或 Basic Auth 用户名)。不需要记录成功响应的 body 或 cookie,避免日志膨胀。
推荐的精简日志格式定义如下:
log_format auth_risk '$remote_addr $time_iso8601 "$request" $status $request_length ' '"$http_user_agent" "$http_referer" ' '"$http_authorization" "$http_x_forwarded_for"';
-
$remote_addr:真实客户端 IP(若经代理,需确保real_ip模块已启用并配置set_real_ip_from) -
$http_authorization:可快速识别是否尝试了 Basic Auth 或 Bearer Token,为空则大概率是未认证裸请求 -
$http_x_forwarded_for:辅助验证代理链路,防止伪造 IP - 省略
$body_bytes_sent等非风险相关字段,降低 I/O 压力
限定作用范围:只对高风险路径启用该格式
全局开启会浪费资源。应只在认证入口、权限校验接口、管理后台路径等位置启用该日志格式,例如:
location /api/auth/login {
access_log /var/log/nginx/401_403_risk.log auth_risk;
# 其他 auth 相关配置
}
location /admin/ {
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
access_log /var/log/nginx/401_403_risk.log auth_risk;
}
- 这样,只有落到这些 location 的请求才写入
401_403_risk.log,天然隔离噪音 - 注意:Basic Auth 触发 401 时,
$remote_user为空;而 Spring Security 等后端返回的 401/403,则需确保 Nginx 能透传状态码(不被 upstream 错误页覆盖) - 若使用 JWT,建议在后端统一返回
X-Auth-Status: failed类响应头,Nginx 可通过$sent_http_x_auth_status进一步增强日志区分度
增强准确性:用 log_by_lua_block 补充上下文
纯 Nginx 变量无法获取后端返回的自定义错误原因(比如 “token expired” 或 “insufficient role”)。可通过 OpenResty 的 log_by_lua_block 在日志阶段读取响应头或 body 片段:
location /api/v1/ {
proxy_pass http://backend;
access_log /var/log/nginx/401_403_risk.log auth_risk;
log_by_lua_block {
local res = ngx.var.upstream_http_x_auth_error or ""
if res ~= "" then
ngx.log(ngx.INFO, "RISK: ", ngx.var.remote_addr, " -> ", res)
end
}
}
- 前提是后端在 401/403 响应中设置
X-Auth-Error头,例如X-Auth-Error: invalid_token - 该方式不增加请求延迟,仅在日志阶段执行,适合轻量补充风险归因
后续分析建议:日志即告警入口
生成的 401_403_risk.log 不是终点,而是风险分析起点:
- 用
awk '/ 40[13] / {print $1}'快速提取高频攻击 IP - 配合 fail2ban,规则匹配
^([0-9.]+) .*"POST /login.* 401即刻封禁 - 导入 ELK 或 Loki,按
http_authorization是否为空区分暴力破解(空 Auth)与越权探测(有 Token 但被拒)


















