ssl_verify_depth 控制证书链验证深度,需与 ssl_client_certificate 配合实现精准校验:设为1仅支持直签,2覆盖常见三级链,过高或过低均导致验证失败或信任绕过;应依据实际链长(如客户端→中间1→中间2→根为3)设置,并确保ca文件仅含可信根证书。

ssl_verify_depth 本身不直接“提升”安全性,而是让 Nginx 能正确、严格地验证客户端证书的信任链——设得太低会误拒合法请求,设得太高则可能接纳不可信的中间签发者,真正起作用的是它与 ssl_client_certificate 配合后形成的校验精度。
控制证书链回溯层级,防止信任过度延伸
默认值为 1,意味着只允许客户端证书直连根 CA;但现实中多数企业 PKI 使用“客户端证书 → 中间 CA → 根 CA”结构。若不调高 ssl_verify_depth,Nginx 在验证时会卡在中间 CA 层,报错 unable to get issuer certificate,看似失败,实则是因深度不足导致校验中断,而非安全增强。
- 设为 1:仅接受客户端证书由根 CA 直签(极少见,几乎不用)
- 设为 2:覆盖“客户端证书 → 中间 CA → 根 CA”三级链(最常用)
- 设为 3 或更高:仅在存在多级中间 CA(如金融私有 CA)时启用,需同步确保 ssl_client_certificate 文件中包含全部可信中间证书
避免因深度不匹配导致的校验绕过
如果实际链长为 3 层(客户端→中间1→中间2→根),但 ssl_verify_depth 设为 2,Nginx 就无法上溯到根,验证失败;此时有人可能干脆关掉 ssl_verify_client 或降级为 optional,反而彻底放弃校验——这比设错 depth 更危险。
- 正确做法是先用 openssl verify -CAfile ca-bundle.crt client.crt 确认链完整性,再将 depth 设为链中最大跳数(即根所在层级编号)
- 例如:client.crt ← signed by inter1.crt ← signed by inter2.crt ← signed by root.crt,则 depth 应设为 3
配合 ssl_client_certificate 实现精准信任锚点
ssl_verify_depth 的效果依赖于 ssl_client_certificate 指向的 CA 文件是否准确。该文件应只含你明确信任的根和/或中间 CA 证书(PEM 格式),不能混入服务端证书或私钥。
- 若文件里只放根 CA,depth 设为 2,就要求客户端证书必须能通过“客户端→中间→根”两跳抵达该根
- 若文件里同时放了根 + 中间 CA,且 depth 设为 1,Nginx 可能直接用中间 CA 验证客户端证书,跳过对根的校验——削弱了信任链完整性
- 推荐策略:ca.crt 文件只含根 CA;depth 设为实际链深度;这样所有验证都必须最终锚定到你信任的那个根
透传验证结果,让后端参与二次决策
ssl_verify_depth 配置生效后,Nginx 会在 TLS 握手阶段完成链验证,并生成 $ssl_client_verify 等变量。这些信息需显式透传,才能支撑更细粒度的访问控制。
- proxy_set_header X-Client-Verify $ssl_client_verify;
- proxy_set_header X-Client-DN $ssl_client_s_dn;
- 后端可据此判断 SUCCESS/FAILED,并结合 DN 字段做角色映射或白名单校验











