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