I was using the Let’s Encrypt Certificate, I talked about that setup here. By default with mod_nss and the Let’s Encrypt Cert you will get an A- at the Qualys SSL Labs Test. So let’s make some modifications to setup to get an A+.

Cipher Suite

Mozilla has a pretty good site that talks about different profiles for different browsers with TLS (Security/Server Side TLS). If you check out the Modern profile you can see that it only recommends using TLS 1.2 and some of the old browsers won’t work. Here is the recommended list from that page:

0xC0,0x2C  -  ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(256)    Mac=AEAD
0xC0,0x30  -  ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(256)    Mac=AEAD
0xCC,0x14  -  ECDHE-ECDSA-CHACHA20-POLY1305  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=ChaCha20(256)  Mac=AEAD
0xCC,0x13  -  ECDHE-RSA-CHACHA20-POLY1305    TLSv1.2  Kx=ECDH  Au=RSA    Enc=ChaCha20(256)  Mac=AEAD
0xC0,0x2B  -  ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(128)    Mac=AEAD
0xC0,0x2F  -  ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(128)    Mac=AEAD
0xC0,0x24  -  ECDHE-ECDSA-AES256-SHA384      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(256)       Mac=SHA384
0xC0,0x28  -  ECDHE-RSA-AES256-SHA384        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(256)       Mac=SHA384
0xC0,0x23  -  ECDHE-ECDSA-AES128-SHA256      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(128)       Mac=SHA256
0xC0,0x27  -  ECDHE-RSA-AES128-SHA256        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(128)       Mac=SHA256

I picked a couple of those and just used them and they bumped me to an A. I realized that if I want to support more browsers I will have to enable some less secure ciphers. A lot of the time to keep Forward Secrecy a combination of DHE and ECDHE ciphers will get you there. But I discovered that DHE ciphers just recently became supported with mod_nss and they are getting added as we speak (server support of DHE ciphers). You will notice that DHE support will be in mod_nss 1.0.13 and on my Debian machine I was at the following:

<> dpkg -l libapache2-mod-nss
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version      Architecture Description
+++-==============-============-============-=================================
ii  libapache2-mod 1.0.10-3     amd64        NSS-based SSL module for Apache2

So to support older browsers I ended up enabling two ciphers (while I wait for the DHE support):

TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA

And also TLS v1.1 and v1.0. In the end here is what I had in my mod_nss config:

<> grep -E '^NSSCipher|^NSSPro' /etc/apache2/mods-enabled/nss.conf
NSSCipherSuite +ecdhe_rsa_aes_128_sha,+ecdhe_rsa_aes_256_sha,+rsa_aes_128_sha,+rsa_aes_256_sha
NSSProtocol TLSv1.0,TLSv1.1,TLSv1.2

With that in place I got an A and it covered 99% of the browsers, I only missed old IE ones:

ssl-test-old-brow

Also if you want to quickly test what ciphers your server supports you can use nmap:

<> nmap --script ssl-enum-ciphers -p 443 www.moxz.tk

Starting Nmap 7.12 ( https://nmap.org ) at 2016-05-22 10:28 MDT
Nmap scan report for kerch (10.0.0.2)
Host is up (0.0018s latency).
rDNS record for 10.0.0.2: www.moxz.tk
PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers:
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: server
|_  least strength: A

Nmap done: 1 IP address (1 host up) scanned in 0.36 seconds

Adding the HSTS Header

The thing that got me to the A+ was enabling the HSTS header. The config is covered in HTTP Strict Transport Security for Apache, NGINX and Lighttpd. First I enabled the header module for apache:

<> sudo a2enmod headers
Enabling module headers.
To activate the new configuration, you need to run:
  service apache2 restart

And then I added the header to be set in my virtualhost:

<> grep Header /etc/apache2/sites-enabled/35-www.conf
	# Add the HSTS Header
	Header always set Strict-Transport-Security "max-age=15768000; includeSubdomains; preload"

Then after one more apache restart

sudo systemctl restart apache2

I was able to get the A+:

ssl-test-a-pl

BTW there is good discussion about other results at [Freeipa-users] let’s encrypt integration and best practices for mod_nss/mod_ssl here is an interesting comment about the Session Resumption:

The main reason this is an “orange” alert in SSLLabs is because the server is assigning Session IDs but then ignoring them; although confusing it is a fairly common default behaviour and doesn’t cause any issues with compliant client implementation