Updated: January 2019 with latest suggestions and revised commentary.
Updated: May 2016 with new cipher suggestions and revised commentary.
We routinely use SSL Labs to verify systems we’ve configured. It’s a great service to verify that an SSL configuration is reasonably secure. It scores a site in four different areas: Certificate, Protocol Support, Key Exchange, and Cipher Strength. A perfect score is theoretically possible, but isn’t practical because many client/OS combinations couldn’t connect to your site.
How do you maximize your score with a configuration that still allows nearly universal access?
Our goals are to:
1. Maximize the overall score from SSL Labs.
2. Ensure Forward Secrecy on the maximum number of clients.
3. Given #2, use the most secure cipher on each client.
We do allow AES128 as current thinking is it’s not less secure than AES256. You can drop this yourself by changing “AES” in our cipher list to “AES256”, but be aware that you will then drop some clients from AES128 to 3DES. You may have PHBs demanding “256 bit encryption”: Our cipher ordering keeps 256 preferred over 128, so clients that support 256 should be using it.
Our cipher preference order is:
1. ECDHE and AES GCM (256 before 128)
2. ECDHE and AES CBC (256 before 128)
3. DHE and AES GCM (256 before 128)
4. DHE and AES CBC (256 before 128)
We have further tweaked this cipher selection and ordering to support HTTP/2 in Firefox and other major browsers.
If you have any suggestions for improving this, or have configurations for more applications than we’re currently listing below, please comment and share!
Here’s our current approach:
1. Make sure your OpenSSL supports ECDHE, GCM, and TLS 1.2
You must be using OpenSSL 1.0.1+ to support TLS 1.2. If your distribution isn’t shipping this, it’s time to consider a new distribution.
Check and verify that your OpenSSL supports TLS 1.2 and Elliptic Curve Diffie–Hellman. TLSv1.2, GCM, and ECDHE are indicated below:
$ openssl ciphers -v | grep TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384 ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384 ... ... ECDH-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128) Mac=SHA256 AES128-GCM-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(128) Mac=AEAD AES128-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA256
If you’re not using a distribution that supports ECDHE,
follow our article on compiling your own copy of OpenSSL here. Run away!
2. Force TLS 1.2+ Only
SSL Labs agent capabilities list that all current browsers on all current operating systems support TLS 1.2.
Warning: Many large legitimate mail servers do not support TLSv1.2 yet, even in 2019.
Jan 26 05:12:54 server postfix/smtpd: Anonymous TLS connection established from newsletter42.walmart.com[22.214.171.124]: TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits) Jan 23 01:10:33 server postfix/smtpd: Anonymous TLS connection established from egssmtp04.att.com[126.96.36.199]: TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits) Jan 16 09:29:28 server postfix/smtpd: Anonymous TLS connection established from mta15.schwab.com[188.8.131.52]: TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)
(seriously Charles Schwab?)
smtpd_use_tls = yes smtpd_tls_mandatory_protocols = TLSv1, TLSv1.1, TLSv1.2 smtpd_tls_protocols = TLSv1, TLSv1.1, TLSv1.2 smtp_use_tls = yes smtp_tls_mandatory_protocols = TLSv1, TLSv1.1, TLSv1.2 smtp_tls_protocols = TLSv1, TLSv1.1, TLSv1.2
ssl_protocols = TLSv1.2
listen: - port: 5222 ... ... protocol_options: - "no_sslv2" - "no_sslv3" - "no_tlsv1" - "no_tlsv1_1" s2s_protocol_options: - "no_sslv2" - "no_sslv3" - "no_tlsv1" - "no_tlsv1_1"
3. Force a secure cipher list and cipher order preference
SSLHonorCipherOrder on SSLCipherSuite "ECDHE+AESGCM ECDHE+AES DHE+AESGCM DHE+AES"
ssl_prefer_server_ciphers on; ssl_ciphers ECDHE+AESGCM:ECDHE+AES:DHE+AESGCM:DHE+AES;
tls_high_cipherlist = ECDH+aRSA+AES256:ECDH+aRSA+AES128:AES256-SHA smtpd_tls_ciphers = high smtpd_tls_mandatory_ciphers = high smtp_tls_ciphers = high smtp_tls_mandatory_ciphers = high
ssl_prefer_server_ciphers = yes ssl_cipher_list = ECDHE+AESGCM ECDHE+AES DHE+AESGCM DHE+AES
listen: - port: 5222 ... ciphers: - "ECDHE+AESGCM ECDHE+AES DHE+AESGCM DHE+AES"
Use your browser, mail client, xmpp client and SSL Labs to test your new configuration. Do not make changes without testing – one typo can break your service.
Review the entire set of test results carefully.
- You should have nothing in red anywhere outside of the Handshake Simulation
- You should have Forward Secrecy on every client and browser except on Windows XP
Pay special attention to the Handshake Simulation section, where you can see which browsers will have problems connecting to your site.
5. Going for the SSL Labs’ A+
SSL Labs won’t give you an A+ without Strict Transport Security enabled. You’ll only want to enable this on domains where the entire site is expected to utilize HTTPS and you never want a browser to connect using HTTP.
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
* Submit your HSTS protected site to the browser preload list: https://hstspreload.appspot.com/
* Enable OCSP Stapling.
* Enable DNS CAA. You can use SSLMate to generate CAA records for your DNS server/Certificate Authority. If you’re like us and using letsencrypt, the record is simply:
IN CAA 0 issue "letsencrypt.org"