Server Name Indication (SNI) with IIS 8 (Windows Server 2012)
Here is the link: SSL Scalability with IIS 8.
In this blog I will discuss specifically about Server Name Indication aka SNI. We will learn how scalability is achieved through this.
During SSL handshake when the client sends a HTTPS request (Client Hello) to the web server, the HTTP headers are not available to the server. Once the SSL handshake is completed the client will encrypt the headers and send the encrypted HTTP request to the server. Therefore server cannot access the HTTP headers or the content until the request is encrypted. Hence, the problem.
Before decrypting the request the only information available to the server will be the IP Address and the Port number. This is available through the TCP headers as only the HTTP headers are encrypted. This leads to the limitation of only one certificate can be bound to a combination of
Legacy SSL handshake between client and IIS 7.x and earlier
All the SSL bindings on Windows OS prior to Windows Server 2008 R2/Windows 7 can be found under following registry key:
HKLM\SYSTEM\CurrentControlSet\Services\HTTP\Parameters\SslBindingInfo
Even if the client provides the server name in the client hello, the server wasn’t capable of using it. This is addressed in IIS 8. To solve this problem associated with SSL/TLS, IETF added a new TLS extension called Server Name Indication. It is mentioned in the following RFC’s
You could also read about SNI on Wikipedia.
As mentioned in the above RFC’s a TLS extension called ServerName was introduced to tackle this problem. Below is a snippet from RFC 6066.
TLS does not provide a mechanism for a client to tell a server the name of the server it is contacting. It may be desirable for clients to provide this information to facilitate secure connections to servers that host multiple ‘virtual’ servers at a single underlying network address.
In order to provide the server name, clients MAY include an extension of type "server_name" in the (extended) client hello. The "extension_data" field of this extension SHALL contain "ServerNameList" where:
struct {
NameType name_type;
enum {
opaque HostName<1..2^16-1>;
struct {
Now the client can send the hostname it wants to access over https as a part of client hello. This helps the server to associate the client hello to a specific request and thus we overcome the limitation which was imposed earlier.
If you were to capture a network trace of SNI complaint browser accessing a HTTPS site you could see this extension as part of the client hello. I captured a Wireshark trace while accessing https://www.outlook.com. I filtered the trace by SSL and searched for Client Hello.
snapshot of a SSL trace in Wireshark
***IMPORTANT***
One important thing to note here is that SNI is part of the Client Hello. So it is the client browsers that need to support this extension. Most of the current day browsers support SNI.
However, there are few browsers out there that don’t support SNI. For example, on Windows OS any version of IE running on Windows XP or lower versions do not support SNI. Vista onwards support for SNI was included for IE 7 and higher. There is a good list on Wikipedia on browsers that provide support for SNI. Below is a snippet from Wikipedia:
List of SNI Compliant Browsers:
So far I was trying to explain the basics of SNI. We need to know this to understand the server side solution for this.
NOTE: SNI is available only on IIS 8 and may be future versions. It is not available on any of the previous versions of IIS like IIS 7.x, IIS6 etc.
SNI on IIS 8
IIS 8 supports Server Name Indication. This is enabled by default and no separate installation is required. Now while adding a HTTPS binding for a website on IIS 8, the option to enable SNI is available. This is how the UI looks like:
There are 2 things to remember when enabling SNI for a specific site on the server.
How does the IIS know if a specific binding uses SNI?
When a SSL bindings is added for a site, there is also a small change in the configuration file i.e., the applicationhost.config. This is how the binding section looks like:
</bindings></font>
The highlighted attribute called sslFlags is. This attribute tells IIS what type of binding it is. This flag can be thought of as a doing an OR operation on 2 variables x and y. Below table would give you a gist of what this flag signifies.
sslFlags
Description
Legacy SSL binding. Neither uses SNI nor CCS
1
1
SSL binding using SNI.
1
2
SSL binding uses CCS, but SNI is not enforced.
1
1
3
SSL binding uses CCS, but SNI is enforced.
Changes in Registry
In IIS 8 we have a new registry key where all the SNI bindings are stored. I had mentioned this in my previous blog post. This location of this registry key is
HKLM\SYSTEM\CurrentControlSet\Services\HTTP\Parameters\SslSniBindingInfo
Executing the following command “netsh http show sslcert” will read this key and show a formatted output as shown below:
SSL Certificate bindings:
</font></span>————————-
</td> </tr> </tbody> </table>
So now we have 3 types of SSL bindings:
There is a small problem that the administrators have to take care of while configuring SSL bindings to use SNI. If a non-SNI compliant browser connects to a site on which SNI is enforced, as I mentioned earlier the SSL handshake would fail.
To tackle this there is a fall-back mechanism in IIS where the it would try to determine a binding with the combination of IP:Port, if this is not present, then the SSL handshake fails. For this the IIS admin has to configure a binding which neither uses SNI nor CCS.
If legacy binding doesn’t exist, then the IIS UI will throw an alert as shown below. This message is a warning saying that there is no legacy binding, so in case of a failure the SSL handshake would fail.
No default SSL site has been created. To support browsers without SNI capabilities, it is recommended to create a default SSL site.
SSL Handshake between a SNI compliant browser and SNI Compliant Server
Below are the steps involved during SSL handshake between a SNI compliant Client and a site hosted on IIS 8 on which a SSL binding is configured to use SNI.
HKLM\SYSTEM\CurrentControlSet\Services\HTTP\Parameters\SslSniBindingInfo</span></font></div> </li>
More Information:
You could refer the following links on additional information on this topic:
http://en.wikipedia.org/wiki/Server_Name_Indication
http://learn.iis.net/page.aspx/1096/iis-80-server-name-indication-sni-ssl-scalability
http://blogs.iis.net/yaminij/archive/2012/06/25/sni-server-name-indication-readiness-tool-draft.aspx
East Lake Standards Track [Page 5]
</p>
RFC 6066 TLS Extension Definitions April 2011
</p>
3. Server Name Indication
select (name_type) {
case host_name: HostName;
} name;
} ServerName;
host_name(0), (255)
} NameType;
ServerName server_name_list<1..2^16-1>
}ServerNameList;
<binding protocol="https" bindingInformation="*:443:SNI.IIS8.com"</strong></font> sslFlags="1" /> </p>
Using
CCS
Using
SNI
C:\>netsh http show sslcert </p>
Hostname:port : SNI.IIS8.com:443
Certificate Hash : 8d90a17d2851f802b0a5619bf695b03544b8f5cb
Application ID : {4dc3e181-e14b-4a21-b022-59fc669b0914}
Certificate Store Name : My
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Disabled
Negotiate Client Certificate : Disabled