什么是SNI?
随着IPv4地址的短缺,为了让多个域名复用一个IP,在HTTP服务器上引入了虚拟主机的概念。服务器可以根据客户端请求中不同的host,将请求分发给不同的域名(虚拟主机)来处理。
但是,在一个被多个域名(虚拟主机)共享IP的HTTPS服务器中,由于在握手建立之前服务器无法知道客户端请求的是哪个host,所以无法将请求交给特定的虚拟主机。然而,要完成握手,又必须读取虚拟主机中配置的证书信息。
Server name indication(简称,SNI)就是用来解决这个矛盾问题的。SNI要求客户端在与服务器握手时就携带需要访问的域名的host信息。这样,服务器就知道需要用哪个虚拟主机的证书与客户端握手并建立TLS连接。
SNI最早在2004年被提出,目前主流的浏览器、服务器和测试工具都已支持SNI。
为什么使用DDoS高防和Web应用防火墙必须要求客户端支持SNI?
DDoS高防和Web应用防火墙(WAF)在反向代理HTTPS业务时,需要代理客户端去和真实服务器(RS)进行交互,所以需要在配置HTTPS防护时上传证书和私钥。真实的DDoS高防IP和WAF服务器的数量是有限的,面对数以万计的域名显然无法实现一个域名一台物理服务器的配置,所以整个DDoS高防和WAF服务集群必然存在多个域名复用相同的服务器。因此,客户端必须支持 SNI,才能与DDoS高防和WAF进行正常交互。
如果使用不支持SNI的浏览器访问DDoS高防或WAF服务防护的网站,DDoS高防或WAF因无法确认客户端请求的是哪个域名,无法调取对应的虚拟主机证书与客户端交互,只能使用内置的缺省证书与客户端连接。在这种情况下,在客户端浏览器上会出现“服务器证书不可信”的提示。
说明 即使真实服务器只有一个域名(没有复用IP的情况),由于DDoS高防或WAF服务需要在中间进行反向代理,而客户端必须先与DDoS高防或WAF建立连接,所以客户端依然需要支持SNI。
解决方案
服务器端
配置您的服务器,使其支持SNI。
具体请参见以下文档:
- Nginx 服务器:同一个IP上配置多个HTTPS主机
- Apache 服务器:apache mod_gnutls实现多HTTPS虚拟主机
客户端
对于不支持SNI的客户端,建议您采用以下解决方案:
- 建议您的用户使用新版本的浏览器,例如Google Chrome、Firefox等。
- 不要在DDoS高防服务中配置七层网站防护,而只采用四层端口转发的方式配置网站防护。
说明 配置四层端口防护将无法防御CC攻击。
SNI兼容性
说明 SNI兼容TLS 1.1及以上版本的协议,但与SSL协议不兼容。
- 支持的桌面版浏览器:
- Chrome 5及以上版本
- Chrome 6及以上版本
- Firefox 2及以上版本
- Internet Explorer 7及以上版本(仅支持Windows Vista、Windows Server 2008及以上版本操作系统。在 Windows XP系统中,任何版本的IE浏览器都不支持SNI。)
- Konqueror 4.7及以上版本
- Opera 8及以上版本
- Safari 3.0及以上版本(仅支持Windows Vista、Windows Server 2008及以上版本操作系统,或Mac OS X 10.5.6及以上版本操作系统。)
- 支持的手机端浏览器:
- Android 3.0 Honeycomb及以上版本
- iOS 4及以上版本
- Windows Phone 7及以上版本
- 支持的服务器:
- Apache 2.2.12及以上版本
- Apache Traffic Server 3.2.0及以上版本
- Cherokee
- HAProxy 1.5及以上版本
- IIS 8.0及以上版本
- Lighttpd 1.4.24及以上版本
- LiteSpeed 4.1及以上版本
- Nginx 0.5.32及以上版本
- 支持的命令行:
- cURL 7.18.1及以上版本
- wget 1.14及以上版本
- 支持的库:
- GNU TLS
- JSSE (Oracle Java) 7及以上版本(仅作为客户端)
- libcurl 7.18.1及以上版本
- NSS 3.1.1及以上版本
- OpenSSL 0.9.8j及以上版本
- OpenSSL 0.9.8f及以上版本(需配置flag)
- Qt 4.8及以上版本