Custom Domains and SSL bindings with IIS Express

11/12/2014

IIS Express is designed to be able to support all web development tasks without admin privileges. But that design comes with some limitations, e.g. you are not able to use any other hostname than localhost and only ports between 44300 and 44399 supports SSL. Those limitation can be a little annoying, luckily we can change the default configuration. In this post I describe how I to use a custom hostname.

When IISExpress is installed it does quite a bit of configuration, the following things happens behind your back.

  • It automatically creates and installs a self-signed SSL server certificate in the local machine store.
  • It configures HTTP.SYS to reserve ports 44300 through 44399 for SSL. Incoming SSL requests that use localhost and one of the ports in the specified range are automatically associated with the self-signed certificate.

(HTTP.SYS is an operating system component that handles SSL for IIS and IIS Express. The setup program is able to configure HTTP.SYS because setup runs under elevated privileges.)
Source: http://www.iis.net/learn/extensions/using-iis-express/running-iis-express-without-administrative-privileges

So if we want to run with another hostname than localhost and use SSL we need to do 3 things.

Generate a new SSL certificate

This is a task for makecert.exe, you can use the following to generate a self signed certificate that gets installed in the Local Machine Personal store. You must run this from an elevated command line, with makecert in the path, e.g. the Visual Studio Developer Command Prompt.

Makecert -r -pe -n CN="sjkptest.dk" -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localmachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12

Once the cert is generated, we need to install it in the trusted root so that the certificate chain is good.

Configure HTTP.SYS to use the new certificate

For IIS Express to be able to use the new certificate we need to configure HTTP.SYS to use it for the port we want. If we use one of the preconfigured ports 44300-44399 we also first have to delete that configuration.

To see what certificates that are configured to which ports run

netsh http show sslcert

To delete an existing certificate configuration (in my case wanted to use the existing port 44302)

netsh http delete sslcert ipport=0.0.0.0:44302

To reconfigure port 44302 to use the new certificiate, we need the certificate thumbprint, which we can get from the mmc or by using certmgr.exe /c /s /r localMachine MY, if you use certmgr use the SHA1 thumbprint

netsh http add sslcert ipport=0.0.0.0:44302 certhash=c2ec8855dc4d87476423211220681f586d390542 appid={214124cd-d05b-4309-9af9-9caa44b2b74a}

The appid you can find by looking in the return from netsh http show sslcert, by taking the Application ID from one of the other ports registered within the port range.

Change the bindings in applicationhost.config

The applicationhost.config file are located in C:\Users\[AccountName]\Documents\IIS Express\config\.

In the file you need to find the section belonging to your application, it looks like this
[xml]
<site name="ApplicationName" id="8">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="ApplicatoinPath" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:6321:sjkptest.dk" />
<binding protocol="https" bindingInformation="*:44302:sjkptest.dk" />
</bindings>
</site>
[/xml]

After the config file is change make sure to restart IIS Express and update the Visual Studio project settings to point to the new hostname. Now you should be able to browse your site on the new custom hostname, if you make sure to update your host file, or make a DNS registration for the host name.

Sources:
http://www.iis.net/learn/extensions/using-iis-express/handling-url-binding-failures-in-iis-express
http://msdn.microsoft.com/en-us/library/bfsktky3%28v=vs.110%29.aspx