Secure SSL certificate configuration with Nginx
tl;dr: Secure SSL cert config for Nginx (grade A-rated on GlobalSign SSL cert checker)
UPDATE 8th July 2014: I have amended my config slightly to use OWASP recommended ciphers and some updates to Debian core libs mean this configuration now produces an A+ result.
It's been quite some time since I wrote a blog post and there are a fair number of reasons for this, not least is that I have migrated this blog from Wordpress to Ghost which took up a lot of time as it also included a platform migration to AWS. During this migration, i decided that my architecture would include SPDY so I needed an SSL certificate and thus needed to configure said certificate.
As a bit of pertinent background information, my web server runs Nginx which proxies requests to Ghost, a NodeJS app. My Nginx install comes from the awesome dotdeb so SPDY support is really easy, as easy as installing the SSL cert and adding the "SPDY" keyword to the listen directive in Nginx:
server {
listen 443 ssl spdy;
server_name thedotproduct.org;
...
}
So that's great, we're up an running with SPDY, tidy!
After getting SPDY working, I wanted to check my SSL cert was working for people other than just me on my browser in my little world so I ran a test using Globalsign's SSL cert checker which was really helpful. I then started reading as SSL ciphers and so on are something I knew a little but not a lot about, I confess that I'm still not a hardcore expert but I have decent understanding of the basics now.
Immediately from the test results, it was clear that some basic remedial actions were needed such as disabling SSLv2 and SSLv3 since no decent, half-modern browser needs them and they contain known weaknesses. Choosing the best combination of SSL ciphers was less simple but after a number of hours reading, tweaking and testing, I came up with the following configuration which achieves a grade A rating on the GlobalSign SSL cert checker:
Here are the test results:
The only compromise I am left with is being vulnerable to the BEAST attack. The choice I had in this regard was using an RC4 cipher which is fairly widely believed to have been compromised by the NSA or being vulnerable to the BEAST attack and since the BEAST attack has now been mitigated in most modern browsers and is by all counts extremely difficult to execute, I see that as the less nasty option. I could simply disable the older TLS versions but too many browsers require them (either because they don't support newer cryptogaphic protocols or they're for some ridiculous reason disabled by default - IE, Firefox, I'm looking at you!) so we'll have to live with them for the moment at least. Here's a rundown on what is configured (with wording according to test results):
- SSL 2.0 Disabled
- SSL 3.0 Disabled
- TLS 1.0 Enabled
- TLS 1.1 Enabled
- TLS 1.2 Enabled
- Weak ciphersuites) disabled
- Certificates configured correctly
- Perfect forward secrecy
- Secure renegotiation configured
- Session resumption configured
- OCSP Stapling
- PCI Compliance
- FIPS Compliance
If you're going for FIPS or PCI DSS compliance or a similar accreditation, you should note that this will almost certainly mandate how you handle keys and other sensitive info/files as well as the way in which your SSL certificate usage is configured.
I am pretty confident that this is the best (which is an opinion and/or requirement-specific of course) SSL config possible right now, at least under Nginx but if you know different, please let me know via a comment below.
Hopefully this'll help if you need to set up an SSL cert under Nginx. Many thanks to those who wrote the references I used, mainly these:
- https://raymii.org/s/tutorials/Pass_the_SSL_Labs_Test_onNGINX(Mitigate_the_CRIME_and_BEASTattack-_DisableSSLv2-_Enable_PFS).html
- https://coderwall.com/p/ebl2qa
- http://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
- http://code-bear.com/bearlog/2013/06/26/nginx-ssl-config-for-forward-secrecy/
- http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_timeout
- http://unmitigatedrisk.com/?p=354
- http://www.westphahl.net/blog/2012/01/03/setting-up-https-with-nginx-and-startssl/
Cheers!