有同鞋反馈过来说,A域名通过Https去访问,完全无法建立连接。用B域名则没有任何问题。于是排除了代码这块的问题。 A域名和B域名,在浏览器上打开,则是完全没问题的。于是在小猜会不会是代码有问题。 然后就开始一系列的排查过程。 期间大神也过来帮忙一起排查。
排查过程
在自己的Mac下用了以下命令去测试连接A.test.domain.com,发现请求异常。无法建议连接。
openssl s_client -connect A.test.domain.com:443 openssl s_client -connect A.test.domain.com:443 -tls1 openssl s_client -connect A.test.domain.com:443 -ssl3 openssl s_client -connect A.test.domain.com:443 -debug ... # 返回都是 CONNECTED(00000003) write:errno=54
同样的命令,去请求B.test.domain.com,则没有任何问题。
手机端请求异常的时候进行了抓包。发现连三次握手都没办法正常进行。
开始对比两个域名之间的不同地方。
- A域名和B域名的证书是在两个地方申请的,一个是沃通,一个是StartSSL
- 联系了沃通,对方技术反馈说通过【沃通提供的测试系统】,确定我们证书没有问题。包括证书链什么的都是正常。
- A域名和B域名的证书链不一样
- 尝试了在沃通官网上找对应的根证书追加到A域名证书里,也是无果。
- A域名和B域名的Nginx版本不一样
- A机器用了openresty,B机用了最新的nginx
- 编译参数部分不一样
- ldd nginx,发现两台机器也是一样的。
- A域名和B域名对应的机器不一样
- A域名和B域名长得不一样…
- …
- A域名和B域名的证书是在两个地方申请的,一个是沃通,一个是StartSSL
开始思考人生
开始反过来测试:
- 把A机的域名配置和证书拉到B机,重启nginx。用openssl命令连接,居然可以正常访问。排除证书问题。
- 定位到可能是A机这边的问题。
- A机yum重新安装nginx:不行。
- 在A机重新编译nginx 1.4.4:不行。
- 直接把B机的nginx拉过去用:不行。
- 在A机上用以前旧的nginx新开了一个1443的端口,指定A的域名。测试,可以连接。
- 把旧的nginx还原之前旧的配置,发现又不能连接了。
- 大神怀疑配置有问题。又开始了各种测试。
- 最终发现是“有问题”的nginx下配置了多个ssl站点。
- 把另外一些多配的ssl站点配置移走后,nginx reload后发现A站点的Https域名可以正常访问了。
想到之前大神处理过SVN多ssl站点的问题。但最终是因为svn客户端1.6即之后的版本都默认支持SNI特性解决了。
在自己电脑上和手机上用openssl命令去连接失败,本地的Openssl版本是0.9.8的,手机的应该同样是旧版本。不支持SNI特性。openssl 1.0之后才会默认支持SNI特性。所以会连接失败。
解决方案
- 手机端升级openssl,明显不太现实。
- 服务端这边只开启这一个域名为https,这样也不太现实。
- android这边修改代码去实现。因为A证书之前在手机浏览器上访问是正常的。
后记
- 其实一开始沃通的技术发过来的测试站点上,有列出部分终端不能支持。并且也标识低版本不支持SNI。当时没仔细从这里入手,导致这里瞎测试了一段时间。
- 配置https的域名,需要在配置配上TLSv1,目前很多旧的手机还是只支持到v1的。否则会遇到和我一样的问题。
- 希望大家不要和我踩同样的坑