Perfect SSL in Apache

Thanks to Edward Snowden we have learned a lot about threats from various(although mostly US) governments. We started to think more about secure technologies and cryptography. I was advertising high security standards even before the Snowden’s leaks. Some of my friends thought that I was being paranoid. Now everyone knows better than to trust RSA or any of their products. Everyone is aware of malware designed by intelligence agencies. Universal snooping isn’t an Orwell’s fantasy anymore, it’s reality.

HTTPS everywhere

That’s why every webmaster is encouraged to switch to HTTPS. If it isn’t your first time on my blog, you may have noticed that there is no HTTP anymore. Every connection is a secure one. It is very easy to enable HTTPS. It’s much more complicated to make it perfect. I have spent some time fine-tuning my apache settings to get a perfect Qualys’ SSL test score. By the way, if you haven’t heard about this tool, it’s industry’s de facto standard. It’s used just for this particular purpose – to find out if your SSL settings can be considered good.Site's Test Results

First of all, please be aware that some settings will require compromises(as with all things security). For example, you can see on the screenshot above that I haven’t achieved perfect “Protocol Support” score. It’s easy to do this and I’ll show you how, but this would basically close access to a site for almost all readers.

Let’s start with basic SSL settings:

        SSLEngine on
        SSLCompression off
        SSLHonorCipherOrder On

SSL compression is a bad idea and needs to be disabled everywhere. Also my settings are better than security defaults in many browsers(especially the one which should’t be named 😉 ), that’s why we force clients to use our preferences.

If you want your score to be nice and green, you need to have a valid SSL certificate signed by an acknowledged CA. The certificate needs to be signed with a secure algorithm. Secure means SHA-2. If you are still using SHA1 – it’s time to upgrade.

Now the next part – “Protocol Support”. If you want to have a perfect score, just disable every protocol except TLSv1.2:

SSLProtocol -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2

This will make your site unaccessible to majority of clients. Even Google and over web crawlers won’t be able to access it. Super paranoid choice. Good result, huh? But let’s be more real:

SSLProtocol -SSLv2 -SSLv3 +TLSv1 +TLSv1.1 +TLSv1.2

If are following security news, you probably know that SSLv3 isn’t very good. Only reason to use it – to support IE6 clients in some antediluvian enterprise environment. I hope that this isn’t your case, otherwise I don’t envy you.

To get a perfect “Key Exchange” score, you must use a strong key. 4096 bits or better for Diffie-Hellman key exchange or just switch to elliptic curves. I haven’t tried elliptic crypto, because I have some reservations.

Perfect “Cipher Strength” is also easy to achieve. Just disable less than 256 bit ciphers:

SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4 !AES128 !SEED !CAMELLIA128"

This cipher combo will also make NSA life harder by enabling forward secrecy. Yay! Just be aware that in some cases you may need support for 128bit ciphers(maybe you are dealing with Java based clients or owners of very old Android devices). In this case, I would simply enable back AES128. However, I don’t care about Java clients, I’ll leave it as it is.

Now the last part. For perfectionists. You want to get this nice “A+” grade, don’t you? To get it, you will need to enable Strict Transport Security and disable HTTP support completely. Yep, no more plain text. No other way to get it. So just suck it up and proceed:

Header set Strict-Transport-Security "max-age=31536000"

This will force clients to request a secure version of your website for the next year. So, no going back now, unless you can persuade all your users to clear their browser cache. And, finally:

<VirtualHost *:80>
        ServerName example.com
        ServerAlias www.example.com
        ServerAdmin webmaster@example.com

        RewriteEngine On
        RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [redirect=301]
</VirtualHost>

Congratulations! You can enjoy your well earned “A+” grade!

Leave a Reply

Your email address will not be published. Required fields are marked *

Are you human? *