Hardening Your Web Server’s SSL Ciphers

There are many wordy articles on configuring your web server’s SSL ciphers. This is not one of them. Instead I will share a configuration which is both compatible enough for today’s needs and scores a straight “A” on Qualys’s SSL Server Test.

First the inevitable disclaimer: the information presented herein is without any guarantees and I’ll take no responsibility if any harm happens to you or your users. That said, to best of my knowledge, as of today, February 5th, 2013 the configuration presented should protect you against known SSL weaknesses. If you find any factual problems, please reach out to me immediately and I will fix it ASAP.

Principles

If you configure a web server’s SSL configuration, you have primarily to take care of three things:

Well, and the obvious things that are usually set by default: disable NULL encryption and MD5.

There used to be a bullet point suggesting to use RC4 to avoid BEAST and Lucky Thirteen. It’s still used as a fallback however RC4 is considered broken now – although there’s no practical attack against it since it requires millions of copies of the same encrypted data.

Unfortunately, there is currently no good answer. On there server side, you should update your OpenSSL to 1.0.0+ so you can support TLSv1.2 and GCM as soon as possible. On the client side…well at this moment only iOS’s Safari supports TLSv1.2. It’s hard to say whether CBC or RC4 is the lesser of the two evils – in the end you should use neither.

Apache

1
2
3
    SSLProtocol ALL -SSLv2
    SSLHonorCipherOrder On
    SSLCipherSuite AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH

This should work on both Apache 2.2 and 2.4. If your OpenSSL doesn’t support the preferred modern ciphers (like the still very common 0.9.8), it will fall back to RC4 but your configuration is ready for the future.

TLS compression is a different beast though: as of Apache 2.2.23, it’s not possible to switch it off inside of Apache. For Apache 2.2.24+ (which isn’t released yet as of 2013-02-05) and 2.4.3+, you can switch it off using:

1
    SSLCompression Off

Currently the default is On, but that should change with 2.4.4+ (which also isn’t released yet).

The good news for Ubuntu admins is that they have back ported that option into their 2.2 packages – and set it to off by default – so you should be fine. The solution on Red Hat based OS (RHEL, Fedora, CentOS, Scientific Linux…) is setting an environment variable inside of your Apache startup script:

1
    export OPENSSL_NO_DEFAULT_ZLIB=1

nginx

1
2
    ssl_prefer_server_ciphers On;
    ssl_ciphers AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH;

SSLv2 is off by default. TLS compression depends on the version of nginx and the version of OpenSSL.

If OpenSSL 1.0.0 or later is installed, anything after nginx 1.0.9 and 1.1.6 is fine. If an older OpenSSL is installed, you’ll need at least nginx 1.2.2 or 1.3.2.

For more details, have a look at this serverfault answer.

TL;DR on TLS compression & nginx: if you’re using Ubuntu Precise (i.e. the current LTS release) you’re fine (OpenSSL 1.0.1/nginx 1.1.19).

Finally

Make sure to test your server afterwards!

If you want to learn more about deploying SSL/TLS, Qualys’s SSL/TLS Deployment Best Practices are a great primer. If you’re concerned with performance, have a look at 5 easy tips to accelerate SSL. The EFF has also a piece on deploying HTTPS correctly and no less than Jacob Appelbaum has a repo with example configurations for SSL/TLS services.

And finally, if you want to know more about the SSL/TLS behavior of your browser, SSL Cipher Suite Details of Your Browser will give you all the details you need.

Stay vigilant, it’s dangerous out there.

Credits: The initial version of this article has been kindly proof-read by Christian Heimes. I have integrated feedback from Hacker News, especially on OpenSSL’s gracious cipher fallback. The errors are all still mine though.

← See all posts