Server Name Indication(SNI)

转载自: http://openwares.net/misc/server_name_indication.htmlhtml

 

Server Name Indication是用来改善SSL(Secure Socket Layer)和TLS(Transport Layer Security)的一项特性。它容许客户端在服务器端向其发送证书以前请求服务器的域名。这对于在虚拟主机模式使用TLS是必要的。nginx

TLS背景web

加密一个面向流的通信会话最经常使用的方法之一就是使用TLS协议。好比,当用户在浏览器的地址栏里面输入https时就是在使用这个协议。windows

为了确认用户想要链接的站点就是浏览器实际链接到的站点,TLS使用包含站点域名的数字签名证书。客户端软件(好比浏览器)一般信任这个证书,若是这个证书是由其内置信任的认证机构签发的。
在TLS启动阶段,客户端软件比较用户输入的URI的域名部分与在服务器证书里面找到的域名部分,若是比较失败,浏览器会提示用户,这个站点的证书存在问题。

缺点后端

SSL v2的设计顺应经典的公钥基础设施PKI(public key infrastructure)设计,后者认为一个服务器只提供一个服务从而也就只使用一个证书。这意味着服务器能够在TLS启动的早期阶段发送或提交证书,由于它知道它在为哪一个域服务。浏览器

HTTP服务器开启虚拟主机支持后,每一个服务器经过相同的地址能够为不少域提供服务。服务器检查每个请求来决定它在为哪一个域服务。这个信息一般从HTTP请求头得到。不幸的是,当设置了TLS加密,服务器在读取HTTP请求里面的域名以前已经向客户端提交了证书,也就是已经为默认域提供了服务。tomcat

所以,这种为虚拟主机提供安全的简单途径常常致使使用了错误的数字证书,从而致使浏览器对用户发出警告。安全

钓鱼链接服务器

实际上,这意味着每个HTTP服务器只能为一个域提供安全浏览。而事实上每个web服务器都为不少域提供服务,结果就是其余的域没法使用安全通讯,从而处于危险境地。此外,安全浏览的缺少使浏览器没法认证服务器,亦即它没法校验站点是否真的是属于宣称它的那我的或实体。钓鱼的一个重要因素是他们企图经过虚假站点来获取用户的信息。使用SSL或者TLS安全链接,浏览器能够基于它的证书来认证站点。钓鱼站点不会做为一个欺骗性的站点获得认证,浏览器会警告这个安全风险。然而,没有安全HTTP就没有标准的方法去认证服务器,使这种钓鱼的企图很容易就能实现。app

修正

一个叫作SNI的TLS扩展经过发送虚拟域的名字作为TSL协商的一部分修正了这个问题。这会使服务器更早的切换到正确的虚拟域,而且发送给浏览器包含正确名字的数字证书。

行动

在2005年,人们意识到从SSL v2到TLS没有很容易的升级路径,而且站点不得不升级他们的软件来。为了尽快的推动,Mozilla宣告彻底抛弃对SSL v2的支持。Firefox社区确信其他的站点会升级他们的服务器到SSL v3或TLS v1。

从2005年开始,CAcert在虚拟服务器上用不一样的方法使用TLS来进行试验,大部分试验是不满意而且不实际的。好比,可使用subjectAltName在一个数字证书中包含多个域,可是这是一个证书,意味着全部的域必须被一我的拥有并控制,而且每次域列表发生变化,证书必须从新发放。

2004年,EdelKey project为OpenSSL里面的TLS/SNI开发了一个补丁。2006年这个补丁进入OpenSSL的开发分支,2007年,它被向后移植到了OpenSSL 0.9.8,也就是当前的发行版本。

支持情况

支持SNI的浏览器

* Mozilla Firefox 2.0 or later
* Opera 8.0 or later (the TLS 1.1 protocol must be enabled)
* Internet Explorer 7 or later on Windows Vista or higher
* Google Chrome (Vista, not XP)
* Safari 3.2.1 Mac OS X 10.5.6

支持SNI的服务器

* Apache 2.2.12 or later using mod_ssl (or alternatively with experimental mod_gnutls)
* Cherokee if compiled with TLS support
* Versions of lighttpd 1.4.x and 1.5.x with patch
* Nginx with an accompanying OpenSSL built with SNI support
* acWEB with OpenSSL 0.9.8j and later (on Windows)

支持SNI的库

* Mozilla NSS 3.11.1 client side only
* OpenSSL
0.9.8f (released 11 Oct 2007) – not compiled in by default, can be compiled in with config option ‘–enable-tlsext’.
0.9.8j (released 07 Jan 2009) – now compiled in by default
Unreleased 0.9.9 is likely to include SNI compiled in by default.
* GNU TLS

不支持SNI的操做系统,浏览器和库

客户端

* Internet Explorer 6 or earlier and any IE version on Windows XP , windows 2003 or earlier
* Konqueror/KDE in any version

服务器端

* Microsoft Internet Information Server IIS (As of 2009).
* Apache Tomcat 8 or earlier

* Qt
* Mozilla NSS server side
* Python

windows和IE

能够看得出,windows XP和windows 2003 server系统上的任何IE版本浏览器都是不支持SNI的, vista及之后系统上的IE 7及更高版本的IE浏览器支持SNI。IE6及更早版本的IE浏览器在任何系统上都是不支持SNI的。

tomcat

tomcat当前的稳定版8尚不支持SNI,tomcat 9才会支持,之后可能会backport到tomcat 8和7。可使用nginx反向https代理后端的tomcat,参见[2]

SNI测试

用浏览器或其余https客户端好比wget等访问SNI测试站点https://sni.velox.ch/便可以知道浏览器或客户端是否支持SNI。

References:
[1]Server Name Indication
[2]Setting up NGINX SSL reverse proxy for Tomcat
[3]HowTo setup Tomcat serving two SSL Certificates using SNI?

相关文章
相关标签/搜索