ssl证书信息不会丢失,问题在于nginx未透传tls层关键标识(如sni、https状态、客户端证书等),需检查proxy_ssl_*配置、x-forwarded-proto头设置及上游tls握手是否成功。

SSL 证书信息本身不会“丢失”,因为 Nginx 不会把证书内容作为请求头转发给后端;真正可能出问题的是:客户端的 SSL 连接信息(如是否启用 HTTPS、SNI 域名、证书验证结果等)未被正确传递,导致后端无法识别安全上下文,或反向代理握手失败。排查重点在于确认 Nginx 是否完整透传了 TLS 层关键标识,并确保上游通信不因证书校验中断。
检查 proxy_ssl_* 相关配置是否启用并生效
当 Nginx 反向代理到 HTTPS 后端时,若需让后端感知或验证客户端连接的安全性,必须显式配置 TLS 代理行为:
- proxy_ssl_server_name on; —— 必须开启,否则 Nginx 默认用 IP 连接上游,不发送 SNI,某些 CDN 或域名托管服务会拒绝无 SNI 的 TLS 握手
- proxy_ssl_name example.com; —— 显式指定期望的上游服务器名称,用于匹配其证书中的 CN/SAN;若 upstream 是域名,此项不可省略
-
proxy_ssl_verify off;(开发/内网环境)或 proxy_ssl_verify on; + proxy_ssl_trusted_certificate(生产环境)—— 若开启 verify,必须提供可信 CA 证书 bundle,否则握手直接失败报
SSL_do_handshake() failed
确认是否误删或遗漏 SSL 协议透传头
Nginx 默认不自动添加与证书相关的请求头。如需让后端获知原始 HTTPS 状态或客户端证书信息,需手动设置:
- 用 proxy_set_header X-Forwarded-Proto $scheme; 透传协议类型(
https或http),避免后端误判为非加密请求 - 若启用了客户端证书认证(
ssl_verify_client on),可用 proxy_set_header SSL_CLIENT_CERT $ssl_client_cert; 将 PEM 格式证书内容转发(注意长度和编码,建议先截断或 Base64 处理) - 不要依赖
$ssl_client_s_dn等变量直接透传,它们是解析后的字符串,不含原始证书数据
验证上游 TLS 握手是否真正完成
很多“证书信息丢失”实际是上游连接根本没建立成功,错误日志藏在 error_log 中:
- 查 Nginx 错误日志,搜索关键词:
SSL_do_handshake、ssl3_read_bytes、handshake failure、unable to get local issuer certificate - 执行测试命令模拟代理行为:
openssl s_client -connect upstream-domain.com:443 -servername upstream-domain.com -showcerts,确认上游证书链完整、时间有效、域名匹配 - 若上游是私有 CA 或自签名证书,
proxy_ssl_trusted_certificate文件必须包含其根证书(PEM 格式),且路径可被 Nginx 进程读取(权限 644,属主 root)
排除 CDN、WAF 或中间设备干扰
如果流量经过 CDN 或 WAF,它们可能终止 TLS 并以 HTTP 重发给 Nginx,导致:
- 原始 SNI 和客户端证书信息完全丢失
- Nginx 收到的是纯 HTTP 请求,
$scheme变成http,$ssl_protocol为空 - 此时需在 CDN/WAF 控制台开启“透传客户端证书”或“保留原始协议头”,并配合
proxy_set_header X-Forwarded-Proto https;强制标记











