ADUFRAY

I recently wrote about how best to configure one’s SSL using Nginx. Unfortunately I recommended RC4 over many other ciphers because at the time it wasn’t completely broken. That time has come to pass.

Here is my updated configuration, unfortunately dropping SSLv3 entirely (and thus blocking the default configuration for Windows XP on IE6):

ssl_certificate      /path/to/combined.cert.and.ca.crt;
ssl_certificate_key  /path/to/cert.key; (Make sure it's 4096-bits!)
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "!ADH:!MD5:!aNULL:ECDH+AES:DH+AES:@STRENGTH:RSA+AES:3DES";

ssl_dhparam /path/to/strong/dhparam-4096.pem;
add_header Strict-Transport-Security "max-age=31536000";

ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/ca.crt;
resolver 8.8.8.8 valid=300s;
resolver_timeout 5s;

Make sure you create your strong DH parameters file (this took 45 minutes on a 2014 Mac Pro):

# openssl dhparam -out /path/to/strong/dhparam-4096.pem 4096

If you don’t care about IE on XP at all, go ahead and drop 3DES at the end of the ssl_ciphers list. That will give you a very strong rating on the Qualys SSL Labs Server Test tool. Also, if forward secrecy is important to you on Java 6u45, go ahead and comment out the ssl_dhparam part.

About the only thing you can do to get a better score at this point is to really cut back on your supported clients.

Here’s what that looks like:

ssl_certificate      /path/to/combined.cert.and.ca.crt;
ssl_certificate_key  /path/to/cert.key; (Make sure it's 4096-bits!)
ssl_protocols TLSv1.2;
ssl_ciphers "!ADH:!MD5:!aNULL:ECDH+AES256:DH+AES256:@STRENGTH:RSA+AES256";

ssl_dhparam /path/to/strong/dhparam-4096.pem;
add_header Strict-Transport-Security "max-age=31536000";

ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/ca.crt;
resolver 8.8.8.8 valid=300s;
resolver_timeout 5s;

As of December 24, 2014, disabling TLSv1.0 and TLSv1.1 breaks these clients (according to Qualys), so I don’t recommend it:

Note that this is almost entirely due to dropping TLSv1.0 and not due to the lack of AES-128. By turning back on TLSv1.0 and TLSv1.1 (lowering your Protocol Support score from 100 to 95) you only lose these clients:

So, to summarize, here are my current recommended configs, one to maximize client compatibility and one to maximize (practical) security.

Compatibility:

ssl_certificate      /path/to/combined.cert.and.ca.crt;
ssl_certificate_key  /path/to/cert.key; (Make sure it's 4096-bits!)
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "!ADH:!MD5:!aNULL:ECDH+AES:DH+AES:@STRENGTH:RSA+AES:3DES";

ssl_dhparam /path/to/strong/dhparam-4096.pem;
add_header Strict-Transport-Security "max-age=31536000";

ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/ca.crt;
resolver 8.8.8.8 valid=300s;
resolver_timeout 5s;

Security:

ssl_certificate      /path/to/combined.cert.and.ca.crt;
ssl_certificate_key  /path/to/cert.key; (Make sure it's 4096-bits!)
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "!ADH:!MD5:!aNULL:ECDH+AES256:DH+AES256:@STRENGTH:RSA+AES256";

ssl_dhparam /path/to/strong/dhparam-4096.pem;
add_header Strict-Transport-Security "max-age=31536000";

ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/ca.crt;
resolver 8.8.8.8 valid=300s;
resolver_timeout 5s;

I expect I won’t have to update this post soon — or at least not until Nginx enables support for hybrid / dual SSL certificates for the same host. (NOT SNI, but rather having an ECC and RSA certificate for the same site. Apache already supports this and Nginx developers discussed it last year.) That or when OpenSSL supports ChaCha20-Poly1305 (this is possible today by using Google’s fork of OpenSSL, BoringSSL, but it requires manually compiling all the software).