抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

前两天收到一个来自去不图床用户的反馈,说在香港区域访问图床时出现了 502 Bad Gateway 的错误,经过排查后发现是 Nginx 反代 SSL_do_handshake 出现问题,这里分享一下该问题的解决思路。

问题说明

是否遇到过使用 Nginx 反代网站时出现 502 Bad Gateway,明明正常访问都没问题 , 可是反代就 502 Bad Gateway , 查看错误日志显示:

1
2024/07/15 17:14:08 [error] 245105#0: *1324376 SSL_do_handshake() failed (SSL: error:1408F10B:SSL routines:ssl3_get_record:wrong version number) while SSL handshaking to upstream, client: 69.162.124.229, server: 7bu.top, request: "GET / HTTP/1.1", upstream: "https://211.101.237.240:443/", host: "7bu.top", referrer: "https://7bu.top"

初步分析问题发现是由于网站启用 SNI,Nginx 反代时默认没有加入以下参数,故无法成功 handshake 上游的 SSL,则导致 502 Bad Gateway 错误:

1
proxy_ssl_server_name on;

什么是 SNI

SNI 有点像邮寄包裹到公寓楼而不是独栋的房子。将邮件邮寄到某人的独栋房子时,仅街道地址就足以将包裹送给收件人。但当包裹进入公寓楼时,除街道地址外,还需公寓号码。否则,包裹可能无法送达收件人或根本无法交付。

许多 Web 服务器更像是公寓大楼而不是独栋房子,因为它们承载多个域名,因此仅 IP 地址不足以指示用户尝试访问哪个域。这可能会导致服务器显示错误 SSL 证书,从而阻止或终止 HTTPS 连接。就像如果没有正确的收件人签名,包裹将无法送到指定的地址一样。

当多个网站托管在一台服务器上并共享一个 IP 地址,并且每个网站都有自己的 SSL 证书,在客户端设备尝试安全连接到其中一个网站时,服务器可能不知道验证哪一个 SSL 证书。

服务器名称指示旨在解决此问题。SNI 是 TLS 协议的扩展,该协议在 HTTPS 中使用。包含在握手流程中,以确保客户端设备能够尝试访问网站的正确 SSL 证书。该扩展使得可以在 TLS 握手期间指定网站的主机名或域名,而不是在握手之后打开 HTTP 连接时指定。

解决方法

将下面的代码加入到 Nginx 配置文件的 location 块中,注意将 7bu.top 改为要反代的域名:

1
2
proxy_ssl_name 7bu.top;
proxy_ssl_server_name on;

某塔发向代理配置文件完整示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
location ^~ /
{
proxy_pass https://c.dusays.com:443;
proxy_set_header Host 7bu.top;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_ssl_name 7bu.top;
proxy_ssl_server_name on;
# proxy_hide_header Upgrade;

add_header X-Cache $upstream_cache_status;
#Set Nginx Cache


if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" )
{
expires 1m;
}
proxy_ignore_headers Set-Cookie Cache-Control expires;
proxy_cache cache_one;
proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 304 301 302 2440m;
}

CDN 设置项

这种情况一般出现在 Nginx 反代,偶尔使用 CDN 时也会出现这个问题,大多都是配置 CDN 的时候没有设置 SNI 导致的问题。可以通过设置回源 HOST 来解决,下图以 99CDN 面板为例:

评论