ssl_verify_depth 限制客户端证书链验证时的最大嵌套层级,即从终端证书向上追溯到信任根CA的跳数;默认值为1,表示仅允许终端证书由指定CA直接签发,不支持中间CA。

ssl_verify_depth 是 Nginx 在启用客户端证书双向认证(mTLS)时,用于限制验证过程中允许的证书链最大嵌套层级的关键参数。它不控制服务端证书链,只影响客户端提交的证书链(即 client certificate chain)在验证时最多能向上追溯几级 CA 证书。
它到底验证什么?
当配置 ssl_client_certificate 并开启 ssl_verify_client on 后,Nginx 会用你提供的 CA 证书(或 CA 证书包)来验证客户端发来的证书是否可信。这个验证过程可能涉及多级签发关系,比如:
- 客户端证书 ← 由中间 CA 签发
- 中间 CA 证书 ← 由根 CA 签发
- 根 CA 证书 ← 你放在
ssl_client_certificate文件里的那个(或其中之一)
ssl_verify_depth 就是限制“客户端证书 → 中间 CA → 根 CA”这条链里,最多允许多少个“←”符号(即最多几级签发跳数)。默认值为 1,意味着只允许客户端证书直接由你指定的 CA 签发,不接受带中间 CA 的链。
常见配置场景与取值建议
根据你的客户端证书链结构决定:
- 客户端证书是自签名,且你把该证书本身当作 CA 放进
ssl_client_certificate:设为 0 - 客户端证书由你的根 CA 直接签发(无中间 CA):保持默认 1 即可
- 客户端证书经一级中间 CA 签发(即:client ← intermediate ← root):需设为 2
- 有两级中间 CA(client ← int1 ← int2 ← root):需设为 3
注意:该值必须 ≥ 实际证书链深度,否则 Nginx 会返回 400 Bad Request 或 SSL_do_handshake() failed 类错误,日志中通常提示 "certificate verification error" 或明确指出 "unable to get local issuer certificate"。
如何确认客户端证书链深度?
拿到客户端发来的完整证书链(通常是 PEM 格式,含 client cert + intermediate(s)),用 OpenSSL 检查:
openssl verify -CAfile your-ca-bundle.pem -untrusted intermediates.pem client.crt更直观的方式是逐级追溯 issuer/subject:
openssl x509 -in client.crt -noout -issueropenssl x509 -in intermediate.crt -noout -issuer
openssl x509 -in root.crt -noout -subject
从 client.crt 的 issuer 开始,一层层比对,直到匹配到 root.crt 的 subject,中间经过几级证书,深度就是几。
配置示例与注意事项
在 server 块中添加:
ssl_verify_client on;ssl_client_certificate /etc/nginx/ssl/ca-bundle.pem;
ssl_verify_depth 2;
关键提醒:
-
ssl_client_certificate文件中必须包含**信任锚点**(通常是根 CA),中间 CA 可放里面,也可单独通过-untrusted方式传入(但 Nginx 不支持运行时传 untrusted,所以推荐全放进同一个文件) - 若客户端只发了终端证书、没发中间证书,即使
ssl_verify_depth足够也会失败——Nginx 不会自动补全缺失的中间证书 - 该参数不影响 OCSP 或 CRL 检查,仅约束证书链拓扑深度










