How to proxy another site through IIS with a Lets Encrypt certificate.
Setting up a reverse proxy web server means you have one web server, that the world talks to. And that server then talks to another one on the world’s behalf.
This sounds like a whole lot of work. So what benefits do you get?
The main reasons I do this are:
- To allow public access to an otherwise unencrypted site or device (eg: my Raspberry Pi camera is HTTP only, but IIS lets me wrap it in HTTPS)
- To use Lets Encrypt for certificate management (eg: PRTG Network Monitor supports HTTPS, but Lets Encrypt is 100 times easier to manage)
- To control access more finely (eg: allow an internal only
ligos.localdomain to connect without a password, but require a login for a public
- To run multiple distinct web servers on different ports on the same computer, but access them without custom ports (eg:
Before we add a site, you need to enable IIS and install the Application Request Routing module to allow reverse proxy. IIS is only available for Windows Pro SKUs, so if you only have Windows Home you’ll need to use a different web server.
In Windows 10 Pro, you enable IIS by searching for Windows Features, which will find the turn Windows Features on or off widget. It’s still an old Windows 7 style app (unless you’re using Windows Server).
There are lots of components you can install for IIS. The following are a pretty minimal set which will allow you to reverse proxy, plus other useful features:
- Web Management Tools -> IIS Management (x3)
- World Wide Web Services -> Application Development Features -> ISAPI Extensions and Filters
- World Wide Web Services -> Common HTTP Features -> Default Document
- World Wide Web Services -> Common HTTP Features -> HTTP Errors
- World Wide Web Services -> Common HTTP Features -> HTTP Redirection
- World Wide Web Services -> Common HTTP Features -> Static Content
- World Wide Web Services -> Health and Diagnostics -> HTTP Logging
- World Wide Web Services -> Performance Features -> Static and Dynamic Content Compression
- World Wide Web Services -> Security -> Basic Authentication
- World Wide Web Services -> Security -> IP Security
- World Wide Web Services -> Security -> Request Filtering
Installing Application Request Routing is easiest via the Web Platform Installer.
You also need to enable the Application Request Routing proxy to actually do the reverse proxy. If this isn’t enabled, you’ll end up getting 404 errors with no obvious reason why.
Open Application Request Routing on your root web server -> Proxy Server Settings -> tick Enable Proxy.
Although the server isn’t actually going to serve any content, IIS still needs a folder to store a web.config file.
x:\websites\site.ligos.net works for me.
The folder should be readable by
IIS_IUSRS group (or whatever user your Application Pool runs as).
Fire up the IIS management console and add a new site.
I always name sites based on their DNS name (if they have multiple DNS names or aliases, then I use the primary one). And I have a heavily re-used Application Pool for static content, which does not have .NET enabled and is very light on resources. At this point, only enable an HTTP endpoint.
Note: there are ways to create IIS sites via Powershell, but I don’t create new sites often enough to warrant scripting.
If you are using IIS for the first time, you should probably check all is working by dropping a basic
index.html page in.
You can’t visit a website without a DNS record (OK, you can, but not the site we’ll be creating).
Make sure you add an appropriate
CNAME record for your new site.
You may also need to allow network access to your server through your router, usually by port forwarding ports 80 and 443 (HTTP and HTTPS respectively).
I’ve got my Mikrotik router configured to do hairpin NAT or reflection, which is like port forwarding but for my internal network (it makes the external IP address appear like its my internal server’s IP address, so I can browse to
site.ligos.net and it just works).
You may also need to contact your ISP as mine blocked common ports like 80 and 443 by default.
You can add the reverse proxy rules through the management interface, but I find it easier to drop in a template
web.config file and edit it directly.
Start with the following (we’ll enable the first couple of commented out rules soon):
The important part for reverse proxy is this part:
This tells the IIS URL rewrite engine to match everything for the
prtg.ligos.net host and proxy it through to localhost on port 8443, keeping the path and query string the same.
Essentially, it’s translating between
You’ll need to use your site’s address, of course.
The web.config file also has support for static content caching, removing the powered by IIS site header, and adding a HSTS header (which won’t do anything until HTTPS is enabled).
Before we can get a certificate from Lets Encrypt, we need to require one path to not reverse proxy.
Uncomment the rule below in your web.config file:
This disables the reverse proxy for the special well known acme-challenge folder, which Lets Encrypt uses to check your site’s ownership.
Before you can serve HTTPS requests you need a certificate, which we can get for free with minimal fuss with Lets Encrypt.
Windows support for Lets Encrypt is not that great, but I’ve found Certify works pretty well, even though it is in alpha. Rick Strahl has a good summary of other Lets Encrypt clients if Certify isn’t to your liking.
Certify will look at the sites hosted on IIS and generate a certificate from Lets Encrypt. Pretty much all you have to do is chose the right site, and click Request Certificate.
If Certify does everything right, it will automatically add an HTTPS binding for your site with the certificate you just acquired.
Unfortunately, Certify isn’t quite perfect and doesn’t always get things right. So it pays to check your IIS bindings for the site.
HTTPS and encrypting everything is fast becoming the default, but most web browsers will still try connecting via unencrypted HTTP first.
Uncomment the top rule to add a redirect when there are any HTTP requests to the equivalent HTTPS page.
Running a reverse proxy enables additional levels of flexibility, security or functionality.
Configuring your site to be reverse proxied and use Lets Encrypt is a powerful combination.