Nginx代理HTTPS API时必须同时配置proxy_ssl_verify on、proxy_ssl_trusted_certificate、proxy_ssl_name和proxy_ssl_server_name四项,缺一不可;否则返回502而非跳过验证。

要让 Nginx 在代理请求到外部 HTTPS API 时真正校验对方证书是否可信,不能只写 proxy_ssl_verify on。它必须和另外三项配置一起生效,否则会直接返回 502 错误,而不是“跳过验证”。
必须配齐的四个基础项
这四项缺一不可,且必须写在同一个 location 或 upstream 块里:
- proxy_ssl_verify on; —— 启用校验开关(默认是 off,不显式开启等于没开)
-
proxy_ssl_trusted_certificate /etc/nginx/ssl/ca-bundle.crt; —— 指向包含可信根证书和中间 CA 的 PEM 文件;推荐用系统级证书包(如
/etc/ssl/certs/ca-certificates.crt),或从 Mozilla 官方下载的cacert.pem -
proxy_ssl_name "api.example.com"; —— 显式声明你期望后端证书中 SAN 字段匹配的域名;如果
proxy_pass写的是 IP 或变量(比如https://$backend_host),这一项绝对不能省,否则校验会因无法比对域名而失败 - proxy_ssl_server_name on; —— 强制 TLS 握手发送 SNI,确保外部 API 返回对应域名的正确证书(尤其对接 Cloudflare、AWS ALB、阿里云 SLB 等多域名网关时必不可少)
应对常见外部 API 的关键增强项
多数外部服务(如 Stripe、Auth0、GitHub API)使用含中间 CA 的证书链,仅靠默认配置容易失败:
- proxy_ssl_verify_depth 2; —— 默认值 1 只认“终端→根 CA”,但 Let’s Encrypt、DigiCert 等主流 CA 都是“终端→中间→根”结构;设为 2 才能完整验证
- proxy_ssl_session_reuse off; —— 关闭 TLS 会话复用,避免异常证书状态被缓存复用(对外部不可控服务更稳妥)
- proxy_ssl_protocols TLSv1.2 TLSv1.3; —— 明确禁用老旧协议,防止握手阶段被降级绕过校验
快速验证证书链是否完整
如果启用后报 certificate verify failed,大概率是后端没返回完整证书链。可用以下命令确认:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts 2>/dev/null | grep "BEGIN CERTIFICATE" | wc -l
输出为 1 表示只返回了终端证书,需让 API 提供方补全中间证书;输出 ≥2 则说明链完整,问题可能出在 Nginx 的 proxy_ssl_trusted_certificate 文件未包含对应中间 CA。
典型配置示例(对接外部 HTTPS API)
假设你要代理请求到 https://api.stripe.com:
location /stripe/ {
proxy_pass https://api.stripe.com/;
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
proxy_ssl_verify_depth 2;
proxy_ssl_name "api.stripe.com";
proxy_ssl_server_name on;
proxy_ssl_session_reuse off;
proxy_ssl_protocols TLSv1.2 TLSv1.3;
}

















