Nginx代理HTTPS后端时证书验证失败,本质是其作为客户端校验失败,主因有三:证书不可信(如自签名或链不全)、域名不匹配(未启用SNI或proxy_ssl_name配置错误)、私钥与证书不匹配;须配置proxy_ssl_verify on、proxy_ssl_server_name on、proxy_ssl_name及proxy_ssl_trusted_certificate。

当 Nginx 用 proxy_pass https:// 转发请求到后端 HTTPS 服务时,若出现类似 ssl: error:0a000086:ssl routines::certificate verify failed 或 X509_check_private_key:key values mismatch 的报错,本质是 Nginx 主动校验后端证书失败,而非前端访问问题。核心在于:Nginx 此时扮演的是 HTTPS 客户端角色,必须能验证后端服务器返回的证书是否可信、完整、匹配。
后端证书验证失败的三类主因
这类报错几乎都落在以下三个环节,需逐项排查:
- 证书不可信:后端使用自签名证书、内网 CA 签发但 Nginx 未加载该 CA 根证书、或证书链不全(缺少中间证书);
- 证书与域名不匹配:Nginx 发起连接时未发送 SNI(Server Name Indication),导致后端返回默认证书(如通配符或错误域名证书),而该证书的 CN/SAN 不包含实际请求的主机名;
- 私钥与证书不匹配:后端服务配置的 .crt 和 .key 文件不是一对,常见于手动替换证书后遗漏更新私钥,或拼接证书链时顺序错误。
关键配置:启用 SNI 并指定验证目标
仅写 proxy_pass https://10.0.0.5; 是不够的——IP 地址无法携带域名信息,后端无法判断该返回哪张证书。必须显式启用 SNI 并告知 Nginx “这次连接应声称访问哪个域名”:
-
proxy_ssl_server_name on;:强制开启 TLS 握手时的 SNI 扩展; -
proxy_ssl_name backend.example.com;:明确指定 SNI 字段值(即后端证书中 SAN 或 CN 应覆盖的域名); -
proxy_ssl_verify on;:开启证书链验证(生产环境必须); -
proxy_ssl_trusted_certificate /etc/nginx/certs/internal-ca.crt;:提供可信根证书路径(如为 Let's Encrypt 或公网 CA 签发,可用系统信任库,如/etc/ssl/certs/ca-certificates.crt)。
快速验证与调试方法
不依赖重启 Nginx,可直接在命令行模拟连接,确认后端证书状态:
- 检查 SNI 是否生效:
openssl s_client -connect 10.0.0.5:443 -servername api.internal.com -showcerts;观察返回的证书 Subject、SAN 是否符合预期; - 验证证书与私钥一致性(在后端服务器上执行):
openssl x509 -noout -modulus -in cert.pem | openssl md5openssl rsa -noout -modulus -in key.pem | openssl md5
两行输出必须完全一致; - 检查证书链完整性:
openssl verify -CAfile /etc/nginx/certs/ca-bundle.crt cert.pem,返回cert.pem: OK才表示链可信。
临时绕过验证(仅限测试环境)
开发或联调阶段若需快速验证逻辑,可临时禁用验证,但严禁用于生产:
-
proxy_ssl_verify off;:跳过证书有效性检查; -
proxy_ssl_trusted_certificate可省略; - 注意:即使关闭验证,
proxy_ssl_server_name on仍建议保留,否则仍可能因 SNI 缺失拿到错误证书,引发其他兼容性问题。











