HTTPS Security, Apache 2.4 and Nginx

Another week, another security warning it seems.

In my day job I admin a number of servers, this blog is hosted also on my RaspberryPi, so I'm no stranger to security. That said, if we start talking about HTTPS then I'm a little out of my depth. This story begins like many others, browsing Hacker News for something to read at lunchtime. It's here I stumbled on this article detailing insecure Diffie-Hellman key exchange on webservers configured to use HTTPS.

What the Diffie-Hellman!?

Sure, I've a loose grasp on public-private keys and their use in SSH. I also have a vague idea that SSL certificates include a public key - what it is used for I wasn’t entirely sure, encryption they tell me. It's also maybe a little alarming that I could be trusted with these severs based on the above but sometimes roles just acquire you.

Diffie-Hellman key exchange

Luckily for me intricate knowledge of Diffie-Hellman wasn't necessary, the article contained a couple of how to's and for anyone looking for some solid pointers I would head there now. Before I began the work of testing my servers I was pointed in the direction of SSL Test, a great tool for those who haven't used it yet. SSL Test will give you a pretty wholesome picture of any HTTPS secured domain - useful.

Time to get Testing

Armed with the knowledge of a security vulnerability and a tool for checking said vulnerability, I set about vetting my servers. To my horror one of the severs was vulnerable, not only to LogJam but also POODLE and a whole host of other potential security issues. Not really what I wanted.

Massive love to SSL Test as it not only shows you what's wrong but also how to fix It. Most of it seemed simple enough, update the config in a few places and maybe an update of Apache, how hard can that be?

Famous Last Words

The server in question runs a bespoke corporate build of CentOS, normally not a problem. However when following the fix steps I needed to add a config parameter that Apache 2.2 didn't know about. Unfortunately, after many hours of wrestling with Apache 2.4 and OpenSSL I was nowhere near. Now I'm sure if I was a little fresher I would have figured it out (though I say that more for my sanity at this point).

However, this server is used daily by the developers in several teams and it needed to be up and running again before the morning. So I made the decision to move from Apache and over to Nginx. I use GitLab CE on one of my servers, which also uses Ngnix, and it has a little bespoke config so I'm more than happy setting it up. I actually prefer Nginx's config syntax over the XML of Apache so it seemed like a good fit.

I inherited my server responsibilities when a colleague left the company. Since then I've not really changed the formula much bar migrating to new hardware. It has long been time to stretch my legs a little, leave my own mark and see what improvements I could make. One small step for...

Nginx and Cert Nightmares

The Nginx setup was a breeze, following the steps here I added my yum repo and installed Nginx. So far, so good. The server was running Confluence so a quick test that Nginx could proxy was in order. Again another success. Clearly feeling a little smug with myself I wired back in the SSL certs and reconfigured our ACL to work with Nginx.

Job done. Time to retest....

Well I certainly didn't slog through the hours of Apache, OpenSSL and then Nginx setups to get a B. A few more changes needed to be made. Dutifully following the advice from SSL Test I needed to drop some unsupported versions of SSL and complete my certificate chain with an intermediate. Easy, bring it on. Quick config change here and then a 'cat' and restart. Boom. Something's gone wrong.

Below is my terminal output:

$ cat intermediate.crt > certificate.crt
$ nginx -s reload
$ nginx: [emerg]SSL_CTX_use_PrivateKey_file("/etc/nginx/ssl_crt.key") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch) nginx:configuration file /etc/nginx/nginx.conf test failed

This was a moment of sheer dread, absolute panic, why oh why didn't I backup the certs?!

An easy mistake to make (> in place of >>) but one that had costed me my cert. In this circumstance if there’s no backup then it’d be off to Verisign or whoever to download the cert again, unlucky for me I didn’t have access. My only saving grace was a vague recollection that the cert was somehow linked to the public key… so did that mean that I already had everything I needed in my keystore? Better yet, I still have a page open to the server and could view the cert!

Final Test

With my fingers crossed I exported the cert from Safari and then copied it back into my ssl.crt. Once again I restarted Nginx and to my absolute delight it worked! I very carefully copied and then zipped the certs / key and intermediate (never again) before attempting to cat the intermediate again.

Job done. Time to retest… drum roll please ...

I was glad the Nginx setup had been so easy, bar that little hiccup. Though I imagine Apache 2.4 could be configured just as easily given a different setup. Overall a needed to know very little about HTTPS or Diffie-Hellman. Though saying that I do intend to give key exchange a once over, and who knows, I may even write some of it down on here…

First appeared on Trusty Interior, last update 14 Nov 2023