原文:https://en.wikipedia.org/wiki/Server_Name_Indication
SNI(Server Name Indication)是一个对TLS计算机网络协议的扩展。握手过程开始时,通过这个协议一个客户端能够指示哪个主机名是它试图去链接的主机名。这允许一个服务器在同一个ip地址和tcp端口号的情况下能够拥有多个证书,因此允许多个安全的(https)网站(或其它使用TLS的服务)在使用同一个ip地址的情况下提供服务,但不要求所有这些网站使用相同的证书。这个机制在概念上等效于HTTP/1.1基于名称的虚拟主机,但对于HTTPS,被请求的主机名称是没有被加密的,所以一个窃听者能够看出那个网站正在被请求。
为了让SNI可用,与其它任何协议一样,绝大多数的访问者必须使用实现了SNI机制的web浏览器。这些没有实现SNI的浏览器的用户,提供了一个默认的证书,因此很可能接收到证书的告警。
内容
1.问题的背景
2.SNI如何修正此问题
3.实现
4.支持
5.参考
6.外部链接
问题背景
--------------------------------------------
当创建一个TLS的链接时,客户端将从web服务器请求一个数字证书。一旦服务器发送了证书,客户端会审查它,同时,会将它尝试去连接的名称与被证书包含在内的名称进行比较。确认是否在链接正常进行时能够匹配。如果不能匹配,用户可能被警告,同时链接可能终止,因为这个不匹配可能指示着中间人攻击的恶意企图。然而,一些应用允许用户的绕开这个警告,继续链接过程,用户会承担信任证书的责任。
一份证书能够包含多个主机名称。 X.509 v3 协议标准介绍了subjectAltName,允许一份证书能够指定超过一个域名,且在通用名称和备用主机领域(subjectAltName fields)中能够使用通配符。
然而,由于预先缺乏一份完整的所有名称的列表,去获取一份包含了服务器负责的所有名称的证书是困难的,甚至是不可能的。负责多个主机名称的服务器可能需要为每一个名称(或者小规模的名称群组)出示一份不同的证书。自2005年以来,CAcert 已经在做虚拟服务器环境中使用TLS的不同方法的实验。大多数的实验的结果是不让人满意,不切实际的。举个例子,可以使用subjectAltName在一个数字证书中包含多个域,但是这是一个证书,意味着所有的域必须被一个人拥有并控制。每次域名列表的变化,“统一通信的证书”必须重新发放。
基于名称的虚拟主机允许多个DNS主机名称被寄宿在使用同一个ip地址的单台服务器(通常是一台web服务器)。为了能实现这个目的,服务器使用客户提供的主机名作为协议的一部分(对于HTTP协议,主机头部提供名称)。然而,当使用HTTPS,TLS握手过程是在服务器查看任何HTTP头部之前发生。因此,对于服务器,使用在HTTP主机头部的信息来确定哪个证书被提供是不可能的,因此被相同证书包含的名称能够提供服务。
在实践中,这意味着一台https服务器只能服务于一个域名(或小规模的域名组)。为每个网站分配一个单独的ip地址增加了托管的花费,因为对ip地址的请求必须适应于区域因特网注册机构,且如今ipv4地址已被用尽了。而ipv6地址空间没有被耗尽,所以为ipv6的服务的网站不会受这个问题的影响。
SNI是如何处理这个问题
------------------------------
SNI通过客户端发送虚拟域的名称解决了这个问题,虚拟域名是作为TLS协商的一部分。这使得服务器去选择正确的虚拟域名,同时提供带有包含了正确名称的证书给浏览器。因此,带有一个单个ip地址的服务器能够为一组域名服务,为这组域名获取一个通用的证书是不切实际的。
SNI在2003年通过RFC3546(TLS扩展)标准协议被加到了IETF的internet RFCs。最近的标准版本是RFC6066.
实现
SNI(Server Name Indication)是一个对TLS计算机网络协议的扩展。握手过程开始时,通过这个协议一个客户端能够指示哪个主机名是它试图去链接的主机名。这允许一个服务器在同一个ip地址和tcp端口号的情况下能够拥有多个证书,因此允许多个安全的(https)网站(或其它使用TLS的服务)在使用同一个ip地址的情况下提供服务,但不要求所有这些网站使用相同的证书。这个机制在概念上等效于HTTP/1.1基于名称的虚拟主机,但对于HTTPS,被请求的主机名称是没有被加密的,所以一个窃听者能够看出那个网站正在被请求。
为了让SNI可用,与其它任何协议一样,绝大多数的访问者必须使用实现了SNI机制的web浏览器。这些没有实现SNI的浏览器的用户,提供了一个默认的证书,因此很可能接收到证书的告警。
内容
1.问题的背景
2.SNI如何修正此问题
3.实现
4.支持
5.参考
6.外部链接
问题背景
--------------------------------------------
当创建一个TLS的链接时,客户端将从web服务器请求一个数字证书。一旦服务器发送了证书,客户端会审查它,同时,会将它尝试去连接的名称与被证书包含在内的名称进行比较。确认是否在链接正常进行时能够匹配。如果不能匹配,用户可能被警告,同时链接可能终止,因为这个不匹配可能指示着中间人攻击的恶意企图。然而,一些应用允许用户的绕开这个警告,继续链接过程,用户会承担信任证书的责任。
一份证书能够包含多个主机名称。 X.509 v3 协议标准介绍了subjectAltName,允许一份证书能够指定超过一个域名,且在通用名称和备用主机领域(subjectAltName fields)中能够使用通配符。
然而,由于预先缺乏一份完整的所有名称的列表,去获取一份包含了服务器负责的所有名称的证书是困难的,甚至是不可能的。负责多个主机名称的服务器可能需要为每一个名称(或者小规模的名称群组)出示一份不同的证书。自2005年以来,CAcert 已经在做虚拟服务器环境中使用TLS的不同方法的实验。大多数的实验的结果是不让人满意,不切实际的。举个例子,可以使用subjectAltName在一个数字证书中包含多个域,但是这是一个证书,意味着所有的域必须被一个人拥有并控制。每次域名列表的变化,“统一通信的证书”必须重新发放。
基于名称的虚拟主机允许多个DNS主机名称被寄宿在使用同一个ip地址的单台服务器(通常是一台web服务器)。为了能实现这个目的,服务器使用客户提供的主机名作为协议的一部分(对于HTTP协议,主机头部提供名称)。然而,当使用HTTPS,TLS握手过程是在服务器查看任何HTTP头部之前发生。因此,对于服务器,使用在HTTP主机头部的信息来确定哪个证书被提供是不可能的,因此被相同证书包含的名称能够提供服务。
在实践中,这意味着一台https服务器只能服务于一个域名(或小规模的域名组)。为每个网站分配一个单独的ip地址增加了托管的花费,因为对ip地址的请求必须适应于区域因特网注册机构,且如今ipv4地址已被用尽了。而ipv6地址空间没有被耗尽,所以为ipv6的服务的网站不会受这个问题的影响。
SNI是如何处理这个问题
------------------------------
SNI通过客户端发送虚拟域的名称解决了这个问题,虚拟域名是作为TLS协商的一部分。这使得服务器去选择正确的虚拟域名,同时提供带有包含了正确名称的证书给浏览器。因此,带有一个单个ip地址的服务器能够为一组域名服务,为这组域名获取一个通用的证书是不切实际的。
SNI在2003年通过RFC3546(TLS扩展)标准协议被加到了IETF的internet RFCs。最近的标准版本是RFC6066.
实现
--------------------------------------------
支持
----------------------------------------------------------
Support[edit]
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 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 | |
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 |
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[8][9] | Since version 9.0.0 | |
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[10] | ||
4th Dimension | Library | No | Not supported in 15.2 or earlier | |
Java | Library | Yes | Since version 1.7 | 2011 |
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.6 | 2014 |
Python | Library | Yes | Supported in 2.x from 2.7.9rc1 and 3.x from 3.2alpha4 (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 |