Nginx记录$ssl_client_verify需启用ssl_verify_client on/optional、配置ssl_client_certificate指向可信CA,并在log_format中结构化包含该变量及$ssl_client_s_dn等关联字段,配合error_log warn级日志实现完整mTLS审计。

要在 Nginx 中通过 log_format 记录 $ssl_client_verify 结果,实现对 TLS 双向认证(mTLS)失败事件的审计,关键在于:正确启用客户端证书验证、确保变量在日志上下文中可用、并用结构化方式记录验证状态及失败原因。
确认 SSL 双向认证已启用且配置正确
Nginx 必须实际执行客户端证书验证,$ssl_client_verify 才会有有效值(如 SUCCESS、FAILED:reason、NONE)。仅配置 ssl_client_certificate 和 ssl_verify_client 不够,还需注意:
-
ssl_verify_client必须设为on或optional(optional_no_ca不触发完整验证,不推荐用于审计) -
ssl_client_certificate指向受信任的 CA 证书(PEM 格式),用于验证客户端证书签名链 - 若使用
optional,Nginx 仍会尝试验证,即使客户端未提供证书,此时$ssl_client_verify为NONE,也属于可审计的“未认证”情形
定义包含 $ssl_client_verify 的自定义日志格式
在 http 块中定义日志格式,显式包含 $ssl_client_verify,并建议补充关联字段便于溯源:
log_format mtls_audit '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_user_agent" "$http_referer" '
'ssl_client_verify="$ssl_client_verify" '
'ssl_client_cert_subject="$ssl_client_s_dn" '
'ssl_client_cert_issuer="$ssl_client_i_dn" '
'ssl_protocol="$ssl_protocol" ssl_cipher="$ssl_cipher"';
说明:
-
$ssl_client_s_dn和$ssl_client_i_dn分别记录客户端证书的主题与签发者(DN),即使验证失败也会存在(只要客户端发送了证书) - 搭配
$ssl_protocol和$ssl_cipher可辅助判断是否因协议/加密套件不兼容导致握手异常(虽不直接导致 verify 失败,但属前置环节) - 避免仅记录
$ssl_client_verify单一字段,否则难以区分是证书过期、CA 不信任、还是客户端根本没送证书
将日志格式应用到 server 或 location,并启用 error_log 辅助定位
在启用 mTLS 的 server 块中指定访问日志:
server {
listen 443 ssl;
ssl_certificate /path/to/server.crt;
ssl_certificate_key /path/to/server.key;
ssl_client_certificate /path/to/trusted-ca.crt;
ssl_verify_client on;
<pre class="brush:php;toolbar:false;">access_log /var/log/nginx/mtls-audit.log mtls_audit;
error_log /var/log/nginx/mtls-error.log warn;
# …
}
同时开启 error_log 并设为 warn 级别很重要:
- 当验证失败时(如证书过期、签名无效、CA 不匹配),Nginx 会在 error log 中输出类似:
SSL_do_handshake() failed (SSL: error:1417C086:SSL routines:tls_process_client_certificate:certificate verify failed:depth=0) - 该错误日志含具体失败深度(depth)和原因,与 access log 中的
$ssl_client_verify值(如FAILED:certificate has expired)互为印证,构成完整审计线索
日志分析与告警建议
记录只是第一步,需建立机制识别异常模式:
- 定期 grep
FAILED:或NONE行,统计高频失败原因(如大量FAILED:unable to get local issuer certificate提示 CA 配置遗漏) - 对
FAILED:出现次数突增设置告警(例如每分钟 >5 次),可能预示攻击尝试或客户端批量配置错误 - 保留含
$ssl_client_s_dn的日志至少 90 天,满足常见合规审计周期要求;敏感字段(如 CN)可按需脱敏(Nginx 本身不支持运行时脱敏,需后处理)











