Skip to content

Blog

Reverse Proxying ADFS with Nginx

In my recent trials and tribulations with ADFS 3.0, I came up against an issue where we were unable to host ADFS 3.0 with Nginx as one of the layers of reverse proxy (the closest layer to ADFS).

When a direct connection, or a cURL request, was made to the ADFS 3.0 endpoints from the machine running Nginx, all seemed well, but as soon as you actually tried to ferry requests through a proxy_pass statement, users were greeted with HTTP 502 or 503 errors.

The machine running ADFS was offering up no other web services — there was no IIS instance running, or anything like that. It had been configured correctly with a valid TLS certificate for the domain that was trusted by the certificate store on the Nginx machine.

It turns out that despite being the only HTTPS service offered on that machine through HTTP.sys, you need to explicitly configure which certificate to present by default. Apparently, requests that come via Nginx proxy_pass are missing something (the SNI negotiation?) that allows HTTP.sys to choose the correct certificate to present.

So, if and only if you are sure that ADFS is the only HTTPS service you are serving up on the inner machine, you can force the correct certificate to be presented by default, which resolves this issue and allows the Nginx reverse proxied requests to get through.

With that warning given, let’s jump in to what we need to do:

Retrieve the correct certificate hash and Application ID

netsh http show sslcert

You’ll need to note the appid and the certificate hash for your ADFS 3.0 service.

Set the certificate as the default for HTTP.sys

We’ll use netsh‘s interactive mode, as I wasn’t in the mood to figure out how to escape curly brackets on Windows’ command line!

You want the curly brackets literally around the appid, but not the certhash.

netsh
netsh> http
netsh http> add sslcert ipport=0.0.0.0:443 appid={appid-from-earlier} certhash=certhash-from-earlier

Verify the proxy_pass settings

Among other configuration parameters, we have the following in our Nginx server stanza for this service:

proxy_redirect off;
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_set_header X-MS-Proxy the-nginx-machine;
proxy_set_header Host the-hostname-in-question

And, with that, we were successfully reverse proxying ADFS 3.0 with Nginx. 🙂

Serving Pi

I recently completed a physical migration of my server, the one that hosts this very page! It all went successfully, and without any noticeable downtime for this site, which I am pleased to be able to do.

There was, however, a period of time during which this server needed to be physically switched off and moved to the new location. To enable zero downtime, something would need to be able to host the server during that period.

Enter my Raspberry Pi!

Raspberry Pi in box

This amazing little thing is capable of running Raspbian, a modified version of Debian, which means I get access to the rich library of Debian packages that are available. I have a private Git repository containing a modular set of Puppet manifests. These describe the exact configuration of this server, so by applying the Puppet manifests, I can spin up a new instance of this particular server’s configuration on a whim.

So, I dusted off an SD card that was lying around, dropped Raspbian on it, and installed Puppet and Git and applied the manifests.

If I’m honest, there were a few components that weren’t quite so happy to run, despite packages being available. Varnish didn’t seem to like my VCL file, so I had to run the site here directly with Nginx pointing to PHP-FPM instead.

To cut a long story short, it worked! I was successfully serving up this site, from the Pi, using (almost) my existing configuration. Performance was not stellar, even compared to the modest hardware that normally serves this page, with page load times about 10 times slower than uncached page loads normally would be. The main blog page did take 1.5 seconds to render! For the short time I needed it though, I was very happy to have a very inexpensive and easy solution.

Nginx, Linux sendfile(), and Problem Solving

Engine room, by Maggie Stephens

In “A Tale of Stale Content”, on the Van Patten Media blog, I take a somewhat philosophical look at IT problem solving, told through the story of an intensely frustrating issue with Nginx serving up stale content in virtualised environments. Apparently, the sendfile on; setting in Nginx will cause it to deliver old versions of files you have since updated on disk.

Sometimes a problem comes up that is just weird. It seems completely illogical. But these computery things are supposed to be nothing but logic, right?

When we eventually arrive at the solution, after many hours of hair loss and bad language, we are reminded of the sheer complexity of these systems. Our assumptions about how something at a higher level should behave are entirely dependent on the premise that the lower levels are all doing exactly as expected too.

It’s humbling, in a slightly odd technical sense. We all need to be humbled sometimes.

Read the full post over on the Van Patten Media blog.

Image is “Engine room”, by Maggie Stephens (Pot Noodle) on Flickr. Licensed under CC-BY.