SSL证书返回错误问题排查

运维同学反馈在IE 8和XP的环境下使用https访问chinaacc.com的时候,返回了cdeledu.com的证书。先验证下:
果然是提示证书不安全,然后查看证书,果然是访问chinaacc.com的时候,返回了cdeledu.com的证书。

经过了解,原来是服务器上配置了多个域名的SSL证书,使用低版本浏览器的时候默认返回了配置的第一个证书。
在HTTP协议中,请求的域名作为主机头(Host)放在HTTP Header中,所以服务器端知道应该把请求引向哪个域名,但是早期的SSL做不到这一点,因为在SSL握手的过程中,根本不会有Host的信息,所以服务器端通常返回的是配置中的第一个可用证书。因而一些较老的环境,可能会产生多域名分别配好了证书,但返回的始终是同一个。
直到后来出现了SNI(Server Name Indication),是一项用于改善SSL/TLS的技术,在SSLv3/TLSv1中被启用。它允许客户端在发起SSL握手请求时(具体说来,是客户端发出SSL请求中的ClientHello阶段),就提交请求的Host信息,使得服务器能够切换到正确的域并返回相应的证书。
这里我们抓一下SSL握手的包,看一下ClientHello的内容
发现使用Chrome访问的,证书正常,此时ClientHello中有SNI,如下图所示:

在XP系统使用IE浏览器的时候返回证书错误,发送的ClientHello包中没有SNI,所以会返回配置的第一个证书。
然后我在Window7下使用IE8测试,返回证书是正常的。看来跟操作系统也有关系。
需要注意SNI需要客户端和服务端同时支持才行。例如查看Nginx时候支持
[root@VM_1_112_centos sbin]# ./nginx -V
nginx version: nginx/1.6.3
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)
TLS SNI support enabled
TLS SNI support enabled表示支持SNI。

支持SNI的浏览器、服务器、库
Internet Explorer 7 or later, on Windows Vista or higher. Does not work on Windows XP, even Internet Explorer 8.
Mozilla Firefox 2.0 or later
Opera 8.0 or later (the TLS 1.1 protocol must be enabled)
Opera Mobile at least version 10.1 beta on Android[citation needed]
Google Chrome (Vista or higher. XP on Chrome 6 or newer. OS X 10.5.7 or higher on Chrome 5.0.342.1 or newer)
Safari 2.1 or later (Mac OS X 10.5.6 or higher and Windows Vista or higher)
Konqueror/KDE 4.7 or later
MobileSafari in Apple iOS 4.0 or later
Android default browser on Honeycomb or newer
Windows Phone 7[citation needed]
MicroB on Maemo