关键是配置 upstream 的 proxy_ssl_protocols 指令显式启用 tlsv1.1,因新版 nginx 默认禁用 tls 1.0/1.1,而老旧 cdn 回源节点仅支持 tls 1.1,需在 upstream 或 location 中设置 proxy_ssl_protocols tlsv1.1 tlsv1.2,并配合 proxy_ssl_verify off 等调优。

要让 Nginx 回源时与旧版 CDN 节点成功建立 SSL 连接,关键不是“降级”Nginx 自身的 TLS 版本,而是控制它作为客户端(即回源发起方)在连接上游服务器时所使用的 TLS 协议版本。默认情况下,较新版本的 Nginx(1.19.4+)已禁用 TLS 1.0/1.1,而部分老旧 CDN 回源节点仅支持 TLS 1.1 或更低,导致 SSL_do_handshake() failed 或 ssl handshake failed 类错误。
确认问题是否为 TLS 版本不兼容
先验证是否真由 TLS 版本引起:启用 Nginx error log 的 debug 级别(需编译含 --with-debug),或使用 openssl s_client -connect cdn-node:443 -tls1_1 手动测试目标 CDN 节点支持的最低 TLS 版本。若 TLS 1.2 连接失败但 TLS 1.1 成功,则基本可定位为此问题。
配置 upstream 的 proxy_ssl_protocols
Nginx 提供 proxy_ssl_protocols 指令,专门用于指定回源时作为 SSL 客户端所允许的协议版本。该指令必须放在 upstream 块或 location 内的 proxy_pass 上下文中,不能写在 http 或 server 全局块中。
例如:
upstream legacy_cdn {
server cdn.example.com:443;
proxy_ssl_protocols TLSv1.1 TLSv1.2; # 显式启用 TLS 1.1(必要)
proxy_ssl_verify off; # 若 CDN 使用自签或过期证书,需关闭校验
proxy_ssl_trusted_certificate /path/to/trust.pem;
}
配合调整其他 SSL 客户端行为
仅开 TLS 1.1 不够,还需注意以下几点:
-
禁用不安全的加密套件:旧 CDN 可能依赖
RC4或3DES,但现代 Nginx 默认已移除。可通过proxy_ssl_ciphers补充,如:proxy_ssl_ciphers "ECDHE-RSA-AES256-SHA:AES256-SHA:RC4-SHA:HIGH:!aNULL:!MD5:!EXPORT56:!EXP"; -
关闭证书验证(谨慎):若 CDN 使用私有 CA 或证书已过期,
proxy_ssl_verify off是临时绕过手段;长期应推动 CDN 更新证书和 TLS 配置。 -
避免 SNI 冲突:某些老节点无法处理 SNI 扩展,可加
proxy_ssl_server_name off;关闭发送 SNI,但需确保目标域名与证书 CN/SAN 匹配。
验证与回滚准备
上线前务必用 nginx -t 检查语法,并在测试环境用 curl -v --resolve 或 tcpdump 抓包确认实际协商的 TLS 版本。保留旧配置备份,因为放宽 TLS 版本会降低传输安全性——此方案仅为过渡措施,建议同步联系 CDN 提供商升级其回源服务至 TLS 1.2+ 并启用现代 cipher suite。











