proxy_ssl_verify_depth 控制Nginx验证后端证书时允许的中间CA级数,必须设为真实链中中间证书数量,并严格配合proxy_ssl_verify on、proxy_ssl_trusted_certificate、proxy_ssl_name和proxy_ssl_server_name四项指令共同生效,缺一则静默降级。

“证书轮询深度”不是标准术语,实际想表达的是 证书链验证时向上追溯的中间 CA 层数限制,对应 Nginx 的 proxy_ssl_verify_depth 指令。它不控制“轮询”,而是控制信任链校验的最大跳数——设小了会 502,设大了可能放行异常长链,关键在匹配真实结构、配齐必要指令。
先确认后端证书链真实深度
别靠猜测或文档描述,用 OpenSSL 实测后端实际返回的证书结构:
- 运行
openssl s_client -connect backend-svc:443 -servername backend-svc.internal -showcerts 2>/dev/null | grep "BEGIN CERTIFICATE" | wc -l,输出数字 = 返回的证书总数(含终端 + 所有中间证书) - 再执行
openssl x509 -in service.crt -text -noout | grep "CA Issuers",每出现一个有效 URI,代表一级中间签发关系 -
depth 值 = 中间证书数量(不含终端证书,也不含根 CA;但根 CA 必须出现在
proxy_ssl_trusted_certificate文件中)
必须同步配置的四项核心指令
只改 proxy_ssl_verify_depth 是无效的,Nginx 会静默降级为不校验:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
-
proxy_ssl_verify on;—— 明确启用上游证书校验(默认是off) -
proxy_ssl_trusted_certificate /etc/nginx/certs/ca-bundle.pem;—— PEM 文件必须包含整条链中所有非终端证书:根 CA + 所有中间 CA(顺序无关,缺一级都不行) -
proxy_ssl_name "backend-svc.internal";—— 显式声明期望的 SNI 主机名,用于匹配证书中的 SAN 字段;若proxy_pass写的是 IP 或变量,此项必填 -
proxy_ssl_server_name on;—— 启用 TLS SNI 扩展,确保握手时把域名发给后端
推荐取值与典型场景
不是越大越安全,也不是越小越严格,而是刚好覆盖你的真实链结构:
-
depth 1:仅适用于自签名证书、或根 CA 直接签发服务证书(无中间层)。需确保
trusted_certificate中已包含该自签根 - depth 2:覆盖 Let’s Encrypt R3、Sectigo、ZeroSSL 等主流商业证书(终端 → 中间 CA → 根 CA),是公网服务和多数云 API 的推荐起点
- depth 3:适配企业私有 PKI 中含两级中间 CA 的结构(如 终端 → 部门 CA → 企业根 CA),内网微服务常见,建议生产环境从 3 起步并验证
- depth ≥4:除非你明确使用了三级及以上嵌套中间 CA,否则不建议;链越长,可审计性越弱,潜在信任风险越高
验证是否真正生效
配置后不能只看 Nginx 启动成功,要实测握手行为:
- 用
curl -v https://your-nginx-domain/api/观察返回是否含SSL certificate verify ok,或失败时错误是否为unable to get local issuer certificate(说明 depth 不够或 CA 文件缺失) - 查 Nginx error log:若出现
SSL_do_handshake() failed后跟certificate verification failed,结合当前proxy_ssl_verify_depth值反推链长度是否匹配 - 确保后端 HTTPS 服务本身返回完整证书链(例如 Nginx 的
ssl_certificate文件应含终端 + 中间证书),否则即使 depth 设对也校验失败

















