什么是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。

具体请参考:

客户端

对于不支持 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 及以上版本