nginx可通过配置专用日志格式和location捕获401响应来记录认证失败事件:定义含$sent_http_www_authenticate的日志格式,在启用auth_basic的location中指定access_log写入独立文件,从而精准记录ip、时间、请求、realm等信息。

Nginx 本身不直接记录“认证失败原因”(比如用户名错还是密码错),但可以通过合理配置日志格式和 location 区域,把所有返回 401 的请求单独捕获并记录为认证失败事件,这是最实用、最可靠的做法。
关键点是:让 Nginx 把 Basic Auth 拒绝响应(HTTP 401)明确写入专用日志文件,而不是混在普通 access.log 里。
✅ 配置专用日志格式,突出认证上下文
在 http 块中定义一个专用于认证失败的日志格式:
log_format auth_fail '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'auth="$sent_http_www_authenticate"';
其中 $sent_http_www_authenticate 是关键变量:Nginx 在返回 401 时会自动设置该响应头(如 Basic realm="Admin Area"),记录它能帮助区分是 Basic Auth 拒绝,而非其他 401 场景。
✅ 在受保护的 location 中启用该日志
比如你的登录接口或管理后台路径是 /admin 或 /login,且启用了 auth_basic:
location /admin {
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
access_log /var/log/nginx/auth_fail.log auth_fail;
}
这样,只要用户访问 /admin 且认证失败(输入错误凭据),Nginx 就会返回 401,并把整条请求完整记入 auth_fail.log —— 包含 IP、时间、请求行、状态码、User-Agent 和认证 Realm 信息。
⚠️ 注意:access_log 必须放在 auth_basic 同一 location 内;如果写在 server 级别,会记录所有请求,无法精准过滤失败认证。
✅ 补充建议:避免日志污染
- 不要依赖
$remote_user判断是否失败(它在失败时为空,不可靠); - 不要用
if ($status = 401)做条件日志(Nginx 的if在log_by_lua_block外不可用,且access_log if=不支持$status); - 若使用反向代理或 CDN,记得用
$http_x_forwarded_for或map提取真实客户端 IP,否则日志里的$remote_addr可能是代理地址。
✅ 后续怎么用这些日志?
有了 auth_fail.log,你就能:
- 用
grep " 401 " /var/log/nginx/auth_fail.log | awk '{print $1}' | sort | uniq -c | sort -nr统计高频攻击 IP; - 配合 fail2ban 实时封禁;
- 推送到 ELK 或 Grafana 做失败趋势看板;
- 设置定时脚本扫描,发现异常峰值就发企业微信/邮件告警。
不复杂但容易忽略。











