ssl_verify_depth在nginx中必须严格匹配客户端证书链结构,等于从终端证书到可信根ca所经ca证书总数(含中间ca和根ca,不含终端证书);设小拒真、设大放滥,须配合ssl_verify_client on、ssl_client_certificate、服务端证书及实测链长共同生效。

ssl_verify_depth 在 Nginx 中不是“适配复杂链”的弹性参数,而是必须与客户端证书链结构严丝合缝的硬性阈值——它不自动适应、不智能推断,设错就拒真、设大就放滥。
它到底数什么?
这个值等于从客户端终端证书出发,向上追溯到你配置的根 CA 所需经过的 CA 证书总张数,含所有中间 CA,也含你放在 ssl_client_certificate 文件里的根 CA,但不含客户端那张终端证书本身:
- 终端 ← 根 CA(直签)→ 链长 = 1 →
ssl_verify_depth 1 - 终端 ← 中间 CA ← 根 CA → 链长 = 2 →
ssl_verify_depth 2 - 终端 ← 中间1 ← 中间2 ← 根 CA → 链长 = 3 →
ssl_verify_depth 3
怎么确认该填几?别猜,实测
用 OpenSSL 直接解析客户端证书链文件(如 client-chain.pem):
- 运行:
openssl crl2pkcs7 -nocrl -certfile client-chain.pem | openssl pkcs7 -print_certs -noout - 数输出中
BEGIN CERTIFICATE出现几次 —— 这就是链里证书总数 - 再确认最后一张证书的
subject是否与你信任的根 CA 的subject一致(用openssl x509 -in root.crt -noout -subject对比)
单设它没用,必须四件套齐备
以下四项缺一不可,且必须写在同一 server 块内:
-
ssl_verify_client on;(开启强制校验) -
ssl_client_certificate /path/to/ca-bundle.pem;(PEM 文件必须包含链中全部中间 CA + 根 CA,顺序不限,缺一级都不行) -
ssl_verify_depth N;(N = 实测链长) -
ssl_certificate和ssl_certificate_key(Nginx 自身服务端证书)
设错的典型表现
值太小:合法连接被拒,返回 400 Bad Request 或 TLS 握手失败,error.log 显示 unable to get local issuer certificate;
值太大:看似“兼容”,实则可能让本该被拦截的深层嵌套中间签发者绕过校验,尤其当信任文件里混入了非必需 CA 时。











