Nginx启用客户端证书校验需配置ssl_verify_client(off/on/optional)并配合ssl_client_certificate指定CA证书;验证通过后可通过$ssl_client_verify等变量获取状态与证书信息,用于透传或应用层判断。

在 Nginx 中启用客户端证书校验,核心是使用 ssl_verify_client 指令配合证书信任链配置,它让服务端强制(或可选)要求客户端提供并验证其 TLS 证书。
理解 ssl_verify_client 的三种取值
该指令控制客户端证书的验证行为,必须配合 ssl_client_certificate(或 ssl_trusted_certificate)才能生效:
- off:不验证客户端证书(默认值),即使客户端提供了也不检查
- on:强制要求客户端提供有效证书,且必须能被信任链验证通过;否则直接返回 400 错误(Bad Certificate)
-
optional:允许客户端提供证书,若提供则验证;若未提供或验证失败,仍允许连接继续(但可通过
$ssl_client_verify变量在应用层做逻辑判断)
准备 CA 证书与服务端 TLS 配置
客户端证书由某 CA 签发,Nginx 必须信任该 CA 才能完成验证。需确保:
- 将签发客户端证书的根 CA 或中间 CA 证书(PEM 格式)保存到服务器,例如
/etc/nginx/ssl/client-ca.crt - 服务端自身 TLS 证书和私钥已正确配置(
ssl_certificate/ssl_certificate_key) - 开启 HTTPS 监听,并在对应 server 块中设置验证指令
示例片段:
ssl_certificate /etc/nginx/ssl/server.crt;ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_client_certificate /etc/nginx/ssl/client-ca.crt;
ssl_verify_client on;
获取并使用客户端证书信息
验证通过后,Nginx 会导出若干变量供后续使用,最常用的是:
-
$ssl_client_verify:值为
SUCCESS、FAILED:xxx或NONE,可用于 if 判断或透传给后端 - $ssl_client_cert:Base64 编码的客户端证书(PEM 内容),可转发给后端做二次校验或用户识别
-
$ssl_client_s_dn:客户端证书的 subject DN 字符串,如
CN=user1,OU=dev,O=example,适合提取用户名
例如,在 proxy_pass 场景中透传认证状态:
proxy_set_header X-Client-Verify $ssl_client_verify;proxy_set_header X-Client-DN $ssl_client_s_dn;
proxy_set_header X-Client-Cert $ssl_client_cert;
调试与常见问题
验证失败时,Nginx 默认只返回模糊错误(如 400)。建议开启日志辅助排查:
- 在 http 或 server 块中添加:
error_log /var/log/nginx/client-auth-error.log debug;(注意 debug 日志量大,仅临时启用) - 确认客户端证书确由
ssl_client_certificate指定的 CA 签发(可用openssl verify -CAfile client-ca.crt client.crt本地验证) - 检查客户端是否在 TLS 握手阶段发送了证书(浏览器需手动选择;curl 使用
--cert client.crt --key client.key) - 若用
optional模式但始终得不到$ssl_client_verify值,可能是客户端根本没发证书,或 Nginx 版本较老未正确填充变量(建议 ≥1.11.0)

















