Let’s Encrypt & IIS as reverse proxy with Certify the Web

Posted on December 9th, 2017

After I have been running Teamcity and Octopus Deploy behind a Microsoft IIS without a certificate for some years I decided to give it a go again.

The reason it's behind using a reverse proxy:

Teamcity is hosted on a Tomcat HTTP Server and Octopus Deploy is self hosted. Both running on a custom port.
Limited in the number of external IP's ... the Teamcity and Octopus Server is running on a different host(could be run on the same host since they are running on different post).

Octopus Deploy does Have built-in support for Let's Encrypt but that forces me to run it on post 80, which of the above reasons is not possible. Steps

Install Certify
Edit web.config
Run Certify for the selected sites.

Step 1

Go to Certify The Web and download the latest release. You can find the src for the project on GitHub Certify The Web - SSL Manager

Step 2

Edit the Web.config with the following changes:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
		<staticContent>
			  <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="1.00:00:00" />
		</staticContent>		
        <rewrite>
            <rules>
                <rule name="LetsEncrypt" enabled="true" stopProcessing="true">
                    <match url="\.well-known/acme-challenge/*" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
                    <action type="None" />
                </rule>
            
                <rule name="Https redirect" enabled="true" stopProcessing="true">
                    <match url="(.*)" />
                    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
                    <conditions>
                        <add input="{HTTP_HOST}" matchType="Pattern" pattern="^domain.tld$" ignoreCase="true" negate="false" />
                        <add input="{HTTPS}" pattern="^OFF$" />
                    </conditions>
                </rule>				
            
                <rule name="ReverseProxyInboundRule1" enabled="true" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                        <add input="{HTTP_HOST}" matchType="Pattern" pattern="^domain.tld$" ignoreCase="true" negate="false" />
                    </conditions>
                    <action type="Rewrite" url="http://172.17.4.78:9999/{R:1}" />
                </rule>
			</rules>
        </rewrite>
    </system.webServer>
</configuration>

Explanation of the three rules

LetsEncrypt

This is to allow renewal of the certificate. This is set before the redirect of requests to HTTPS.

Https redirect

Force https requests of all request that does not math the above rule.

ReverseProxyInboundRule1

Rewrite the inbound request to the http webserver which in my environment is hosted on a different server. But might also just be localhost.

Step 3

Start Certify the Web where you will be asked to create a new primary contact.

1

Fill in the form and click "Regsiter Contact". This information is used when requesting certficates from Let's Encrypt.

Click the "New Certificate".

2

Select the IIS site you want to create a certicate for.

3

It will then show the hostname on that site. You can then selected what sites you want to create a Certicate for. Remember this hostname needs to be accessible from the outsite. Hence my name here: 'racing.localtest.me' will work not.

You can also select the primary domain for the certicate if there is more than one.

4

On the Advanced tab there is diffent options, which I havent used yet. But the web hook option would nice if you want to noticed either when a Success or Error eccours when requesting a new certificate.

5

If everything goes well you will now have a site running https with a valid and FREE certificate.