Nginx访问上游HTTPS服务证书验证失败时,核心是正确配置proxy_ssl_trusted_certificate指定可信CA根证书,并开启proxy_ssl_verify on;ssl_trusted_certificate仅用于客户端证书验证,与上游校验无关。

当 Nginx 作为反向代理或 HTTPS 服务端时,若后端服务(如上游 API、gRPC 服务、或另一个 HTTPS 站点)使用了自签名证书、私有 CA 签发的证书,或其证书链中缺少中间/根证书,客户端(如 curl、浏览器、或内部服务)在验证 TLS 时就可能报错:SSL certificate problem: unable to get local issuer certificate 或 self signed certificate in certificate chain。此时仅靠 ssl_certificate 和 ssl_certificate_key 是不够的——Nginx 默认不主动向客户端提供完整证书链,也不验证上游证书的信任锚。
而 ssl_trusted_certificate 并非用于“让 Nginx 信任谁”,而是用于启用客户端证书验证(mTLS)时,指定 Nginx 用以校验客户端证书签名的可信根 CA 列表。它不解决你遇到的“访问上游时证书校验失败”问题——那是 proxy_ssl_trusted_certificate 的职责。
关键区分:两个不同场景,两个不同指令
务必分清:
-
ssl_trusted_certificate:仅在开启ssl_client_certificate+ssl_verify_client on时生效,用于验证客户端**提交的证书**是否由你信任的 CA 签发; -
proxy_ssl_trusted_certificate:在proxy_pass https://...场景下,用于告诉 Nginx “用这份 CA 文件去验证上游服务器返回的证书是否可信”。这才是修复“访问上游报根证书缺失”的核心配置。
手动补全上游证书信任链(推荐做法)
如果上游服务证书由私有 CA 或内网 PKI 签发,你需要把该 CA 的根证书(.crt 或 .pem)放在 Nginx 可读路径(如 /etc/nginx/ssl/internal-ca.crt),然后在对应 location 或 server 块中添加:
proxy_ssl_trusted_certificate /etc/nginx/ssl/internal-ca.crt;-
proxy_ssl_verify on;(必须开启,否则不校验) -
proxy_ssl_verify_depth 2;(可选,指定最多允许几级中间证书,默认 1;私有 CA 若含中间件,建议设为 2 或 3) -
proxy_ssl_protocols TLSv1.2 TLSv1.3;(显式限定协议,避免旧协议兼容问题)
✅ 示例片段:
location /api/ {
proxy_pass https://backend.internal;
proxy_ssl_trusted_certificate /etc/nginx/ssl/ca-bundle.pem;
proxy_ssl_verify on;
proxy_ssl_verify_depth 3;
proxy_ssl_protocols TLSv1.2 TLSv1.3;
proxy_ssl_server_name on; # 启用 SNI,重要!
}
如何获取并验证上游 CA 证书?
不要凭空猜测或复制网上根证书。正确方式是:
- 用
openssl s_client -connect backend.internal:443 -showcerts连接上游,复制输出中以-----BEGIN CERTIFICATE-----开头、结尾的全部内容(尤其是最后一个证书块,通常是根 CA); - 将该证书保存为
root-ca.crt,用openssl x509 -in root-ca.crt -text -noout确认它是自签名(Issuer == Subject)且未过期; - 合并多个 CA(如有中间 CA)时,按“叶子→中间→根”顺序拼接进一个文件(Nginx 会按需遍历);
- 测试是否生效:
nginx -t检查语法,nginx -s reload重载,再请求接口看是否不再报证书错误。
补充:若上游用的是 Let’s Encrypt 或公共 CA,通常无需额外配置
因为主流 Linux 发行版的 ca-certificates 包已内置主流根证书。但某些精简容器镜像(如 Alpine + 自编译 Nginx)可能缺失。此时可:
- 安装系统级 CA 包(Alpine:
apk add ca-certificates); - 或显式指向系统 CA 路径:
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;(Debian/Ubuntu)或/etc/pki/tls/certs/ca-bundle.crt(RHEL/CentOS); - 注意:Nginx 不自动读取系统默认 CA 路径,必须显式指定
proxy_ssl_trusted_certificate。
不复杂但容易忽略:配错指令名、混淆 client/server 场景、忘记开 proxy_ssl_verify、或证书路径权限不对(Nginx worker 进程需有读取权限)。确认这四点,90% 的上游证书校验失败都能定位解决。


















