Server Name Identification or SNI is the functionality by which a virtual hostname can be used to complete the SSL negotiation for https traffic.
In the real world this essentially means that you can have multiple sites running within IIS, each with their own SSL certificate/s but all bound to the same IP address.
This is great, especially for webservers serving multiple sites from the same IIS instance. An example might be for multi tenant hosting environments where it reduces or removes the legacy and potentially costly requirement to bind each SSL enabled site to a specific public IP address.
While this is not exactly ‘news’, I intend to describe how this can be leveraged in test/dev environments. In this type of environment you may want to have several sites running concurrently and utilising free SSL certificates for full and real world client or user acceptance testing.
*I should caveat at this point that not all older browsers support SSL negotiation using SNI. While the vast majority of modern browsers do just fine, no version of Internet Explorer on Windows XP is supported (for those users that still haven’t moved away from an unsupported OS).
You need to be running at least IIS8 to support SNI, so assuming this is in place, you should be ready to get started.
Firstly to create your sites in IIS.
There are many ways you could go about this but my advice is to create the site with http bindings (no https) to start with. The tool used later will take any http binding in place and automatically create an https binding associated with the SSL cert we provision.
As an example I have created a site with http bindings for two hostnames;
Now for the SSL cert, we will use Lets Encrypt as the CA.
Lets Encrypt advertises itself as “a free, automated, and open Certificate Authority”, is part of the Linux Foundation and is provided by the Internet Security Research Group (ISRG).
Now I am normally cautious on free CAs, especially after another big name in this space was publicly shamed recently for various misdemeanours gaining itself an untrusted status with Mozilla as a result. You can read the full article here; https://blog.mozilla.org/security/2016/10/24/distrusting-new-wosign-and-startcom-certificates/
Lets Encrypt gives me no such concerns and a quick look at their homepage lists several large and high profile technology companies as sponsors (including Mozilla).
Unlike other root CAs Lets Encrypt leverages tools run from the webserver itself and using the Automatic Certificate Management Environment (ACME) protocol to request and provision certificates and auto configure the environment on which they are to be used.
This means there are a wealth of third party tools available that essentially all do the same job.
For me, I found the easiest and most reliable to be letsencrypt-win-simple. This is a command line tool which does everything I need, including requesting a multi domain SAN cert.
Download the zip file from the Git project page at https://github.com/Lone-Coder/letsencrypt-win-simple
Once downloaded and extracted you will need to open an elevated command prompt and navigate to the folder you have extracted to above.
Full documentation is available on the project page, however for my purposes of creating a SAN cert to cover two domains, I ran ‘letsencrypt.exe –san’
This will then open another window listing the sites found in IIS and asking you to choose which site to request the certificate for. I enter ’14’ which relates to the site name ‘IP’;
If you see questions to specify the user to run as choose no, (you should already be running as administrator).
You may see a warning about the tool not being able to access the .well-known\acme-challenge file.
If this is a problem for you then I would recommend adding an entry to the web.config file for this site to allow files without extensions to be served. This is a requirement.
For convenience below is included a sample web.config file which you can copy and place in the root of your IIS site.
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <validation validateIntegratedModeConfiguration="false" /> <staticContent> <mimeMap fileExtension=".*" mimeType="text/json" /> </staticContent> </system.webServer> <system.web> <authorization> <allow users="*" /> </authorization> </system.web> </configuration>
After a few seconds, you should get confirmation the process is complete. Confirm this by checking the bindings again for the site. You should see new https bindings that mirror any http bindings you has already set up.
You can now remove the http bindings (if required).
Lastly, try browsing to your site using https:// and check the certificate. You should see no warning within the browser and viewing the certificate should show something similar to below;
Note the short expiry on the certificate of 90 days. This is by design and Lets Encrypt state on their website that this is to prevent issues arising from key compromise etc.
Renewing a certificate is as easy as repeating the above process.