Getting an A+ on Qualys SSL Labs' SSL Report

3 minute read Published:

I’m supposed to be studying for the ASA 101 sailing test. Yesterday, I procrastinated by adding another section to The Seven Minute Server and used CSS to create a practice test/quiz for the ASA 101 by hiding the answers until you hover over them. It didn’t get me any closer to finishing the prep book, but it was fun…

Today, when I should have been tying exotic knots, on a whim, I ran my site through Qualys SSL Labs’ SSL Report and was dismayed to see this site got a B. So, of course, I decided that it’s of utmost importance that I get an A+ on Qualys SSL test instead of learning my knots…

I already have SSL enabled on my Apache web server, using a Let’s Encrypt certificate.

I already have all connections to non-secure port 80 redirected to 443 in /etc/httpd/conf/httpd.conf:

  <VirtualHost *:80>
   ServerName sevenminuteserver.com
   Redirect / https://sevenminuteserver.com
  </VirtualHost>

  <VirtualHost *:443>
   ServerName sevenminuteserver.com
  </VirtualHost>

But still the B! So I added the following to my httpd.conf and restarted httpd:

SSLProtocol +SSLv3 +TLSv1.1 +TLSv1.2
SSLCipherSuite HIGH:!aNULL:!eNULL:!kECDH:!aDH:!RC4:!3DES:!CAMELLIA:!MD5:!PSK:!SRP:!KRB5:@STRENGTH
SSLHonorCipherOrder on
SSLCompression off
SSLSessionTickets off

I originally specified individual cipher suites to use, but found that was too restrictive (older versions of Android, specifically, wouldn’t be able to connect).

That got me up to an A, but no A+. You need to enable Strict Transport Security to get an A+. Adding this is pretty straightforward, you simply add the following to your httpd.conf file and restart httpd:

  <IfModule mod_headers.c>
   Header always Set Strict-Transport-Security "max-age=15768000; includeSubdomains; preload" env=HTTPS
  </IfModule>

Note that if you intend to serve non-https sites from subdomains, you’ll want to remove the “includeSubdomains” part. Also, if you’re running multiple VirtualHosts and some won’t be serving https, you should put the Header directive into your specific VirtualHost container.

I had trouble getting headers to work inside my VirtualHost container; I originally thought it had something to do with setting ServerSignature Off and ServerTokens Prod globally (these option settings keep Apache from appending its version numbers to error pages and advertising its version in headers, respectively), but it turned out that when I configured Let’s Encrypt, it created a VirtualHost container on my web server at /etc/httpd/conf.d/ssl.conf – so you can either move that data into your httpd.conf or add your custom header directive into ssl.conf.

After you’ve got your configuration done, restart httpd and test your headers:

curl -iL https://sevenminuteserver.com/ |grep Strict

You should see this:

 Strict-Transport-Security: max-age=15768000; includeSubdomains; preload

Then head back to Qualys and check yer score. Enable the “hidden” button when searching to keep your domain from appearing on the front page…

While I was in there, I changed my error pages:

 ErrorDocument 500 /index.html
 ErrorDocument 400 /index.html
 ErrorDocument 404 /index.html
 ErrorDocument 402 /index.html

If you’re going to be scanning, might as well visit my home page, bots…