Nowadays, the web is moving towards making HTTPS mandatory across all websites. Initiatives like Let’s Encrypt that offer dead-simple https installation, or Root CAs like StartSSL that offer unlimited free certificates or even browsers like Google Chrome that already started deprecating HTTP all contribute into going towards this direction. Many of us think this is the correct way. An HTTPS-only web provides a lot of great advantages over the traditional, HTTP one.
However, just because you can see that little green
https:// in your address bar doesn’t mean you’re secure. There is a vast amount of possible SSL/TLS configurations that a system administrator can make that range from the most secure one yet, all the way to “Rebranded HTTP”. Currently, configuring a web server to be really secure is increasingly difficult and requires the administrator to always watch the latest news for the upcoming attacks and deprecations that may require a change in the configuration.
Fortunately, tools like Qualys' SSL Server Test make the job a little bit easier, as you can run that test against your (or anybody else’s) servers and see a little nice grade on how well you did. This grade can range from
A+ all the way to
F, or even
T. At least that’s how low I’ve seen it go. Maybe you can make an even worse configuration.. ;-)
Now getting an
A+ is not really difficult and ensures that your website is relatively secure, at least as far as HTTPS is concerned. Let’s see how we can get this grade in
Apache 2.2.22 on
Debian Jessie 8.0 with
mod_ssl. For this to work, you need a valid HTTPS Certificate from a Trusted Certificate Authority. In order to start for free, you can use StartSSL. Now you need to make sure this certificate is signed with
SHA-256 (actually the latter is a part of the first). After that, you can create a
VritualHost for your secure website:
<VirtualHost *:443> DocumentRoot "/var/www/" ServerName secure.example.com </VirtualHost>
The above example will create a basic HTTP website for the domain
secure.example.com listening on port
443. Now the next lines can be added below the
Apache to enable HTTPS for this
SSLCertificateFile /path/to/your.crt SSLCertificateKeyFile /path/to/your.key SSLCertificateChainFile /path/to/your.ca-bundle
The above will tell the webserver where is the certificate, the private key, and the certificate chain file. I assume you already have these files.
SSLProtocol -ALL +TLSv1.2
This explicitly enables only
TLS v1.2 for all HTTPS connections, the latest stable version of
TLS that is supported by the latest stable version of
With this set to
on, the web server will try to honor the order of the ciphers in this configuration file. With this current setup, this is not really necessary, but it is recommended to have it set.
Here is the most important line of all. The supported ciphers. In this line we tell
Apache to use
ALL ciphers, except the
EXPort Grade (Weak) Cryptography, ciphers marked as
LOW-strength, and finally, everything that uses
DH (Diffie-Hellman). One could argue that a white-list is better than a black-list, but this is easier to maintain, in a sense that if an attack comes up against a specific cipher in the future, you can easily block it by appending it in the end.
This will tell the server to never renegotiate keys with a client in an insecure way.
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
And finally, enable
HSTS. That is a special header that requires
mod_header to be enabled (use the command
a2enmod header). If a browser visits the website over HTTPS once, it will only visit this website again for the next
31536000 seconds using HTTPS and never falls back to HTTP. Additionally, with
includeSubDomains you can tell the browser to also treat all subdomains in the same way (HTTPS-only).
Now, after running a
service apache2 restart, and running a test for your website, you should see an
A+ with results similar to this. Congratulations on enabling one of the most secure HTTPS configurations on your website!
But is this the best HTTPS configuration you can have? Absolutely not. And I’m not talking about the remaining 10% in “Cipher Strength”. You see, apart from this grade, there are many more things to consider when enabling HTTPS with configurations like this. If you take a look for example at the “Handshake Simulation” area of the detailed report, you see that using this, you leave out some large parts of the Internet Population, like:
Some of these devices are old and some are newer. If you set the configuration above, all these users will never be able to use your HTTPS website. This is clearly a business decision. Do you want to block all these users in order to be more secure or do you want to relax your requirements a little bit but make sure more people have access to the website? If it’s a personal blog it may be okay, but if you’re a huge website like Google Search you might risk even going as low as a B to enable access to more customers. If you consider that it’s nearly impossible to update every Android Phone to 4.4+, then pretty much most Android users are gone! With an iPhone, more people have access, since people using an iPhone 3GS or newer still can visit the website securely. If you exclude the Baidu Crawler, you might appear lower in the Baidu Search Engine Ranks. Again, this is a business decision and depends on how much security you’re willing to sacrifice to enable access to more customers. If you’re a System Administrator it’s probably a good idea to consult an executive before making this decision on your own..