Anyone responsible for hosting web services protected by SSL/TLS should be at least curious about how they might score against Qualys SSL Labs Server Test. I know I was when I first became aware of the tool. The results may surprise you, and you’ll probably learn a lot if you actually put the effort into securing and optimizing your configuration to get a higher score. I’d like to share some of my Apache configurations to hopefully save some folks out there a little time and raise awareness about web security.
I’ll start by removing all configurations I’ve added to achieve my A+ score, and we’ll slowly tighten the screws to see the effect each configuration has on the results of the test.
Ouch! If I’m being honest, I may have intentionally sabotaged my Apache config a little to get a score like this. Turns out if you’re running a fully patched CentOS 7 web server with Apache 2.4.6, it does an ok job of being secure out of the box. I enabled all possible ciphers, excluded the secure ones, and used a 1024-bit certificate issued by an untrusted CA to add a little dramatic effect. I tried to make things a little worse by enabling SSLv2 and v3, but they are no longer supported with the version of Apache I am using. Because I am unable to use that as an example here, just make sure you have a line like this in your Apache configuration to ensure all insecure SSL/TLS protocols are disabled.
SSLProtocol all -SSLv2 -SSLv3 -TLSv1
For our first change, let’s fix that certificate by requesting one using Let’s Encrypt with at least a 2048-bit private key. Make sure to check out CertificateTools.com for a super easy way to generate your CSR. It supports RSA and ECC keys and provides the OpenSSL commands so you can run them locally!
That’s good progress. We’ve gotten rid of a few warnings, but we still have an ugly “F”. Next we’ll make some changes to the supported ciphers.
Excellent! In these results, we notice that the server does not support “Forward Secrecy.” I intentionally left out the ECDHE suite of ciphers just to bring attention to this and stress the importance of making sure these ciphers are enabled. For our final cipher hardening and to fully support perfect forward secrecy, we need to make sure the following lines exist in our config.
SSLHonorCipherOrder on SSLCipherSuite ALL:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4
Looking good! Now to finally get our server to score that A+, we need to enable HTTP Strict Transport Security (HSTS). This is simply an additional web header that is stored in a browser for the amount of time specified in the header that tells the browser to force the use of HTTPS. This prevents software like SSLStrip from intercepting web requests and convincing your browser to use HTTP instead. This is a simple security feature that can be enabled by just adding a plugin to your wordpress, but Apache gives us a great way to enable it within our config using the following line.
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
Perfect! Now we can technically go one step further with our HTTPS security by creating some additional headers to support a feature called HTTP Public Key Pinning (HPKP). This will tell your browser to store at least one certificate in the chain upon its first visit to a given site. If the next visit doesn’t contain the cached certificate in the chain, it will prevent the user from being able to visit the site. This is extremely effective at preventing man-in-the-middle (MITM) attacks, but requires a strong understanding of how it works and lots of diligence to maintain it properly. Currently only Chrome, Firefox and Opera support HPKP, and Chrome has announced plans to remove support for it because of the possibility for an attacker to install malicious pins or for a site operator to accidentally block visitors. Given that, it’s not something I would recommend, but I want to at least touch on it for completeness.
I hope this article was helpful and informative. Please leave questions and comments below.