某日临近下班的时候,收到一个用户不能打开企业邮箱页面的投诉,最终发现是 HTTPS 的问题,这篇文章完整记录了处理过程,解决投诉后,我也在思考问题产生的原因。
收到投诉后,我们的运维同事使用 QQ 远程连接用户桌面(最有效、最快速的问题排查手段)的功能了解具体的情况,初步情况如下:
- Chrome 打开企业邮箱官网(https://mail.sina.net)没有问题。
- 登录 webmail(https://webmail.sina.net)后页面空白。
运维同事使用 Chrome 开发者工具发现 webmail 页面(该页面能够正常输出数据)引入的静态元素(js、css)无法加载,将某一个 js 文件(i0.sinaimg.cn 域名)单独在 Chrome 中打开,页面出现 ERR_SSL_VERSION_OR_CIPHER_MISMATCH 错误。
可能有些同学奇怪,为什么 js 文件打不开就出现空白页面?这和我们的前端开发架构有关,页面的渲染极度依赖 js,如果 js 无法加载整个页面就无法呈现。
看到 ERR_SSL_VERSION_OR_CIPHER_MISMATCH 错误,我***反应是服务器 https 配置兼容性不好或者客户端(Chrome)https 配置支持不够。考虑到只有个别用户投诉,再加上我本来就知道邮箱 https 配置兼容性非常广(支持 tls 1.0、tls 1.1、tls 1.2),所以重点怀疑客户端 https 的问题。
进一步排查发现用户的 Chrome 版本是 36,潜意识认为是用户浏览器版本过低的问题,做了两个检查:
(1)查看该 Chrome 版本是何时发布
(2)查看该 Chrome 版本 https 支持的***版本
通过 SSL Labs User Agent Capabilities 工具(https://www.ssllabs.com/ssltest/clients.html)检测结果如下:
通过上图看出该版本***支持 tls 1.2,不存在 https 版本配置过低的问题。
既然从理论上排除了 Chrome 兼容性问题,我想使用 Chrome 开发者工具【Security】菜单查看具体的 https 报错信息,悲催的是 chrome 36 版本居然没有【Security】菜单。。。***的排查工具无法使用了,该版本的开发者工具如下图:
此时我抓瞎了,继续思考,有两个新的现象进入脑子:
(1)webmail 360 浏览器能够正常访问,IE、Chrome 无法访问,其实这一条信息干扰性极大,让我怀疑还是客户端兼容性的问题。
由于不是我远程连接用户桌面,所以当时也没有查看(也没想到) 360 开发者工具的调试信息,这是非常可惜的一点。
(2)Chrome 访问企业邮箱官网没有问题,这其实是非常重要的一条信息,如果是客户端(IE、Chrome)问题,为啥官网 https 访问没有问题,我打开开发者工具看了一下,发现官网引入的 js 元素域名是 www.sinaimg.cn。
问题逐步清晰了,官网和 webmail 引入的 js 元素域名是不一样的,我们公司所有的静态元素都部署在自有 CDN 上(事后才知道也引入了阿里云 CDN),是否这两个域名配置的证书以及 HTTPS 配置不一样?虽然本就知道公司证书都是 SAN 泛域名证书,所有的域名以及子域名都使用同一张证书,但从严谨的角度考虑,我还是使用SSL Labs SSL Server Test 工具(https://www.ssllabs.com/ssltest/analyze.html)测试 https 配置情况。
这个工具会扫描对应域名所有的 IP,然后显示该 IP 下的证书、HTTPS 配置的具体情况,测试 www.sinaimg.cn 结果如下:
通过上图可见整个配置检测没有问题。接着测试 i0.sinaimg.cn,结果如下:
出现上图的的原因就是 CDN 的某个点的 https 配置(443端口)无法获取到,工具中止了检测。
此时问题逐步清晰了,公司静态池(静态元素)CDN 部署了很多点,是否是某个点 https 配置有问题?CDN 由公司专门团队维护,立刻向他们反馈,五分钟后问题解决。
得到的反馈就是静态池也使用了阿里云的 CDN(最近刚加的点,投诉用户正好访问了这个 CDN 点),而这个 CDN 点居然没有配置支持 https。。。
CDN 同事在阿里云开启 443 https 服务(主要工作是上传 i0.sinaimg.cn 证书)后就解决了问题,我们不禁要追问为这个点什么没有 https 部署,他们的解释是没有接到这个点要支持 https 的需求。。。
对于这个理由,要是我还是当年年少轻狂的我,估计要喷他们了(现在也只能心里喷了),静态池服务早就宣称全站支持 HTTPS 了,为啥还有这问题?CDN 配置是开发人员无法也无需知道的(完全透明),既然全站 HTTPS 了,新增加一个点是不是应该也要支持?怎么能说没有接收到需求呢?我渣浪的甩锅作风还是一如既往。
有些同学不禁要问,这么大的故障,为啥别的产品不受影响呢?原因就在于 i0.sinaimg.cn 这个域名下的服务使用者可能很少,下一阶段我们要尽快将静态元素迁移到 www.sinaimg.cn 域名上。
解决该问题后,我冷静下来思考,为啥 360 浏览器没有问题?同一台机器 DNS 解析难道不是一样的吗?360 连接的 443 服务器难道和 Chrome 连接的 443 服务器不一致?如果不一致,那么 360 浏览器显示正常是可以理解的,如果一致,那就很难解释了。
由于当时没有看到 360 浏览器访问的具体情况,所以我做了一个测试:
- (1)登录阿里云 CDN 控制台,默认 443 端口是关闭的,也就是说故障发生的时候,443 肯定没有开启。
- (2)由于我没有阿里云 CDN 服务,所以做了个模拟,用自己的服务器测试 https://www.simplehttps.com(80 打开,443 关闭),看看 360 浏览器是如何运行的
最终使用 360 浏览器访问该网址,不能成功打开,所以这成了一个悬案了。
通过这件事情,得到的一些体会和想法:
- 排查问题是需要经验的,经验基于技能的掌握程度,冷静的头脑,熟练借助工具。
- 很多问题看上去很复杂,但最终的原因是如此无厘头,这说明整个技术体系是混乱的,是割裂的。
- 实际排查顺序并不是本文描述的那样,也走了很多弯路,如此整理是为了让读者更好的了解排查问题的思路。
- SSL Labs 工具 SSL Server Test 非常好,它是如何检测出一个域名对应的所有 IP 呢?如果有现成解决方案,我打算基于此,写一个简单的小工具,快速诊断出 https 配置情况(更轻量的工具)。