Strong TLS Configuration (and Getting an A+ On the SSL Test)

In yet another case of improper defaults, two of the most common web servers on the internet today do an unnecessarily poor job of securing “secure” connections. Below are snippets you can use in Apache or Nginx to better protect connections to your server of choice (I’m assuming you already know how to configure your server and are just looking for optimal configuration options). You can read further below to learn some more about the why. Because we’re nerds, you’ll want to run your site through Qualys’ SSLTest before and after to compare results. Be sure to have a look at the tips and caveats section before you go diving right in.

a+ screenshot

Nginx


Apache



Note: I like to remove the IfModule block surrounding the Apache TLS config. In my opinion, the server should fail to start if your TLS config is broken somewhere.

Breakdown

• We select only TLS v1 and upward (on in the case of Apache, deselect all SSL versions enabled by default.
• We limit the set of available ciphers to those in the ‘high security’ group, except those that include MD5, DSS or a NULL algorithm (which breaks down to “DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC3-SHA”).
• Typically, a server will go along with whatever cipher the client requests. In order to enforce forward secrecy on all modern clients, we instruct the server to assert its preference (primarily for IE and Java, surprise surprise).
• Finally, we send an HSTS header which forces the browser to upgrade insecure connections (and gets us an A+!).
• (For Apache only, your DH params should be concatenated to the end of your certificate).

Tips and Caveats

Warning 1: Sending a Strict-Transport-Security (HSTS) header will force any supporting client to upgrade their connections to your server until the max-age specified in the header since you last sent it. It is not trivial to revert, so be sure you intend to serve your site over TLS for the foreseeable future before sending it.
Warning 2: This will break compatibility with IE on Windows XP and Java v6. There are a few options you can enable to fix this, but since both platforms were end-of-life’d some time ago I’m just going to write them off as a lost cause.
Warning 3: Generating your own DH parameters will take a really long time, and consume a ton of resources (I would actually recommend opening a screen or tmux session on a box you don’t care about and having a meal while it runs).
Warning 4: When you behold your A+ rating, it’s tempting to try for all 100s (oh yeah, I know), but the “improvements” you’d need to make provide no real benefit. Your cipher suite can only include 256-bit-or-higher symmetric algorithms (higher bit length does not correlate with greater security), and only TLS v1.2 can be used (there are no significant known attacks on TLS v1 or v1.1). Not to mention you’ll break compatibility with anything built before just about yesterday (see what your handshake simulation would look like here).
Tip 1: Using a 4096-bit key gets you an easy ‘100’ on Key Exchange, but as enlightened people we don’t care about such things of course.
Tip 2: Since your DH params don’t need to be secret, you can borrow one from elsewhere instead of generating it yourself. If you do, just try to get it from a relatively unpopular (preferably not even public) source.
Tip 3: Remember the realities of encryption.
xkcd security comic
Note 1: The SSL Test also scans for common vulnerabilities, so if you’re exposed to something recent your score won’t look good. Be sure to always keep your server up-to-date, and check your score before and after you make any changes. Read up on some recent ones here.
Note 2: You can consider adding ‘includeSubdomains’ to your HSTS header if appropriate for your use case.

Optional Additions

Online Certificate Status Protocol (OCSP) Stapling: Due to the size of CRLs (Certificate Revocation Lists) these days, OCSP was brought about to reduce the burden on both user agent and issuer in this respect. Unfortunately, OCSP has been less than reliable, so browser manufacturers have had to disregard OCSP when the issuer fails to respond in a timely manner. OCSP stapling allows your server to cache a valid response from an OCSP server and deliver it to the client during a handshake, thereby reducing the client’s burden and eliminating the potential for a timeout condition.
HTTP Public Key Pinning (HPKP): This one is definitely designed for larger organizations (but knowledge is knowledge). This tells the browser that it should accept certificates for this domain only from a specified issuer. This reduces your exposure to fraudulent certificates issued for your domain.

Further Reading

• The SSLTest’s scoring guide: https://www.ssllabs.com/downloads/SSL_Server_Rating_Guide.pdf
• Mozilla’s wiki entry for TLS: https://wiki.mozilla.org/Security/Server_Side_TLS
• Details on the draft of TLS v1.3 (mostly removing unused and insecure features): https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_1.3_.28draft.29
• SSL Labs’ own list of testing tools: https://github.com/ssllabs/research/wiki/Assessment-Tools

Bonus – Generating your CSR and key in a one-liner