ssl_verify_depth应设为客户端证书链中从终端证书到可信根ca所含ca证书的总张数(含中间ca和根ca,不含终端证书),必须与实际链结构严丝合缝;设小拒合法用户,设大放行可疑长链。

直接说结论:ssl_verify_depth 要设成你客户端证书链中「从终端证书到可信根 CA」所经过的 CA 证书总张数,不是中间 CA 的个数,也不是随便填个安全值。设小了会拒掉合法用户,设大了等于放行可疑长链,它必须和你实际部署的证书结构严丝合缝。
先搞清 ssl_verify_depth 算的是什么
这个值统计的是完整信任路径上所有参与签名的 CA 证书数量,含中间 CA,也含你放在信任文件里的根 CA,但不包括客户端那张终端证书本身。
- 客户端证书由根 CA 直签 → 链为「终端 → 根」→ ssl_verify_depth = 1
- 客户端证书由中间 CA 签发,该中间 CA 又由根 CA 签发 → 链为「终端 → 中间 → 根」→ ssl_verify_depth = 2
- 客户端证书经两级中间 CA(如部门 CA → 区域 CA → 企业根)→ 链为「终端 → 中间1 → 中间2 → 根」→ ssl_verify_depth = 3
怎么准确知道该填几
别猜,用 OpenSSL 实测:
- 拿到客户端证书链文件(比如 client-chain.pem),运行:
openssl crl2pkcs7 -nocrl -certfile client-chain.pem | openssl pkcs7 -print_certs -noout - 数输出里 BEGIN CERTIFICATE 出现几次 —— 这就是你链里实际包含的证书总数
- 再确认其中最后一张是不是你信任的根 CA(用 openssl x509 -in root.crt -noout -subject 对比),确保整条链能闭环
必须同时配齐的配套指令
单独写 ssl_verify_depth 没用,Apache 或 Nginx 都会静默跳过校验:
- Apache(双向认证):SSLVerifyClient require + SSLCACertificateFile(含全部中间 CA 和根 CA)+ SSLEngine on
- Nginx(反向代理上游校验):proxy_ssl_verify on + proxy_ssl_trusted_certificate(同样需含完整信任链)+ proxy_ssl_name + proxy_ssl_server_name on
合规场景下的常见取值建议
等保三级、金融类系统通常要求可验证、可追溯、不过度延伸的信任链:
- 自建单层 PKI(根 CA 直签所有终端)→ 设为 1,最严格
- 标准商用或企业两级 PKI(终端 ← 中间 ← 根)→ 设为 2,覆盖 Let’s Encrypt、DigiCert 等主流客户端证书
- 大型集团多级私有 CA(如总部根 → 大区中间 → 分公司中间 → 终端)→ 设为 3,需同步强化中间 CA 管控
- 不建议设为 4 及以上 —— 链过深本身是风险信号,审计时易被认定为信任锚松散











