SNI问题

问题现象

如果客户端不支持sni,可能会导致如下现象:

  • 手机APP客户端,ios客户端可以正常访问,而Android客户端无法正常打开
  • 浏览器打开网站,显示证书不可信

问题原因

随着IPv4地址的短缺,为了让多个域名复用一个IP地址,在HTTP服务器上引入了虚拟主机的概念,服务器可以根据客户端请求中不同的host来将请求交给不同的域名(虚拟主机)来处理。

但在一个被多个域名(虚拟主机)共享IP的HTTPS服务器中,浏览器在访问一个HTTPS站点时,先与服务器建立SSL连接,建立连接的第一步就是请求服务器的证书。而服务器在发送证书的时候,是不知道浏览器访问的是哪个域名的,所以不能根据不同域名发送不同的证书。

SNI (Server Name Indication)是为了解决一个服务器使用多个域名和证书的SSL/TLS扩展。一句话简述它的工作原理就是,在连接到服务器建立SSL链接之前先发送要访问站点的域名(Hostname),这样服务器根据这个域名返回一个合适的证书。目前,大多数操作系统和浏览器都已经很好地支持SNI扩展,OpenSSL 0.9.8已经内置这一功能,新版的nginx也支持SNI。

当使用不支持SNI的浏览器访问Web应用防火墙的网站时,Web应用防火墙因不知道客户端请求的是哪个域名,无法调取对应的虚拟主机证书来跟客户端交互,只能使用内置的一个缺省证书去跟客户端握手,这时在客户端浏览器上会提示“服务器证书不可信

服务器端SNI实现

如需要配置服务器支持SNI:

Nginx:https://carey.akhack.com/2017/05/03/nginx%E6%94%AF%E6%8C%81SNI/

客户端SNI实现

SNI是一个很便利的扩展,随着IPv4地址的耗尽,全面支持SNI是趋势。解决方案:

  • 建议用户升级或使用新版本的浏览器,如Chrome、Firefox等(强烈推荐)
  • 如果是微信、支付宝第三方回调。需要让其调用源站IP,绕过Web应用防火墙

常见的SNI支持情况

注意: SNI兼容TLS1.0及以上的协议,但不被SSL支持。

桌面版浏览器支持

  • Chrome 5及以上版本
  • Chrome 6及以上版本(Windows XP)
  • Firefox 2及以上版本
  • IE 7及以上版本(运行在Windows Vista/Server 2008及以上版本版本系统中,在XP系统中任何版本的IE浏览器都不支持SNI)
  • Konqueror 4.7 及以上版本
  • Opera 8 及以上版本
  • Safari 3.0 on Windows Vista/Server 2008 及以上版本, or Mac OS X 10.5.6 及以上版本

手机端浏览器支持

  • Android Browser on 3.0 Honeycomb 及以上版本
  • iOS Safari on 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 及以上版本

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器