Nginx 在尝试反向代理启用了 SNI 的 Https 网站时发生 SSL 握手失败的解决方法
本文最后更新于 860 天前,其中的信息可能已经有所发展或是发生改变。

为了优化博客在国内的访问速度,又找了一台机子来进行反代,在尝试直接反代到博客源站时发生 Http 502 错误,根据日志信息,判断为 Nginx 未设置反代 SNI 配置,故在 location 块中添加如下几行:

    # reverse proxy
    location / {
        // 对反代连接启用 SNI 支持
        proxy_ssl_server_name on;
        // 设置 SNI 目标域名
        proxy_ssl_name blog.lamgc.net;
        // 反代至博客国际站
        proxy_pass https://blog.lamgc.net;
        // ....
    }

配置完成后,SNI 成功启用,但在连接中依然遇到 SSL 握手失败,Nginx 日志如下:

2021/04/17 09:52:01 [error] 23#23: *1 SSL_do_handshake() failed (SSL: error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:SSL alert number 70) while SSL handshaking to upstream, client: 113.*.*.*, server: blog.lamgc.moe, request: "GET / HTTP/2.0", upstream: "https://132.*.*.*:443/", host: "blog.lamgc.moe"
...

筛选日志信息,错误信息为“tlsv1 alert protocol version:SSL alert number 70”,猜测是 SSL 协议版本问题,但不知道具体信息,百度搜索无果后尝试进行 Google 搜索,发现一张 SSL 警告代码解释表[1],查表找到错误代码 70 的解释为:“The protocol version the client attempted to negotiate is recognized, but not supported. For example, old protocol versions might be avoided for security reasons. This message is always fatal.”(客户端尝试协商的版本可以识别,但不受支持。出于安全考虑,避免使用旧的协议。此错误永远是致命的)。也就是反代所使用的 SSL 版本未配置,Nginx 可能在尝试使用TLSv1.0 或以下的版本进行协商,被源站拒绝,因此,可以加入“proxy_ssl_protocols”指定反代连接所允许使用的 SSL 协议。

配置如下:

    # reverse proxy
    location / {
        // 对反代连接启用 SNI 支持
        proxy_ssl_server_name on;
        // 设置 SNI 目标域名
        proxy_ssl_name xxx.com;
        // 设置反代连接所允许使用的 TLS 版本
        proxy_ssl_protocols TLSv1.2 TLSv1.3;
        // 反代至目标站点
        proxy_pass https://xxx.com;
        // ....
    }

至此,反代出现的 SSL 握手失败问题全部解决。

[1] SSL 警告代码解释表:what do the following ssl alert messages – broadcom

上一篇
下一篇