排查nginx与cdn https故障关键在tls握手稳定性,需验证sni启用(proxy_ssl_server_name on)、proxy_pass使用域名、证书链完整、tls协议及cipher套件兼容,并通过tcpdump/wireshark抓包定位握手断点。

排查 Nginx 与 CDN 之间的 HTTPS 连接故障,关键不是看证书是否“上传成功”,而是验证 TLS 握手能否在 Nginx 和 CDN 之间稳定完成。很多问题表面是 502、403 或连接重置,根源却藏在 SNI、协议兼容性或证书链传递环节。
检查 proxy_pass 是否使用域名且启用 SNI
Nginx 默认不会向上游(CDN)发送 SNI 信息,除非明确配置。若 proxy_pass 写成 IP 地址(如 https://192.168.1.100),SNI 字段为空,CDN 无法识别目标域名,可能返回默认证书、403 或直接中断握手。
- 必须将
proxy_pass改为有效域名,例如:proxy_pass https://cdn.example.com; - 紧随其后添加:
proxy_ssl_server_name on;(Nginx ≥ 1.7.0) - 用
openssl s_client -connect cdn.example.com:443 -servername cdn.example.com手动验证 CDN 是否能正确响应对应域名的证书
确认证书链完整且 CDN 可验证
CDN 作为 HTTPS 客户端(当 Nginx 代理请求过去时),需要能校验你源站或上游 CDN 的证书。若它收到的是不完整链(缺中间证书),proxy_ssl_verify on 就会失败,导致 502。
- 测试命令:
curl -vI https://cdn.example.com --resolve "cdn.example.com:443:实际IP",观察是否出现 SSL certificate problem - 若 CDN 要求严格校验,确保
ssl_certificate指向的文件包含完整链(即fullchain.pem,而非仅cert.pem) - 生产环境建议开启
proxy_ssl_verify on,并配好proxy_ssl_trusted_certificate指向可信根+中间 CA 包
比对 TLS 协议与加密套件兼容性
不同 CDN 厂商支持的 TLS 版本和 cipher suite 差异较大。Nginx 若强制启用 TLS 1.3 但 CDN 尚未支持,或只允许 ECDHE-RSA-AES256-GCM-SHA384,而 Nginx 配置了不匹配的套件,握手就会失败。
- 临时放宽限制测试:在 upstream 或 location 中加
proxy_ssl_protocols TLSv1.2 TLSv1.3;和proxy_ssl_ciphers HIGH:!aNULL:!MD5:!RC4; - 查 CDN 文档确认其支持的最低 TLS 版本(如 Cloudflare 要求 TLS 1.2+,阿里云 CDN 支持 TLS 1.0–1.3)
- 避免使用已弃用算法(如 SHA1、RSA key exchange),否则部分 CDN 会静默拒绝
抓包定位握手断点
当错误现象模糊(如偶发 Connection reset、无日志报错),最直接的方式是捕获 Nginx 到 CDN 的 TLS 流量。
- 在 Nginx 服务器执行:
tcpdump -i any host cdn.example.com and port 443 -w cdn_handshake.pcap - 用 Wireshark 打开,过滤
tls.handshake.type == 1(Client Hello),检查 Server Name 字段是否正确 - 查看是否有 TLS Alert(如 “unknown_ca”、“protocol_version”、“handshake_failure”),直接指向失败类型
- 注意:若抓不到 Client Hello,说明连接在 TCP 层就被拦截(如安全组、WAF、运营商干扰)











