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.
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.
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.
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>
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!
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.