ssl_verify_client必须与HTTPS监听、ssl_certificate/ssl_certificate_key、ssl_client_certificate三者同时配置才生效;取值on强制校验客户端证书,optional允许无证书请求,off则完全忽略校验。

ssl_verify_client 本身不是独立生效的指令,它必须和 ssl_client_certificate、HTTPS 监听一起配合,才能真正启用客户端证书校验。单独写它,等于没配。
必须同时满足的三个前提
- 已开启 HTTPS 监听:
listen 443 ssl;,且配置了服务端证书和私钥(ssl_certificate/ssl_certificate_key) - 指定了可信 CA 证书文件:
ssl_client_certificate /etc/nginx/ssl/ca.crt;(PEM 格式,只含公钥,无私钥、无空行、无 BOM) - 设置了合理的验证深度:
ssl_verify_depth 2;(若客户端证书由中间 CA 签发,深度至少为 2;默认 1 只支持根 CA 直签)
三种取值的实际效果
-
off:完全不校验客户端证书(默认值),即使客户端发了也忽略 -
optional:允许无证书请求通过($ssl_client_verify值为NONE);若提供了证书,则尝试验证签名与有效期,失败也不阻断连接 -
on:强制每个 TLS 连接都提供有效客户端证书;未提供、格式错误、签名无效、过期、CA 不可信,都会在握手阶段直接中断,返回 HTTP 400 错误(不是 403)
常见配置片段
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_client_certificate /etc/nginx/ssl/ca.crt;
ssl_verify_client on;
ssl_verify_depth 2;
# 可选:透传校验结果和证书信息给后端
proxy_set_header X-Client-Verify $ssl_client_verify;
proxy_set_header X-Client-DN $ssl_client_s_dn;
proxy_set_header X-Client-CN $ssl_client_s_dn_cn;
}调试关键点
- 查看 Nginx 错误日志(
error_log),495/496 错误码对应证书问题(如SSL_do_handshake() failed) - 使用
curl --cert client.crt --key client.key https://example.com测试,避免浏览器缓存干扰 - 验证 CA 文件是否加载成功:
openssl verify -CAfile /etc/nginx/ssl/ca.crt client.crt应返回OK - 确保 Nginx worker 进程有权限读取
.crt文件(如chmod 644 /etc/nginx/ssl/ca.crt)
不复杂但容易忽略。


















