摘要
本文介绍如何通过调试和排查解决 Nginx 配置中因多个网站使用不一致的 SSL/TLS 配置而导致无法开启 TLSv1.2
的问题。通过逐步排查 SSL 配置、加密套件的兼容性、以及 Nginx 配置的调整,最终实现了所有站点同时支持 TLSv1.2
和 TLSv1.3
协议。
问题引入
因为周末要去广州长隆玩,两天1晚玩三园有点赶,看了小红书,还是得做一些攻略,带着娃去才能从容一些。截了一张图,关于长隆大马戏普通位置选择什么位置,准备写入攻略。因为图床之前配置的,很久没用了,shareX上传图片,结果出现上传失败。
错误日志如下:
Error message:
请求被中止: 未能创建 SSL/TLS 安全通道。
Request URL:
https://img.daogu.work/api/1/upload
Stack trace:
在 System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
在 System.Net.HttpWebRequest.GetRequestStream()
在 ShareX.UploadersLib.Uploader.SendRequestFile(String url, Stream data, String fileName, String fileFormName, Dictionary`2 args, NameValueCollection headers, CookieCollection cookies, HttpMethod method, String contentType, String relatedData)
在正式排查前,做了以下事项:
- 检查shareX版本,为最新版本。
- 检查shareX中关于图床API的配置,因为重新安装过,不知道API key是否重置,去后台重新填写了API key
- 配置.net,修改注册表值,
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319
修改SchUseStrongCrypto
的DWORD值为1,如果是64位系统,在这个位置HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319
也同样修改一下。
上述3项措施做完后,发现仍然报错。
问题排查
增加低版本的协议
nginx对于以下4种协议,全部支持,修改后,发现不起作用,又改回了后面2个。
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
排查客户端还是服务端问题
openssl s_client -connect img.daogu.work:443 -tls1_2
openssl s_client -connect img.daogu.work:443 -tls1_3
这两条命令,分别检测tls1.2和tls1.3这两个协议,我先在一台centos7.6机器上执行,这个机器比较老了,不支持tls1.3,仍然报错,我就跑回服务器本地上执行了,发现tls1.2无法执行,会自动跳到tls1.3.
日志信息:
openssl s_client -connect img.daogu.work:443 -tls1_2
CONNECTED(00000003)
40A76BEB057F0000:error:0A00042E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:../ssl/record/rec_layer_s3.c:1605:SSL alert number 70
由此可以判断在windows上报错,在服务器本机也报错,这个应该是服务端的问题。
排查nginx加密算法
原先的加密配置,对tls1.2缺乏支持
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
修改后的加密配置
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256';
重启nginx
sudo nginx -s reload
这般操作后,仍然无效。这里的加密内容可见参考链接3,禁用了tlsv1和tlsv1.1,仍然无法解决问题。
查看openssl是否支持tlsv1.2
openssl ciphers -v | grep TLSv1.2
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
......
看上面的日志,是支持的。
检查 Nginx 编译的 SSL 库
nginx -v
查看输出中是否包含 --with-openssl
和 OpenSSL 的版本信息,确保其支持 TLSv1.2
,查看结果是支持的。
修改测试网站 –确认服务端tlsv1.2问题
#被强制重定向了,强制使用了tlsv1.3,没有使用tlsv1.2
curl -v --tlsv1.2 https://img.daogu.work
#直接请求
curl -v --tlsv1.2 https://img.daogu.work/login
另外,可以使用sslabs这个网站来检测站点支持的tls的版本情况,具体可以看参考链接2。
搜索解决
nginx tlsv1.2 兼容问题
这个时候,google 搜索 nginx 配置tlsv1.2 兼容
,为什么会想到这个?因为很明显sslabs中显示tlsv1.2没有配置成功,但是我的配置文件中确实有配置tlsv1.2,应该是不兼容的问题。在gpt中问了几个问题,也没有解决。
遇到的坑: 配置tls1.2不生效, 原因是某些站点ssl部分配置不一致。 所以一定要注意: 如果你有多个站点配置了https, 所有的站点的ssl配置部分一定要一致,要不然不会生效。
看了上面的话,顿时明白了,因为我有多个站点,每一部分的ssl配置并不一致。将下列3部分的内容,保持一致,然后重新启动nginx,顺利上传图片,问题解决。
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
ssl_prefer_server_ciphers on;
ssl_prefer_server_ciphers
设置
ssl_prefer_server_ciphers on
的作用是:服务器优先使用其配置的加密套件,而不是允许客户端选择套件。通常,推荐设置为 on
,以保证安全性。但如果有需要,可以尝试将其设置为 off
来测试不同的配置。我有一个服务设置的是off,将其全部修改成on。
问题解决
windows中能顺利访问
![](https://img.daogu.work/images/2024/12/02/chrome_Uui80n2NkD.png)
sslabs成功访问tlsv1.2
![](https://img.daogu.work/images/2024/12/02/chrome_JeUXz2dbxz.png)
广州长隆大马戏普通人的最佳座位
E3和B3区域的最后一排。
结论
本文针对无法上传图片,无法创建安全通道问题,通过一步步排查,最终确认是服务端nginx配置问题。通过将服务端各项服务的ssl的三项配置保持一致,最终成功使得nginx支持tlsv1.2的访问。