服务器名称指示(英语:Server Name Indication,简称SNI)是一个扩展的TLS计算机联网协议,在该协议下,在握手过程开始时客户端告诉它正在连接的服务器要连接的主机名称。这允许服务器在相同的IP地址和TCP端口号上呈现多个证书,并且因此允许在相同的IP地址上提供多个安全(HTTPS)网站(或其他任何基于TLS的服务),而不需要所有这些站点使用相同的证书。它与HTTP/1.1基于名称的虚拟主机的概念相同,但是用于HTTPS。所需的主机名未加密, 因此窃听者可以查看请求的网站。
简介服务器名称指示(英语:Server Name Indication,简称SNI)是一个扩展的TLS计算机联网协议,在该协议下,在握手过程开始时客户端告诉它正在连接的服务器要连接的主机名称。这允许服务器在相同的IP地址和TCP端口号上呈现多个证书,并且因此允许在相同的IP地址上提供多个安全(HTTPS)网站(或其他任何基于TLS的服务),而不需要所有这些站点使用相同的证书。它与HTTP/1.1基于名称的虚拟主机的概念相同,但是用于HTTPS。所需的主机名未加密,因此窃听者可以查看请求的网站。
为了使SNI协议起作用,绝大多数访问者必须使用实现它的Web浏览器。使用未实现SNI浏览器的用户将被提供默认证书,因此很可能会收到证书警告。
问题的背景当进行TLS连接时,客户端从Web服务器请求数字证书。服务器一旦发送证书,客户端就会检查这个证书,并将其尝试连接的名称与证书中包含的名称进行对比。如果发生匹配,则连接正常进行。如果没有找到匹配,则可能会向用户警告该差异,并且可能会中止连接,因为该失配可能表明存在中间人攻击。不过,某些应用程序允许用户绕过警告继续进行连接,由用户承担信任证书以及连接的责任。
一个证书覆盖多个主机名是可以做到的。X.509v3规范引入了subjectAltName字段,该字段允许一个证书指定多个域名,并在通用名和subjectAltName字段中使用通配符。
然而,由于缺少所有名称的完整列表,可能很难甚至不可能获得涵盖服务器将负责的所有名称的单个证书。负责多个主机名的服务器可能需要为每个名称(或一组名称)提供不同的证书。自2005年以来,CAcert已经在虚拟服务器上运行了TLS的不同用法的实验。大多数实验是不理想和不切实际的。例如,可以使用subjectAltName来包含单个证书中由一个人控制的多个域名。每当域名列表更改时,必须重新发布此类“统一通信证书”。
基于名称的虚拟主机允许多个DNS主机名由同一IP地址上的单个服务器(通常为Web服务器)托管。为了实现这一点,服务器使用客户端提供的主机名作为协议的一部分(对于HTTP,名称显示在主机头中)。但是,当使用HTTPS时,TLS握手发生在服务器看到任何HTTP头之前。因此,服务器不可能使用HTTP主机头中的信息来决定呈现哪个证书,并且因此只有由同一证书覆盖的名称才能由同一IP地址提供。
实际上,这意味着对于安全浏览来说,HTTPS服务器只能是每个IP地址服务一个域名(或一组域名)。为每个站点分配单独的IP地址会增加托管成本,因为对IP地址的请求必须为区域互联网注册机构提供证据而且现在IPv4地址已用尽。其结果是,许多网站在IPv4上使用安全通信实际上都受到了限制。IPv6地址空间未用完,因此使用IPv6提供的网站不受此问题的影响。
SNI如何解决此问题SNI通过让客户端发送虚拟域名的名称作为TLS协商的一部分来解决此问题。这使服务器能够提前选择正确的虚拟域名,并向浏览器提供包含正确名称的证书。因此,对于实现SNI的客户端和服务器,具有单个IP地址的服务器可以在获取公共证书不现实的情况下提供一组域名。
SNI在2003年6月的RFC 3546,《传输层安全(TLS)扩展》中加入到IETF的Internet RFCs中。最新版本的标准是RFC 6066。
实现在2004年,EdelKey项目做了一个用于将TLS/SNI添加到OpenSSL中的补丁。在2006年,这个补丁被移植到OpenSSL的开发分支,并在2007年由OpenSSL 0.9.8支持(首次发布在0.9.8f)。
一个应用程序要实现SNI,它使用的TLS库必须实现SNI,并且该应用程序必须将主机名传递给TLS库。其他复杂的问题有,TLS库可以包括在应用程序中或者作为底层操作系统的组件。因此,一些浏览器在任何操作系统上运行时都能实现SNI,而其他浏览器仅在某些操作系统上运行时才能实现SNI。
安全性由于SNI信息并非加密的,允许审查者区分出“真实”和“虚假”的服务或者识别出用户访问的网站域名。现已被部分国家用于互联网审查。
域前置主条目:域前置
域前置通过SNI中使用虚假无害的域名信息,已经被TLS加密的应用层才使用真实的域名信息,将真实流量隐藏在看似无害的流量中,从而使审查者无法区别出来,要么一律放行,要么带有严重附加伤害的一刀切封锁。
Google和CloudFront曾启用该技术的支持,之后停止了,被认为是受到俄罗斯政府的压力,防止Telegram利用该技术来规避审查。
加密服务器名称指示(ESNI)作为TLS的标准扩展实现,TLS 1.3将通过支持加密SNI以解决这个问题。目前,Cloudflare、Mozilla、Fastly和苹果的开发者已开始制定了关于加密服务器名称指示(Encrypted Server Name Indication)的草案。
Cloudflare的联合创始人兼首席执行官Matthew Prince曾表示,传统SNI“绝对是加密装甲中的最后一个缝隙”。1
本词条内容贡献者为:
胡启洲 - 副教授 - 南京理工大学