The SSL Test provided by Qualys does an incredibly thorough evaluation of the SSL configuration on your server. It's a great way to get a feel for whether or not you're doing SSL right. In this blog I'm going to walk through the steps required to get an A+ rating, the highest possible score. Now that everyone is patching and checking their servers after Heartbleed, let's take the opportunity to make some quick improvements while we're at it!
Introduction
You can see my A+ rating on the SSL Test right here. Factoring in many different aspects of an SSL implementation, the test is a perfect indicator of just how seriously a host takes transport layer security. As with all aspects of security, the landscape shifts and changes as new features are introduced and old features are deprecated. I aim to keep this blog up to date with changes as and when they are required.
The Basics
This blog will cover the steps I took to get my A+ rating on Qualys. I'm running nginx under Ubuntu and I will assume that you already have a server setup with SSL working and go from there. You can get your current rating from Qualys and take a screenshot so you have a point of reference to compare later on. I'd advise that you test out new configurations on a development or test server so that you don't accidentally affect your live server should the worst happen. NginX has a nice feature to test a configuration before you load it, but it's still best to test on a non-live system where possible. We will also be taking a backup of our configs before we modify them so we can revert back in an emergency. All of these changes are required in the server block of the virtual host file normally located in /etc/nginx/sites-enabled, unless otherwise stated.
Backup Your Configuration Files
Before we proceed with making some pretty hefty changes to our nginx configuration files, it's a good idea to take a backup of them.
cp /etc/nginx/nginx.conf /home/scott/nginx.conf
cp /etc/nginx/sites-enabled/scotthelme.co.uk.conf /home/scott/scotthelme.co.uk.conf
I've just made a copy of the files in my home directory so I have them on hand should I need them. Feel free to make copies wherever you like, but make sure you do!
Enabling SSL
In your config you should already have the basics of your SSL configuration. The server is instructed to listen on port 443, for HTTPS, and the paths to the certificate and key file are defined.
listen 443 ssl;
server_name scotthelme.co.uk;
ssl_certificate /path/to/ssl.crt;
ssl_certificate_key /path/to/ssl.key;
These are probably the only options that won't need to be modified in your config so let's move on to the good stuff.
SSL Protocols
The first decision to be made is regarding the protocols you wish your server to use. You can retain SSLv3 support for now and still achieve an A+ rating. However, disabling SSLv3 means that you only lose IE6 and equally horrid browsers. Considering that IE7 and IE8 are both available on the no longer supported Windows XP, I decided to remove SSLv3 support altogether. It's worth nothing that you can get TLSv1.0 support on IE6, it just isn't enabled by default. You can probably assume it isn't enabled if they haven't been security conscious enough to upgrade from IE6. More details here on Wikipedia regarding browsers and protocol support.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
Or if you feel the need for IE6 users:
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
UPDATE 16th Oct 2014
After the POODLE Vulnerability was announced in the SSLv3 protocol, do not enable SSLv3 as doing so can be dangerous and will prevent you from getting an A+ on the Qualys SSL Test.
You can enable and disable SSLv3 support and see the difference it makes in your SSL Test score if you like. You will notice a small bump in the Protocol Support score once you disable SSLv3, going from 90 to 95.
SSL Ciphers
The toughest decision on your server will be your supported cipher suites. With a near infinite number of possible combinations, this is largely down to a lot of research and a lot of opinion. You definitely want to support ECDHE suites so you get Forward Secrecy and it's advised to disable DHE suites as they are slower than ECDHE. Beyond this, there could be a long and drawn out discussion on various configurations and their merits so I will share mine here and ask for feedback in the comments if anyone has suggestions.
UPDATE 10th Sept 2014
Old ciphers
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!CBC:!EDH:!kEDH:!PSK:!SRP:!kECDH;
New ciphers
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
Update: I've removed the RC4 cipher which is now considered to be too weak and added DHE suites alongside ECDHE suites for more robust Forward Secrecy support.
If you like, feel free to add or change ciphers as you see fit but bear in mind that the order of ciphers is relevant to the next step.
Cipher Order
With the ciphers ordered so that the most preferred ciphers appear first in the list, we want to ensure that we enforce their use in that order.
ssl_prefer_server_ciphers on;
Now, when the client provides their list of supported ciphers, the server will choose the best one possible based on the order given above. This way we can ensure that we always use the best possible cipher but none weaker than those included.
SSL Optimisations
To minimise the impact of the SSL overheads on your server, you can reduce the number of handshakes that a client needs to perform. The handshake is the most expensive part of serving content over SSL. The first step it to enable the keep alive timeout. This will allow the client to send multiple requests via the same connection. This a trade off on higher capacity servers as you need to strike a balance between connection limits and inducing more load by severing connections prematurely.
keepalive_timeout 70;
The second step is to enable the SSL cache to remove the need for a handshake on subsequent or parallel connections. This needs to be added to the http block of your nginx.conf file located in /etc/nginx.
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
The shared SSL cache of 10Mb will hold around 40,000 connections so should be more than enough for most sites. Feel free to reduce or increase the size of the cache to fine tune it to your requirements. The session time out defines how long a session can remain in the cache and remain valid before it is discarded.
Strict Transport Security
The above configuration will get you an A rating on the SSL Test, but if you want to improve that to an A+, you need to go that little bit further. I have covered HSTS (HTTP Strict Transport Security) in detail in a previous blog and that's a good place to start if you want to know more about it. In short, when you present the client with a certain response header, the browsers will always enforce the use of HTTPS going forwards and never permit the user to attempt any connection using HTTP. This mitigates various SSL stripping attacks and also prevents the constant need for you to 301 clients from HTTP to HTTPS.
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
To be fully HSTS compliant you should only issue the response header over a secure transport layer. You can find more details in the previous blog that I linked. Whilst it's not essential, it is advised.
OCSP Stapling
Whilst OCSP Stapling doesn't have an impact on your SSL Test result, it's highly advised that you enable it. You can find all the information you need about OCSP Stapling in my previous blog and there are details there on how to implement it too. It's really quick and simple to setup and whilst we're here improving everything, you may as well enable another awesome feature.
SHA1 vs SHA256 Certificates
(Added 22nd Sept 2014)
Google recently announced that following the deprecation of SHA1 in 2011 they are starting the sunsetting process for the cryptographic hash. Announced on their Online Security Blog, users will soon start to see various HTTPS warning indicators on websites that still use SHA1 certificates or chains that contain SHA1 certificates. You can read more details in the linked article. Due to this, Qualys have updated their SSL Test to indicate when a certificate, either the leaf or a certificate in the chain, is using SHA1. This means for the time being that my blog is currently only scoring an A rating instead of the A+ as I have a SHA1 certificate. As my certificate expires in December (2014) which is only a few months away, I'm not going to replace it and revoke the current one, I will upgrade to SHA256 when I renew. This is what the rating looks like at the time of writing with a SHA1 certificate.
UPDATE 23rd Dec 2014
Having now renewed my certificate and upgraded to SHA256 I'm back to scoring an A+ on the Qualys Test.
TLS_FALLBACK_SCSV
(Added 23rd Dec 2014)
TLS_FALLBACK_SCSV is a Signalling Cipher Suite Value (the SCSV part) that allows a browser to indicate to a server when the current connection attempt is a fallback attempt. When present in the client hello, the server knows that the connecting client can use a better protocol than it is currently connecting with and will reject the connection. TLS_FALLBACK_SCSV gained a lot of popularity after POODLE as it would prevent clients that supported TLS from being forced back to SSLv3 to be attacked. It's a great feature to support on your server as it will prevent a client being forced back from TLSv1.2 to TLSv1.1 for example. We don't really want to be in a situation where an attacker can dictate the protocol we use to communite so TLS_FALLBACK_SCSV is highly advised.
(Update 11th Jan 2015)
Changes to the Qualys SSL Test now require TLS_FALLBACK_SCSV support to get an A+ rating. You will need to patch your servers but no further configuration should be required to introduce support.
Loading Your NginX Config
Now that your config files have been modified and saved, you need to load them into nginx. A simple reload command will do the trick and nginx will also check the config file doesn't have any obvious syntax flaws before it tries to load it. This prevents your server being taken offline for something as simple as missing a semi-colon!
sudo service nginx reload
Assuming you don't get any errors and the service reloads the config, you can head straight over to the SSL Test and fire up another one to check out your new score! Once the test has completed, you should see something similar to my score at the top!
Conclusion
Making huge improvements to your transport layer security isn't really that difficult. In the worst case scenario you might need to update a package or two to get the latest protocol and cipher suite support. In the space of half an hour you can take your site from failing the SSL Test to obtaining an A+ grade, the highest achievable. It's very interesting to put some big name sites in the test and see just how bad some of the configurations out there really are. Any server that supports SSLv2 automatically gets an F and fails the test because the protocol is no longer considered secure. That said, a browser will still give you the green padlock in the address bar to indicate a 'secure' connection and the sheer number of websites that still support this protocol is staggering. If you implement the above changes and get an A+ rating for your site, please share a link to the results in the comments below!
Read More: Squeezing a little more out of your Qualys score
- Getting an A+ on the Qualys SSL Test - Windows Edition