nginx 启用 proxy_ssl_verify on 必须同时配置 proxy_ssl_trusted_certificate、proxy_ssl_name 和 proxy_ssl_server_name,否则校验失败返回 502 错误;它用于严格校验后端 https 服务证书合法性,防止中间人攻击。

Nginx 本身并没有 proxy_ssl_verify 这个参数,正确名称是 proxy_ssl_verify(注意是下划线,不是短横线),且它必须与 proxy_ssl_trusted_certificate 配合使用,才能实现对后端 HTTPS 微服务证书的严格合法性校验。
启用并配置 proxy_ssl_verify
该指令控制 Nginx 是否验证上游服务器(即后端微服务)返回的 TLS 证书。默认为 off,需显式设为 on 才开启验证:
-
proxy_ssl_verify on;—— 启用证书链校验和主机名匹配 -
proxy_ssl_verify_depth 2;—— 可选,指定证书链最大验证深度(如根 CA → 中间 CA → 服务证书) -
proxy_ssl_trusted_certificate /etc/nginx/ssl/upstream-ca.crt;—— 必填,指定受信任的根证书或中间证书文件(PEM 格式)
确保后端证书满足校验要求
即使开启了 proxy_ssl_verify on,若后端证书不合规,请求仍会失败(返回 502 Bad Gateway)。需确认以下几点:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 后端服务证书必须由
proxy_ssl_trusted_certificate中列出的 CA 签发(含完整证书链) - 证书中的
Subject Alternative Name (SAN)必须包含 Nginx 实际连接的域名或 IP(例如:Nginx 用https://api.internal访问,则 SAN 需含api.internal;若直连 IP,如https://10.1.2.3,则需 SAN 包含该 IP,纯域名证书不认 IP) - 证书未过期、未被吊销(Nginx 不主动做 OCSP/CRL 检查,但过期或签名无效会直接拒接)
可选:校验证书主机名(防止中间人)
Nginx 默认只校验证书链和有效期,不强制校验证书绑定的域名是否匹配 upstream 地址。如需开启主机名检查,需配合使用:
-
proxy_ssl_name "api.example.com";—— 显式指定期望的 SNI 名称和证书 SAN 主机名 -
proxy_ssl_server_name on;—— 启用发送 SNI 扩展(便于后端识别虚拟主机) - 注意:
proxy_ssl_name值必须与后端证书中 SAN 的某一项完全一致(区分大小写),否则校验失败
调试与排错建议
开启严格校验后常见报错及应对方式:
-
SSL_do_handshake() failed (SSL: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca)→ 根证书未正确加载或路径错误,检查proxy_ssl_trusted_certificate文件权限和内容 -
SSL_do_handshake() failed (SSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure)→ 后端不支持 Nginx 提出的 TLS 版本或加密套件,可在 upstream 中加proxy_ssl_protocols TLSv1.2 TLSv1.3; -
upstream SSL certificate does not match "xxx"→ 主机名不匹配,检查proxy_ssl_name和证书 SAN 是否一致










