Saturday, July 4, 2020

Getting an A+ Score on Qualys' SSL Server Test

On a lark, to get some experience with configuring HTTPS servers, I decided to host the Flightware frontends on my RaspberryPi on an HTTPS endpoint instead of the default HTTP. The broad steps to do this were:

  1. Getting a certificate for my site via LetsEncrypt's certbot
  2. Enabling the HTTPS endpoint on Lighttpd
  3. Testing the security of the setup via the Qualys SSL Server Test
It took some trial and error to get an A+ rating for my server's SSL setup. The two key steps involved in improving the security of the setup were:
  1. Starting with a strong SSL configuration generated by Mozilla's SSL Configuration Generator. This means no SSL v2, SSL v3 or anything below TLS v1.2, and setting up HSTS
  2. Configuring DNS CAA records for the domain. Here's how my CAA record is configured on Google Domains:

    dig caa element77.com +short

    0 issue "letsencrypt.org"

    0 issue "pki.goog"

    0 iodef "mailto:caa@element77.com"

    0 issue "amazon.com"

I haven't set up OCSP stapling yet but that's an exercise for the future. Here's my full SSL configuration for the server.

  1 # /usr/share/doc/lighttpd/ssl.txt

  2 

  3 server.modules += ( "mod_openssl" )

  4         

  5 $SERVER["socket"] == "0.0.0.0:443" {

  6         ssl.engine = "enable"

  7         ssl.privkey= "/etc/letsencrypt/live/piaware.element77.com/privkey.pem"

  8         ssl.pemfile = "/etc/letsencrypt/live/piaware.element77.com/fullchain.pem"

  9         ssl.ca-file = "/etc/letsencrypt/live/piaware.element77.com/chain.pem"

 10         

 11 # Test via https://www.ssllabs.com/ssltest/analyze.html?d=piaware.element77.com

 12 # See https://www.raymii.org/s/tutorials/Strong_SSL_Security_On_lighttpd.html

 13 # See https://ssl-config.mozilla.org/#server=lighttpd&version=1.4.55&config=intermediate&openssl=1.1.1d&guideline=5.4

 14 # modern configuration

 15         ssl.openssl.ssl-conf-cmd = ("Protocol" => "ALL, -SSLv2, -SSLv3, -TLSv1, -TLSv1.1")

 16         ssl.honor-cipher-order = "disable"

 17         ssl.cipher-list = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-    GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"

 18         ssl.dh-file = "/etc/ssl/certs/dhparam.pem"

 19         ssl.ec-curve = "secp384r1" 

 20 }               

 21                 

 22 server.modules += ( "mod_setenv" )

 23 $HTTP["scheme"] == "https" {

 24         setenv.set-response-header = (

 25                 "Strict-Transport-Security" => "max-age=31536000; includeSubdomains",

 26                 "X-Frame-Options" => "DENY",

 27                 "Content-Security-Policy" => "frame-src none;"

 28         )

 29 }       

 30                 

 31 # Redirect HTTP to HTTPS only on port 80

 32 # dump1090-fa data is served on 8080 on HTTP

 33 $HTTP["scheme"] == "http" {

 34         $SERVER["socket"] == ":80" {

 35                 url.redirect = ("" => "https://${url.authority}${url.path}${qsa}")

 36         }

 37 }


No comments: