Nginx验证后端HTTPS证书有效性必须同时配置四项:proxy_ssl_verify on、proxy_ssl_trusted_certificate指定CA链、proxy_ssl_name声明匹配域名、proxy_ssl_server_name on启用SNI,缺一不可且须同处location或upstream块内。

在 Nginx 中验证 HTTPS 通信链路的安全有效性,核心是确保“客户端 ↔ Nginx ↔ 后端服务”全程加密且可信,不能只看前端是否挂锁,更要确认后端 TLS 握手是否真正通过严格校验。关键不在加不加 proxy_ssl_verify on,而在于它能否与配套参数形成闭环验证。
启用 proxy_ssl_verify 的四个必要条件
单独开启 proxy_ssl_verify on 必然导致 502 错误,因为 Nginx 在 SSL_do_handshake() 阶段就中断连接。必须同时满足以下四点,且全部写在同一作用域(如 location 或 upstream 块内):
- proxy_ssl_verify on;—— 启用证书链校验动作本身
- proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;—— 指向含根 CA + 所有中间 CA 的 PEM 文件;不能只放后端证书,也不能依赖系统路径而不检查 Nginx 进程读取权限
-
proxy_ssl_name "api.internal.example.com";—— 显式声明期望的 SAN 域名;若
proxy_pass写的是 IP(如https://10.0.1.5)或变量,不设此项则跳过域名匹配,但多数后端证书不含 IP SAN,仍会失败 -
proxy_ssl_server_name on;—— 启用 TLS SNI;否则后端可能返回默认证书(如自签名或泛域名证书),与
proxy_ssl_name不符
设置 proxy_ssl_verify_depth 匹配真实链长
该值决定 Nginx 最多允许几级证书签发路径。默认为 1,仅认“终端证书 → 根 CA”,但生产环境几乎全是三级结构(终端 → 中间 CA → 根 CA)。设错会导致 certificate verify failed:
- 两级链(终端 + 一个中间 CA)→ 设为 2
- 三级链(终端 + 中间 CA + 根 CA)→ 设为 3
- 自签名证书 → 设为 1,但前提是
proxy_ssl_trusted_certificate文件里已包含该自签根证书 - 设得过高(如 5)虽不报错,但会放宽对不可信中间签发者的限制,削弱验证意义
排查后端证书链不全问题
Nginx 不会自动补全证书链,它只验证后端实际返回的那一截。日志中出现 certificate verify failed,90% 是后端没返回完整链(缺中间 CA):
- 用
openssl s_client -connect 10.0.1.5:443 -servername api.internal.example.com直连后端,观察--- Certificate chain ---下是否包含全部证书 - 若只返回终端证书,需让后端 Web 服务器(如 Nginx、Apache、Spring Boot)配置中明确拼接中间证书(如
ssl_certificate指向fullchain.pem而非单个cert.pem) - 验证时注意加上
-showcerts参数,确保看到完整链输出
辅助验证手段:OCSP Stapling 与连接状态观测
除了后端证书校验,还可通过 OCSP Stapling 提升客户端侧验证效率与可靠性:
- 在 HTTPS server 块中启用:
ssl_stapling on;和ssl_stapling_verify on; - 配合
ssl_trusted_certificate指向包含根 + 中间 CA 的文件,用于验证 stapling 响应本身 - 用
curl -Iv https://your-domain.com查看响应头中是否有OCSP Response Status: successful - 结合
nginx -t测试配置,nginx -s reload生效后,再用真实请求触发并观察 error.log 中的 SSL 握手日志


















