一, 背景需求
server1-3 使用不同的域名对外提供 https 服务, 用 nginx 作为前端负载均衡器并负责 https 集中解密工作 (以用户访问的域名为依据进行流量分配, 同样的也是以域名为依据来判断应该将哪张证书丢给用户. 即: SNI(Server Name Identification) 功能), 用户为 WIN XP 和 WIN 7(都使用 IE8 浏览器).
- [root@localhost ~]$ nginx -V
- nginx version: nginx/1.14.2
- built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)
- built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled ===> 查看 SNI 状态
二, 工作原理
1, 用户 (WIN XP,WIN 7) 通过 DNS 解析获知 "a.test.com","b.test.com","c.test.com" 三个域名对应的 IP 都为 "192.168.178.154"
2, 用户 (WIN XP,WIN 7) 与 "192.168.178.154" 进行 SSL 握手, 获取相应域名证书后再次向 "192.168.178.154" 发起真正的 http(已加密)请求
3,"192.168.178.154" 收到加密后的 http 请求后先进行解密, 然后再根据相应的策略向后端服务器 server1-3 发起 http 请求(未加密)
4, 后端服务器 server1-3 进行处理后将回应的包发送给 nginx,nginx 将该数据进行加密后再次封装然后发送给用户
三, 出现的问题:
就在大家都觉得这个逻辑十分顺畅的时候问题来了, 我们发现 WIN XP 用户使用 IE 浏览器不能正常访问, 其他系统均可以正常访问
四, 排障:
1,WIN XP 访问同样域名的 80 端口是否正常? 结果: 正常. 说明问题出在 SSL 握手上了
2, 将 WIN XP 和 WIN 7 访问 443 端口的流量进行抓包分析(可以看到 WIN7 的 SSL 握手成功, 而 WINXP 第一次使用 TLSv1 握手失败, 然后自动换用 SSLv3 进行握手, 但依然失败)
3, 为什么 WIN7 发 hello 的时候的 nginx 就会回应 hello, 而 WINXP 发 hello 时 nginx 就会回 Alert 呢? 我们来展开 WIN7 和 WINXP 的 hello 包来仔细看下.(可以看到 WIN7 的 hello 包中携带了 Extension:server_name 字段, 并且里面包含了要访问的域名信息. 而反观 WINXP 则没有该字段)
4, 那 WINXP 换用其他浏览器能不能解决这个问题呢?(换用搜狗浏览器试下, 结果发现可以访问了. 抓包发现搜狗浏览器在发送 SSL 的 hello 包时会携带 Extension:server_name 字段, 并且还附带了一大堆其他参数)
五, 总结:
WINXP 在使用 IE 访问 https 网站时, 对方服务器不能使用 SNI 方式进行分流, 不然会因为不能建立 SSL 握手而访问失败
附: 解决方案
1,WINXP 换用其他浏览器(对于公网服务不现实)
2, 服务端通过 IP 地址进行分流(WINXP 虽不携带访问的域名信息, 但它总有三层包头吧!)(推荐)
3, 服务端全站只用一张大通配证书, 无论用户访问哪个域名都将该证书丢给它(不推荐)
来源: https://www.cnblogs.com/baihualin/p/10965236.html