访问https SocketException:Connection reset

线上业务遇到了一个奇怪的事情,服务访问https域名有问题,日志里报错大量的connection reset 。之前一直都好着啊,怎么突然就报这个错。浏览器访问了一下https的网站发现没问题啊。怎么java服务访问就有问题了。


报错日志

抓包

遇到这种网络上的问题,就不要猜了,先tcpdump一下,再wireshark分析下吧。
抓到的网络包如下:


wireshark抓包

分析tcp stream 发现,emmm,为什么只发了一个client hello 就给我reset了。这是什么操作?让我们来看一下我的打招呼的方式有问题吗?


tls client hello阶段

点开,似乎没啥问题啊,这里是TLS 1.0。反正问题已经定位了,首先这是服务端问题,不是我客户端问题。因为我就发了一个client hello,服务端就reset我。这明显不是我客户端的锅啊,而且问题还是再TLS握手阶段出的问题。因为连 TLS 过程都还没有建立好呢。
好吧,问题是服务端,而且是nginx这块,因为TLS的加解密是nginx这块在做的。

分析

难道是nginx的配置没写支持TLS 1.0 。因为前段时间对nginx做了一次迁移,但似乎我也没改域名的配置啊。看看配置。


nginx ssl 配置

对啊。server 块中 ssl_protocols TLSv1 ,这不就是TLS1.0 么。怎么回事。。。
算了,那就nginx这块再抓包吧。。。在nginx这块抓包发现,数据包是TLS1.0 全部被reset了。好吧,应该就是nginx这块不支持TLS1.0 的问题。但是我配置文件明明是写的支持啊???

杀手锏

看来要第三方分析一下该域名了。
https://www.ssllabs.com/ssltest
用ssl test 测试一下 我们这个网站支持什么样的客户端。

证书支持的 加密套件版本

这里是我已经更正nginx后的截图,源截图是TLS 1.0 显示的是No
好吧,果然不支持。靠~ 那就是nginx不支持 TLS1.0 的事实铁定了。
回到问题源点,nginx到底是出了什么问题?最后想到了http块。

问题解决

原来是http块也配置了 ssl_protocols TLSv1.1 TLSv1.2; 单单忘了TLSv1 。这导致了 http块 覆盖了 server 块的内容,所以TLS1 nginx不支持。导致的reset。

使用opensll 测试一下:

$ openssl s_client --connect xxx.xxx.mi.com:443 -showcerts -tls1
CONNECTED(00000003)
depth=2 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
verify return:1
depth=1 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http://certs.godaddy.com/repository/, CN = Go Daddy Secure Certificate Authority - G2
verify return:1
.....

通了。。。

你可能感兴趣的:(访问https SocketException:Connection reset)