Server Name Indication
Server Name Indication (SNI) is an extension to the TLS computer networking protocol[1] by which a client indicates which hostname it is attempting to connect to at the start of the handshaking process. This allows a server to present multiple certificates on the same IP address and TCP port number and hence allows multiple secure (HTTPS) websites (or any other Service over TLS) to be served off the same IP address without requiring all those sites to use the same certificate. It is the conceptual equivalent to HTTP/1.1 name-based virtual hosting, but for HTTPS. The desired hostname is not encrypted,[2] so an eavesdropper can see which site is being requested.
To make SNI useful, as with any protocol, the vast majority of visitors must use web browsers that implement it. Users whose browsers do not implement SNI are presented with a default certificate and hence are likely to receive certificate warnings.
Background of the problem
When making a TLS connection the client requests a digital certificate from the web server. Once the server sends the certificate, the client examines it and compares the name it was trying to connect to with the name(s) included in the certificate. If a match occurs the connection proceeds as normal. If a match is not found the user may be warned of the discrepancy and the connection may abort as the mismatch may indicate an attempted man-in-the-middle attack. However, some applications allow the user to bypass the warning to proceed with the connection, with the user taking on the responsibility of trusting the certificate and, by extension, the connection.
It is possible for one certificate to cover multiple hostnames. The X.509 v3 specification introduced the subjectAltName field which allows one certificate to specify more than one domain and the usage of wildcards in both the common name and subjectAltName fields.
However it may be difficult - or even impossible, due to lack of a full list of all names in advance - to obtain a single certificate that covers all names a server will be responsible for. A server that is responsible for multiple hostnames is likely to need to present a different certificate for each name (or small group of names). Since 2005, CAcert has run experiments on different methods of using TLS on virtual servers.[3] Most of the experiments are unsatisfactory and impractical. For example, it is possible to use subjectAltName to contain multiple domains controlled by one person[4] in a single certificate. Such "unified communications certificates" must be reissued every time the list of domains changes.
Name-based virtual hosting allows multiple DNS hostnames to be hosted by a single server (usually a web server) on the same IP address. To achieve this the server uses a hostname presented by the client as part of the protocol (for HTTP the name is presented in the host header). However, when using HTTPS the TLS handshake happens before the server sees any HTTP headers. Therefore, it is not possible for the server to use the information in the HTTP host header to decide which certificate to present and as such only names covered by the same certificate can be served from the same IP address.
In practice, this means that an HTTPS server can only serve one domain (or small group of domains) per IP address for secured browsing. Assigning a separate IP address for each site increases the cost of hosting, since requests for IP addresses must be justified to the regional internet registry and IPv4 addresses are now exhausted. The result is that many websites are effectively constrained from using secure communications over IPv4. IPv6 address space is not exhausted, so websites served using IPv6 are unaffected by this issue.
How SNI fixes the problem
SNI addresses this issue by having the client send the name of the virtual domain as part of the TLS negotiation.[2] This enables the server to select the correct virtual domain early and present the browser with the certificate containing the correct name. Therefore, with clients and servers that implement SNI, a server with a single IP address can serve a group of domain names for which it is impractical to get a common certificate.
SNI was added to the IETF's Internet RFCs in June 2003 through RFC 3546, Transport Layer Security (TLS) Extensions. The latest version of the standard is RFC 6066.
Implementation
In 2004, a patch for adding TLS/SNI into OpenSSL was created by the EdelKey project.[5] In 2006, this patch was then ported to the development branch of OpenSSL, and in 2007 it was back-ported to OpenSSL 0.9.8 (first released in 0.9.8f[6]).
For an application program to implement SNI, the TLS library it uses must implement it and the application must pass the hostname to the TLS library. Further complicating matters, the TLS library may either be included in the application program or be a component of the underlying operating system. Because of this, some browsers implement SNI when running on any operating system, while others implement it only when running on certain operating systems.
Support
Software | Type | Supported | Notes | Supported since |
---|---|---|---|---|
Internet Explorer | Web browser | Yes | Since version 7 on Vista (not supported on XP)[7] | 2006 |
Mozilla Firefox | Web browser | Yes | Since version 2.0[8] | 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 OS | Web browser | Yes | 7.2 or later | |
Windows Mobile | Web browser | Yes | Some time after 6.5[9] | |
Android default browser | Web browser | Yes | Honeycomb (3.x) for tablets and Ice Cream Sandwich (4.x) for phones[10] | 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 | No[11][12] | ||
Apache Tomcat | Web server | Yes | Not supported in 8 or earlier[13] | |
Apache HTTP Server | Web server | Yes | Since version 2.2.12[14] | 2009 |
Microsoft IIS | Web server | Yes | Since version 8[15] | 2012 |
Qt | Library | Yes | Since version 4.8[16] | 2011 |
Mozilla NSS server side | Library | No[17] | ||
Java | Library | Yes | Since version 1.7 | 2011 |
Go | Library | Yes | Since version 1.4 | 2011 |
Perl | Library | Yes | Since Net::SSLeay version 1.50[18] and IO::Socket::SSL version 1.56[19] |
2012 |
PHP | Library | Yes | Since version 5.6[20][21] | 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)[22][23] |
2011 for Python 3.x and 2014 for Python 2.x |
References
- ^ "Server Name Indication". Transport Layer Security (TLS) Extensions. IETF. p. 8. sec. 3.1. doi:10.17487/RFC3546. RFC 3546.
- ^ a b "TLS Server Name Indication". Paul's Journal.
- ^ "CAcert VHostTaskForce". CAcert Wik.
- ^ "What is a Multiple Domain (UCC) SSL Certificate?".
- ^ "EdelKey Project".
- ^ "OpenSSL CHANGES".
- ^ a b "IIS 8 and IIS 8.5 SNI Browser Support". DigiCert. Retrieved 31 December 2015.
- ^ https://bugzilla.mozilla.org/show_bug.cgi?id=116169#c26
- ^ "Understanding Certificate Name Mismatches". Blogs.msdn.com. Retrieved 8 March 2011.
- ^ "Android issue 1290 - Https websites that support Server Name Indication (SNI) don't work". Code.google.com. 1 December 2010. Retrieved 13 December 2011.
- ^ "IBM HTTP Server SSL Questions and Answers". Publib.boulder.ibm.com. Retrieved 8 March 2011.
- ^ "IHS 8 powered by Apache 2.2.x ?". Publib.boulder.ibm.com. Retrieved 8 March 2011.
- ^ "Stack Overflow post by a Tomcat Comitter". Retrieved 28 October 2014.
- ^ "CHANGES: Server Name Indication support is listed under the changes for Apache 2.2.12". Apache Software Foundation.
- ^ "Server Name Indication (SNI) with IIS 8 (Windows Server 2012)". Retrieved 8 January 2016.
- ^ "QTBUG-1352. It would be useful if QSslSocket supports TLS extensions such as Server Name Indication as per RFC 3546". Qt Bug Tracker. Retrieved 15 April 2011.
- ^ "Implement TLS Server Name Indication for servers". Bugzilla@Mozilla. 11 November 2006. Retrieved 30 October 2012.
- ^ "Net::SSLeay - Low level API: Server side Server Name Indication (SNI) support".
- ^ "IO::Socket::SSL - SNI Support".
- ^ "Add encrypted server SNI support · php/php-src@fad14e3".
- ^ "PHP: SSL context options".
- ^ "Support TLS SNI extension in ssl module". Bugs.python.org. Retrieved 8 March 2011.
- ^ "PEP 466: backport ssl changes". Bugs.python.org. Retrieved 23 March 2016.
External links
- RFC 6066 (obsoletes RFC 4366 (which obsoleted RFC 3546))
- https://alice.sni.velox.ch/ Test client-side TLS SNI capability