排查nginx proxy_pass转发https服务tls握手失败,核心是确认nginx作为客户端连上游是否正常:先据error.log中“to upstream”定位方向;重点检查proxy_ssl_verify配置、sni启用(proxy_ssl_server_name on)、证书信任链及tls协议兼容性,并通过tcpdump、openssl s_client和debug日志交叉验证。

排查 Nginx proxy_pass 转发 HTTPS 服务时的 TLS 握手失败,核心是确认 Nginx 与上游服务器之间的 SSL/TLS 协商是否正常。常见原因不是客户端连 Nginx 失败,而是 Nginx 自身作为 HTTPS 客户端去连接后端时出错。
检查 Nginx 是否启用了 SSL 模块并正确配置 upstream
Nginx 默认不验证上游证书,但若上游使用自签名、过期或域名不匹配的证书,且你启用了 proxy_ssl_verify on,就会握手失败。先确认是否误开了校验:
- 检查配置中是否有
proxy_ssl_verify on;如有,临时改为off测试是否恢复(仅用于诊断,生产环境不应长期关闭) - 确认
proxy_ssl_trusted_certificate指向的 CA 文件存在且包含上游服务器证书链的根/中间证书 - 若上游用 SNI 域名(如多个 HTTPS 服务共用 IP),需设置
proxy_ssl_server_name on,否则可能因服务端返回错误证书而握手失败
抓包定位握手在哪一步中断
在 Nginx 服务器上对 upstream 地址抓包,能直观看到 TLS 握手是否发起、ServerHello 是否返回、有无 Alert 包:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
- 运行:
tcpdump -i any -w proxy_handshake.pcap host upstream.example.com and port 443 - 复现请求后,用 Wireshark 打开 pcap,过滤
tls,观察是否完成 ClientHello → ServerHello → Certificate → Finished 流程 - 若卡在 ClientHello 后无响应:上游端口未通、防火墙拦截、或 upstream 未监听 443
- 若收到 TLS Alert(如 “Unknown CA” 或 “Bad Certificate”):说明 Nginx 验证失败,对应检查证书信任链
启用 Nginx 错误日志并提高 SSL 调试级别
默认 error_log 级别(warn)通常不输出 TLS 握手细节,需临时调高:
- 在
http或location块中添加:error_log /var/log/nginx/proxy_ssl.log debug; - 重启 Nginx(或 reload),触发一次失败请求
- 查看日志中是否出现类似
SSL_do_handshake() failed、SSL_connect() failed、SSL certificate verify error的线索 - 注意:debug 日志量大,排查后及时改回 warn 或 error 级别
模拟 Nginx 的 HTTPS 客户端行为做隔离验证
绕过 Nginx,用相同参数手动测试能否成功建立 TLS 连接,快速判断是 Nginx 配置问题还是上游本身异常:
- 用
openssl s_client -connect upstream.example.com:443 -servername upstream.example.com(加-servername模拟 SNI) - 观察是否能完成握手、证书是否被信任、是否有 Verify return code 非 0
- 若 openssl 也失败,说明上游证书或网络层有问题;若 openssl 成功而 Nginx 失败,则聚焦 Nginx 的
proxy_ssl_*参数
不复杂但容易忽略:Nginx 1.19.4+ 默认启用了 TLSv1.3,而某些老旧 HTTPS 服务只支持 TLSv1.2;可尝试显式指定 proxy_ssl_protocols TLSv1.2; 排除协议不兼容问题。










