Nginx中ssl_verify_client仅控制是否启用客户端证书校验,真正决定验证深度的是ssl_verify_depth;二者须同在server块中配合使用,并与listen 443 ssl、ssl_certificate、ssl_certificate_key、ssl_client_certificate共同构成双向认证基础配置。

Nginx 中 ssl_verify_client 本身不负责控制证书验证深度,它只是一个开关,决定是否在 TLS 握手阶段强制要求并校验客户端证书。真正控制“验证深度”的是另一个独立指令:ssl_verify_depth。
要让客户端证书验证生效且可靠,必须把这两个指令配合使用,并确保它们和其他必要配置共存于同一个 server 块中。
必须同时存在的四个基础配置项
listen 443 ssl;
启用 HTTPS 监听,否则 TLS 层不会启动,ssl_verify_client就无从谈起。ssl_certificate和ssl_certificate_key
指向 Nginx 自身的服务端证书和私钥,用于向客户端证明身份。ssl_client_certificate
指向你信任的 CA 证书(PEM 格式),必须含CA:TRUE,不能是客户端证书或私钥。ssl_verify_client on;
开启强制双向认证;设为optional或off就无法实现强身份校验。
ssl_verify_depth 怎么设才合理?
这个值表示 Nginx 在构建证书信任链时,最多允许向上追溯几级签发者。
-
默认是
1,即只允许客户端证书 → 根 CA 一级直达。
如果你的客户端证书由中间 CA 签发(比如:根 CA → 中间 CA → 客户端证书),默认设置就会失败,日志中常见错误:FAILED: unable to get issuer certificate
-
正确做法是根据实际证书链层级显式设置:
- 根 CA 直签客户端证书 →
ssl_verify_depth 1 - 根 CA → 中间 CA → 客户端证书 →
ssl_verify_depth 2 - 更复杂的多级链(如根 → 中间1 → 中间2 → 客户端)→
ssl_verify_depth 3或更高
- 根 CA 直签客户端证书 →
✅ 验证方式(本地测试):
openssl verify -CAfile ca.crt -untrusted intermediate.crt client.crt
若返回 OK,说明链完整,再把对应层数写进 Nginx 配置。
实际配置片段示例
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-bundle.pem;
ssl_verify_client on;
ssl_verify_depth 2;
location /api/private/ {
if ($ssl_client_verify != "SUCCESS") {
return 403 "Client certificate validation failed";
}
proxy_pass https://backend;
proxy_set_header X-Client-Verify $ssl_client_verify;
proxy_set_header X-Client-DN $ssl_client_s_dn;
}
}注意:ssl_verify_depth 必须和 ssl_verify_client 在同一 server 块里,且 ssl_client_certificate 文件中应包含所有必要的上级 CA 证书(可合并为一个 PEM 文件,顺序不限)。
补充建议:提升校验可靠性
-
启用 OCSP Stapling(更实时):
ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 valid=300s;
-
或配置 CRL(需定期更新):
ssl_crl /etc/nginx/ssl/ca.crl;
这些不是必需项,但能防止已吊销证书被误放行。
不复杂但容易忽略。


















