Configuring SSL/TLS settings in a Linux web server can be tricky. There are many details to get right. To make sure our SSL/TLS security is top-notch, we can use Qualys’s SSLLabs online tool. Let’s review how to get a 100% SSL/TLS Score on SSLLabs online testing tool.

A+ perfect SSLLabs Score
A+ Perfect SSLLabs Score

Qualys’s SSLLabs is an online tool that tests a website’s SSL/TLS configurations for all current SSL/TLS security best practices. “Current” is the keyword here. This is because the standards for SSL/TLS security settings are always changing. So it is important to test your website’s SSL/TLS settings regularly.


This article is the seventh in the Diamond Hard LAMP series.


How Much Security is Too Much Security?

Getting a perfect 100% in all SSLLabs categories has its downsides. To achieve 100 across the board requires extremely strict settings. Having strict settings means most older browsers will not be compatible with your website. The older browsers will just display an error to their users, and your site will be inaccessible.

A+ 90% SSLLabs Score

So, what’s the happy middle ground?

Focus on getting an “A+” rating, not 100 in all categories. Even weaker SSL/TLS settings are pretty strong. You would need the resources of a nation-state actor to leverage weak SSL/TLS implementations. So in our risk analysis using some weaker SSL/TLS settings is not a big issue. With this knowledge, we can relax some of our settings to be more compatible.

The key setting that impacts compatibility the most is the Cipher Suite. A Cipher Suite combines multiple algorithms to negotiate security settings during the SSL/TLS handshake. Older or outdated browsers cannot negotiate with all the newer and stronger Cipher Suites.


Drake meme: Strong less compatible security better for 100% SSLLabs Score bragging rights.

What to Know Before Begining

The following settings are for Apache 2.4+ running on Debian flavors of Linux, i.e. Ubuntu, Debian, Mint, etc. This article assumes you know the basics of managing a Linux webserver.

As discussed in the previous section, you don’t need a perfect 100 score in SSLLabs to be secure. However, I understand the desire to have a perfect score. So, I will include two sets of settings; Strong & Perfect.

Ok, let’s jump into this!


Site Certificate Generation

To get a 100 in this category your website must be using a Trusted Certificate Authority, and have a 4096 bit or greater certificate key size. I use LetsEncrypt, as I expect most of you do. So below is how you issue a certificate with a 4096 key size using CertBot.

certbot certonly -n --apache --rsa-key-size 4096 --staple-ocsp -d CyberGladius.com

A smaller 2048 private key does have some speed advantages during the key exchange process and CPU resource usage. So having a smaller private key may be a better option for you. Using a 2048 bit key over a 4096-bit key will drop your Key Exchange categorize score from 100 to 90. Still very strong and has an “A+” rating in SSLLabs.


Generating A Diffie-Hellman Key for Perfect Forward Secrecy

Its sounds like word soup, huh? We are generating a Diffie-Hellman(DH) key to use with an Elliptical Curve algorithm, which gives our server Perfect Forward Secrecy(PFS).

Why do we need this?

Let’s say an attacker gets a hold of the server’s private key; with PFS, they will not be able to decrypt past communications. How PFS works is complicated, but we don’t need to understand it to use it. We only need to generate the DH key and add the key location to our SSL/TLS settings. Just run the following commands to generate a unique DH key for your server

Warning: This will take a long time to generate, maybe hours, and will take a lot of CPU resources!

# Generate DH Key.
sudo openssl dhparam -out /etc/ssl/private/dhparams_4096.pem 4096
# Set the DH key Permissions
sudo chmod 640 /etc/ssl/private/dhparams_4096.pem
sudo chown root:root /etc/ssl/private/dhparams_4096.pem

Once your new DH key generation is complete move on to the next section.


Protocol Support, Key Exchange, & Cipher Strength

The following settings are what you need to get a 100% SSL/TLS Score on SSLLabs. I am not going to explain every setting and why it is needed, that is beyond the scope of this article. If you wish to understand why these settings are needed see the below “Resource” section for follow-up reading.

Let’s jump into the core of the configurations that affect the SSL/TLS security and SSLLabs score.

The SSL/TLS Apache module is configured either site-by-site or globally. I prefer enforcing the settings globally to ensure all sites on the server have strong SSL/TLS settings. However, you can override the global settings for specific sites if needed.

Files to make setting changes to.

  • Global Settings : /etc/apache2/mods-available/ssl.conf
  • Site Settings : /etc/apache2/sites-enabled/example.com.conf

I chose to have all my settings global, so below are some of my settings from the “/etc/apache2/mods-available/ssl.conf” file. You should be able to copy and paste these settings into your “ssl.conf” file between the “<IfModule mod_ssl.c>” and “</IfModule>”.

When you add these settings to your “ssl.conf” file, make sure you uncomment one of the two “SSLCipherSuite” options based on how much security you want.

# - Allow only strong TLS
SSLProtocol -ALL +TLSv1.2 +TLSv1.3
# - Disable compression, mitigate CRIME attack.
SSLCompression off
# - Deny insecure reconnects
SSLSessionTickets off
# - Try ciphers in the order listed. Try the strongest ciphers first until a compatible one is found.
SSLHonorCipherOrder on
# - Denies access if the client does not pass the host restriction or supplies a invalid user name and password.
SSLOptions +StrictRequire
# - Global DHParam key for Elliptic Curve
SSLOpenSSLConfCmd DHParameters "/etc/ssl/private/dhparams_4096.pem"
#
############
# Pick "Strong & Compatible" OR "Perfect SSLLabs Score"
###
## --- Strong & Compatible ----
#
# - Preferred Elliptic Curve
#SSLOpenSSLConfCmd ECDHParameters prime256v1
#
# - Other accepted Elliptic Curve
#SSLOpenSSLConfCmd Curves brainpoolP512r1:secp521r1:brainpoolP384r1:secp384r1:brainpoolP256r1:prime256v1
#
# - TLSv1.3 Settings
#SSLCipherSuite TLSv1.3 TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256
#
# - TLSv1.2 Settings
#SSLCipherSuite HIGH:!MEDIUM:!LOW:!aNULL:!eNULL:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!SEED:!DSS:!CAMELLIA:!SHA:!kSRP:-kRSA
#
####
## ---- Perfect SSLLabs Score Settings ----
#
# - Preferred Elliptic Curve
SSLOpenSSLConfCmd ECDHParameters brainpoolP512r1
#
# - Other accepted Elliptic Curve
SSLOpenSSLConfCmd Curves brainpoolP512r1:sect571r1:secp521r1:secp384r1
#
# - TLSv1.3 Settings
SSLCipherSuite TLSv1.3 TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384
#
# - TLSv1.2 Settings
SSLCipherSuite TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:PSK-CHACHA20-POLY1305:ECDHE-PSK-CHACHA20-POLY1305:DHE-PSK-CHACHA20-POLY1305:RSA-PSK-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384:DH-RSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:DH-DSS-AES256-GCM-SHA384:ADH-AES256-GCM-SHA384:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDH-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-CCM8:DHE-RSA-AES256-CCM:PSK-AES256-CCM:DHE-PSK-AES256-CCM:PSK-AES256-CCM8:DHE-PSK-AES256-CCM8:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-AES256-CCM8
#
############
# - OCSP Stapling, only in httpd 2.3.3 and later
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
#
# - HTTP Strict Transport Security Header.
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomainsi; preload"
#
# - Set a same origin policy
Header always set X-Frame-Options SAMEORIGIN
#
# - Rewrite any session cookies to make them more secure
# - Make ALL cookies created by this server are HttpOnly and Secure Header always edit Set-Cookie (.*) "$1;HttpOnly;Secure"
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
#
#Prevent browsers doing MIME Type sniffing.
Header always set X-Content-Type-Options nosniff

Apply Settings and Test!

Ok, now that we have made all our setting changes and installed the new certificates let’s apply the changes.

# Stop and Start Apache
sudo apachectl stop && sleep 5 && sudo apachectl start 

Apache should now have all the new settings needed to get 100% SSL/TLS Score on the SSLLabs test!


Resource

Below is additional reading on this subject, and the sources I collected my research from. I link them here encase you are looking for more depth on the topic.