Post heartbleed, looking at alternatives to OpenSSL

With the bug of the year (Heartbleed) patched on all my systems, I decided to look into alternative SSL implementations. I mostly use Lighttpd and Nginx, and try to stay away from Apache, unless I really need something that will only work with it.

/images/heartbleed.png

Apache seems to have 2 possible SSL implementations available. The first one, mod_ssl, which is based on OpenSSL, is used by ~99% of the users. mod_nss is the second SSL implementation for Apache, based on the netscape/mozilla NSS library.

A quick google-search for alternative SSL implementations or modules for Nginx and Lighttpd returned no actual working code, only some requests for functionality, so it seems that this is (at this time) a dead end. Looking further on google and wikipedia I looked at the alternative SSL implementations, specifically axTLS, PolarSSL and MatrixSSL.

axTLS

AxTLS was the first library I looked at, within the source distribution is a minimalistic webserver with SSL/TLS support and a tool called axtlswrap, a simple stunnel like wrapper for the AxTLS library. I quickly configured the minimalistic webserver (axhttpd) and gave it a temporary StartSSL certificate. The configuration was quite simple after configuring the library to actually use my provided certificate and key instead of the built-in certificate. I then decided to run the SSLLabs tests against this webserver, to see how it would compare against my regular Lighttpd/OpenSSL secured websites.

The library provided the minimal required features, but at this time doesn’t support TLS1.2, and had only limited support for the various popular ciphers. This would result in a usable webserver, but with limited options in ciphers and limited support for strong encryption. Since I didn’t feel like dropping back to a ‘B’ score in SSLLabs tests, AxTLS was not a sufficient solution.

PolarSSL

PolarSSL is another open-source SSL library, which is available under the Gnu GPLv2 or a commercial license. It’s currently being used in various well-known products (PowerDNS and OpenVPN-NL, a dutch-government approved version of OpenVPN). PolarSSL seemed to support all the latest ciphers and TLS standards and there were at least 2 httpd servers that supported using PolarSSL.

Hiawatha

Hiawatha was the first webserver software I tried with PolarSSL. The code for PolarSSL is actually included in the downloads from Hiawatha, so you don’t need to download this seperately. The hiawatha source-tree includes a script to download a newer version of PolarSSL when needed.

Hiawatha was also quite easy to configure, and I had it running with my certificate in a matter of minutes. Another test-run of the Qualys SSLLabs tests gave a very positive result. The only downside was a choice for a 1024 bit Diffie–Hellman key exchange. I struggled a bit to get this to 2048 or 4096 bits, but after a few failed attempts found a Hiawatha configuration option to set this (DHsize = 4096).

With this setting I got my beloved A score in Qualys SSLLabs. Support for TLS versions 1.0, 1.1 and 1.2, with support for SSLv2 and v3 completely disabled.

I didn’t do much further testing with Hiawatha, as I only configured it to do SSL/TLS and then reverse-proxy everything to a lighttpd server running plain http.

Monkey

The monkey webserver is another http daemon with support for PolarSSL. It’s focussed and optimized for running only on Linux systems, and aims to have a good performance while also having all the standard and required features (ipv6, virtual-hosting, fastcgi)

To enable the SSL module with Monkey, it’s required to run ‘configure’ with the ‘–enable-plugins=polarssl’ option. This doesn’t seem to be documented in either configure or the INSTALL or README files. It’s also funny to see that compiling jemalloc.c takes about as much time as all the other files combined.

My first build of Monkey was against the systems PolarSSL, which resulted in an A- score in the SSLLabs tests. I spotted that the Debian polarssl package was still stuck at version 1.2.9, so I downloaded the latest PolarSSL and built that version (1.3.6) (make lib SHARED=1; make install)

When running with PolarSSL 1.3.6, the Monkey webserver also got an ‘A’ score in SSLLabs. The only ‘red’ is the session resumption, which for some reason isn’t working. This is still something I need to look into. Also, it appears that monkey can only run over a single transport, so either HTTP or HTTPS. This would mean running two seperate monkey-instances for http+https support. This might be something that will be fixed in a future monkey version.

For as long as my testing system is still running, you can check the live SSLLabs score on it. Please ignore the ‘axtls’ in the hostname, it’s currently running Monkey, but the certificate I created for testing was first used for testing axtls.

Feature-wise monkey seems like a nice alternative to Apache, Nginx and Lighttpd, and looking at the http performance, it also gives some very nice results. My testing with HTTPS however quickly triggered various bugs and crashes, so it seems that the PolarSSL support for Monkey is still somewhat buggy. I could succesfully run my benchmarks against the server in HTTP mode, at up to 18000 requests per second (on a dual core VM), but running with SSL enabled would crash the monkey process when running with more then a hand full of threads. The system would be stable for hours with only 2-6 threads, but when running with 10+ threads it would crash within seconds. I hope these bugs will be fixed soon, so Monkey with PolarSSL will prove itself to be a worthy competitor in the SSL serverspace.

Update 2014/04/22:

It seems my libpolarssl was compiled with some incorrect settings. I’ve reconfigured/recompiled polarssl and both monkey and hiawatha. The servers are now stable as expected, performance-data will be updated as well, as soon as my new tests have completed.

Basically: make sure you enable POLARSSL_THREADING_PTHREAD and disable POLARSSL_DEBUG_C