本文详细阐述了Server Name Indication(SNI)的概念、产生背景、兼容性、以及检验是否支持SNI的方法。

什么是SNI

SNI是为了解决一个服务器使用多个域名和证书的Secure Socket Layer(SSL)/Transport Layer Security(TLS)的一个扩展。它允许服务器在同一IP地址和TCP端口数下支持多张证书,从而允许多个HTTPS网站,或其他服务在TLS的网站,被同一个IP地址而不需要所有的网站使用相同的证书。

SNI产生背景

SSL初期设计是一台服务器只能为一个域名服务。当客户端访问站点时,利用DNS域名解析,向解析到的IP地址(服务器地址)发送请求服务器的证书,然后服务器将自身唯一的证书返回回来,交给客户端验证。通过验证后,按照协商好的加密通道,进行后续通信。这意味着服务器可以在SSL的启动动阶段发送或提交证书。

但随着服务器支持虚拟主机的出现,一台服务器要为多个域名提供服务。继续沿用之前的工作原理,会经常导致服务器端无法知道与客户端所请求域名对应的证书,从而使用错误的数字证书,导致浏览器对用户发出警告。

SNI的设计目的是为了让服务器根据请求来决定为哪个域服务,这个信息通常从HTTP请求头获得。

SNI应用场景

当服务器解析到同一个IP(如:192.168.10.3)下的多个域名(如:domain1.com、domain2.com)在使用默认端口时,你可以安装不同的SSL证书。否则,服务端不能针对不同的域名安装不同的SSL证书。

注意:针对无法支持SNI的服务器,我们推荐安装多域名SSL证书通配符SSL证书

SNI的兼容性

SNI兼容TLS 1.0及以上协议,但不兼容SSL。具体支持清单如下所示:

Software Type Supported Notes Supported since
Internet Explorer Web browser Yes Since version 7 on Vista (not supported on XP) 2006
Mozilla Firefox Web browser Yes Since version 2.0 2006
cURL Command-line tool and library Yes Since version 7.18.1 2008
Safari Web browser Yes Not supported on Windows XP
Google Chrome Web browser Yes Since 6.0[7] 2010
BlackBerry 10 Web browser Yes Supported in all BB10 releases 2013
BlackBerry OS Web browser No Not supported in 7.1 or earlier
elinks Web browser No Not supported in 0.12pre6 or earlier
Windows Mobile Web browser Yes Some time after 6.5
Android default browser Web browser Yes Honeycomb (3.x) for tablets and Ice Cream Sandwich (4.x) for phones 2011
Firefox for Android Web browser Partial Supported for browsing, Sync and other services don't support SNI[8][9]
wget Command-line tool Yes Since version 1.14 2012
Nokia Browser for Symbian Web browser No
Opera Mobile for Symbian Web browser No Not supported on Series60
IBM HTTP Server Web server Yes Since version 9.0.0[10][11]
Apache Tomcat Web server Yes Not supported before 8.5 (backport from 9)
Apache HTTP Server Web server Yes Since version 2.2.12 2009
Microsoft IIS Web server Yes Since version 8 2012
nginx Web server Yes Since version 0.5.23 2007
Jetty Web server Yes Since version 9.3.0 2015
Qt Library Yes Since version 4.8 2011
Mozilla NSS server side Library No [12]
4th Dimension Library No Not supported in 15.2 or earlier
Java Library Yes Since version 1.7 2011
ColdFusion / Lucee Library Yes ColdFusion since Version 10 Update 18, 11 Update 7, Lucee since Version 4.5.1.019, Version 5.0.0.50 2015
Erlang Library Yes Since version r17 2013
Go Library Yes Since version 1.4 2011
Perl Library Yes Since Net::SSLeay version 1.50 and IO::Socket::SSL version 1.56 2012
PHP Library Yes Since version 5.3 2014
Python Library Yes Supported in 2.x from 2.7.9 and 3.x from 3.2 (in ssl, urllib[2]and httplib modules) 2011 for Python 3.x and 2014 for Python 2.x
Ruby Library Yes Since version 2.0 (in net/http) 2011

如何检验是否支持SNI

通过工具(如: Client Hello )抓取SSL握手协议过程中的报文,如果在Client Hello抓取的报文显示SNI扩展内容,表示此客户端支持SNI。这里以Google Chrome浏览器访问亚洲诚信的SSL握手过程为例:
SNI扩展内容

注意:对于不支持SNI的客户端,选择以下任一方法并再次检验:

  • 升级或使用新版本的浏览器(如: Chrome、Firefox等)。
  • 如果是微信、支付宝第三方回调,需要让其调用源站IP。