SSL/TLS best practices for websites
Keeping Secrets
SSL and its successor TLS are a never-ending source of surprises – even for me, and I have been using these encryption technologies since the early days of Netscape Navigator. When you think you finally understand SSL, a new mystery opens up, and you find yourself delving the depths again.
Most admins don't have time for long searches. Admins want to set up a secure HTTPS website as quickly as possible and turn to the next task. This article provides advice on using SSL for web practitioners, and I'll even include some sample files for Apache and Nginx.
1. Algorithms and Key Lengths
Currently, TLS supports three key algorithms: DSA is dead; the future belongs to elliptic curve cryptography with ECDSA, but older clients do not support it, so the standard also supports RSA for now.
The key length of 2048 bits for RSA keys, or 256 bits for ECDSA, should be sufficient for most purposes. Keys of this length offer 112 or 128 bits of encryption strength. If you want a future-proof solution, you can opt for a 3072-bit RSA key, which also gives you 128 bits of encryption.
2. KeyManagement
What is more important than the length of the key in practice, however, is the way the admin handles the keys. Much evidence suggests that the most successful attacks on SSL have not actually cracked the encryption but simply avoided it. If you can break into a server to steal the private keys, or otherwise gain access to them, you do not need to break your teeth on the cryptography.
The private keys must remain secret. Only a small group of employees should have access to these valuable files – just enough to ensure smooth operations.
Additionally, the admin should protect the keys with a password and enter a passphrase when generating them. These precautions reduce the risk if a backup of the system gets into the wrong hands.
The person in charge should keep a copy of the keys in a safe place. Losing the key for a single server is not too bad, because a new one can be easily generated. But, if you operate your own certificate authority (CA), keys are extremely complex to replace.
3. TheCertificate
The SSL certificate should come from a reputable certification authority, but you do not need to put too much thought into the choice. In the case of Domain Validated (DV) certificates, the lowest price wins. If your site has many users, certificates with extended validation (EV) leave a better impression, but they hardly increase the technical security.
The certificate needs to contain all the hostnames – including the versions with and without the WWW prefix, as in, example.com and http://www.example.com. The "Key and Certificate Sharing" box provides more instructions on using multiple hostnames.
The certification chain needs to be complete. Broken chains are among the most common deficiencies. Some browsers can handle a broken chain, but the problem can lead to hard-to-understand errors.
The CA should sign its certificates using SHA-256. It also needs to embed revocation information in the form of certificate revocation lists (CRLs) and an online certificate status protocol (OCSP). If you want to play CA yourself, read the box titled "Self-Signed or Private CA."
4. Protocols
A public website must support the TLS 1.0, TLS 1.1, and TLS 1.2 protocols. SSL 2 is obsolete and insecure. SSL 3 is also deprecated and, although it is not inherently insecure, it lacks many important features of more modern protocols. Therefore, it is a good idea to disable SSL 3 if there is no special reason to keep it. Nearly all clients support at least TLS version 1.0.
5. Cipher-SuitePreference
The ability to specify cipher suites that the server should use by preference is a very useful feature. Because TLS ensures the integrity of the handshake, the attacker cannot use the preference mechanism to stipulate weaker encryption.
6. Choice ofCipher Suite
I recommend strong ciphers that implement 128-bit encryption. This list includes AES and Camellia, but AES offers the advantage that it can be used with authenticated suites that support GCM mode. And, AES is faster. Authenticated suites are your best option for TLS and avoid potentially insecure cipher-block chaining suites. 3DES offers 112 bits strength and is suitable for interoperability with older clients. You should avoid RC4, which is insecure.
You will also want to steer clear of cipher block chaining suites that use SHA-256 and SHA-384 to validate integrity. These options are noticeably slower than SHA-1 and offer no significant security advantages. The shortcomings are irrelevant in SHA-1 in this case, because validation relies on HMAC. SHA-256 and SHA-384 are also nominally GCM suites, but because they work differently from authenticated suites, the performance difference is not noticeable.
For a key exchange via ECDHE, the secp256r1
curve offers the best performance and 128-bit security. Other curves are a lot slower or poorly supported. Compared to DHE, ECDHE is always preferable for achieving good performance even with a 2048-bit key length.
Admins should steer clear of the RSA key exchange, unless circumstances force their hand, because it does not offer forward secrecy. It is safer to search for the abbreviation ECDHE or DHE in the name of the cipher suite. This helps you achieve forward secrecy, which means that each individual connection to the site is protected with an individual key.
Without forward secrecy, the security of all connections depends on the confidentiality of the server's private key. Should the private key ever be stolen or cracked, a hacker can retroactively decrypt sniffed network traffic.
For OpenSSL version 1.0.1 with elliptic-curve cryptography enabled, based on all these considerations, it is advisable to choose the suites from Listing 1 in the stated order. The collection is divided into two groups by an empty line. If you have a group of users with modern software, you can ignore the last five suites because they use the RSA key exchange and offer no forward secrecy. Add RC4-SHA at the end if it is essential for interoperability.
Listing 1: Cipher Suites
01 ECDHE-ECDSA-AES128-GCM-SHA256 02 ECDHE-ECDSA-AES256-GCM-SHA384 03 ECDHE-RSA-AES128-GCM-SHA256 04 ECDHE-RSA-AES256-GCM-SHA384 05 DHE-RSA-AES128-GCM-SHA256 06 DHE-RSA-AES256-GCM-SHA384 07 ECDHE-ECDSA-AES128-SHA 08 ECDHE-ECDSA-AES256-SHA 09 ECDHE-ECDSA-DES-CBC3-SHA 10 ECDHE-RSA-AES128-SHA 11 ECDHE-RSA-AES256-SHA 12 ECDHE-RSA-DES-CBC3-SHA 13 DHE-RSA-AES128-SHA 14 DHE-RSA-AES256-SHA 15 EDH-RSA-DES-CBC3-SHA 16 17 AES128-GCM-SHA256 18 AES256-GCM-SHA384 19 AES128-SHA 20 AES256-SHA 21 DES-CBC3-SHA
Listings later in this article demonstrate the configuration of these suites for specific servers.
7. OCSPStapling
The stapling extension of the online certificate status protocol (OCSP) allows operators of a website to offer call-back information for certificates on their own server. Without stapling, a client must contact the CA to ensure that a certificate has not been revoked. Stapling makes the site faster; users do not need to tell the CA which pages they are visiting, and the site is independent of the performance of the CA's OCSP responder.
8. DamageMitigation
As with any software, the risk of serious security gaps is also possible in the TLS/SSL stack. In most cases, you can stuff the holes with patches. In the interests of security, you should familiarize yourself with the main attacks against transport encryption: Beast, Crime, Time, Breach, RC4-Bias, Lucky 13, and the Triple Handshake attack.
9. Heartbleed
A vulnerability in the widespread free crypto library OpenSSL, named Heartbleed, has been known since April 2014. Heartbleed has nothing to do with cryptography itself but was caused by a programming error. The consequences for a vulnerable server are devastating, because attackers can grab the private key through the hole. Ready-made attack tools are available on the Internet for downloading; every server operator should thus be familiar with Heartbleed.
Admins must adhere to the following steps when they discover that their servers are vulnerable to Heartbleed:
- Update the affected systems to close the gap.
- Generate new private keys, procure new certificates, and revoke the existing certificates.
- Replace the ticket key if session tickets are used.
- Assess whether other confidential data was stolen due to the vulnerability. For example, passwords might have been in memory areas that were read. If so, notify the users and ask them to change their passwords.
10. HTTP
Although SSL and TLS have been developed to secure any connection-oriented protocol, the most important need was that of protecting HTTP. Still today, encrypted access to websites is the most common use for TLS. However, the web has evolved from a simple system for the delivery of documents to a complex application platform.
10.1 No MixedContent
Encryption is not included in the HTTP repertoire. Therefore, many websites do not use encryption. Often the reason is the extra effort and the expertise required. Additionally, some web browsers complicate the situation by allowing providers to mix secure and unsecured content within an HTML page.
For security reasons, it is best to set up transport encryption for the complete domain name, including its sub-domains. The use of HTTP Strict Transport Security (HSTS) also prevents mixed content from the same domain, and Content Security Policy prevents insecure content from third parties.
10.2 CookieSecurity
HTTP cookies that the developer do not declare as secure, rip a hole in the security concept. An attacker on the network can still read cookies on fully encrypted websites. A point that deserves special attention in quality assurance of web projects. Also, casual cookie rules allow an attacker to inject cookies into other web applications.
An attacker will typically use an application on a related subdomain; that is, attack www.example.com
through blog.example.com
or use a fictitious subdomain. Although this technique does not give the attacker confidential information, a skilled attacker might be able to elevate their privileges through the application.
As an antidote, cookie encryption or integrity checking is recommended. Although cookie encryption is more secure, you can use integrity checking as alternative if the cookies need to be readable for JavaScript.
10.3 HSTS
HTTP Strict Transport Security (HSTS), described in RFC 6797 [1], implements strict rules for encrypting websites. The server discloses the policies in the HTTP response header to compatible browsers (Figure 2).
If HSTS is enabled, a compliant web browser exclusively uses TLS to communicate with a website. This approach stops a few security holes that are otherwise hard to close, such as visits via plain text bookmarks or links, insecure cookies, SSL stripping, and mixed content in the same domain. Strict Transport Security also ensures secure handling of invalid certificates. Without HSTS, web browsers let the user decide what to do in case of invalid certificates. But, most users cannot distinguish between attacks and misconfigurations, which makes them potential victims of network attacks. With HSTS, however, invalid certificates remain invalid and cannot be worked around. It is best to enable Strict Transport Security for a complete domain name, including its subdomains.
Configuration Recommendations
The following sample configurations require support for elliptic curve cryptography (EC), which is required for a modern SSL deployment. Unfortunately, EC is not available everywhere. In the case of the Apache web server, EC was introduced in version 2.2.6; many older installations do not include the feature. However, the version number alone is not conclusive. Some distributions, such as Debian, have backported EC for their Apache packages.
A quick look at the release notes is therefore essential. Until recently, Fedora and Red Hat still disabled EC; an update to a recent release should remedy add EC support. In case of emergency, you can build Apache 2.4.x from sources with statically linked Open SSL – see the discussion at the my website [2].
Listing 2 shows the Apache instructions for the global SSL configuration. The configuration information resides in different files on different distributions. In the original source code for Apache 2.4.x, the file is $SERVER_ROOT/conf/extra/httpd-ssl.conf
, Debian and Ubuntu use /etc/apache2/mods-available/ssl.conf
, and Red Hat uses /etc/httpd/conf.d/ssl.conf
. The Mod_SSL Guide [3] includes the SSL configuration directives for Apache. Listing 3 shows the configuration for the nginx web server.
Listing 2: Apache Configuration
01 SSLProtocol all -SSLv2 -SSLv3 02 SSLHonorCipherOrder On 03 SSLCipherSuite "ECDHE-ECDSA-AES128-GCM-SHA256 \ 04 ECDHE-ECDSA-AES256-GCM-SHA384 \ 05 ECDHE-RSA-AES128-GCM-SHA256 \ 06 ECDHE-RSA-AES256-GCM-SHA384 \ 07 DHE-RSA-AES128-GCM-SHA256 \ 08 DHE-RSA-AES256-GCM-SHA384 \ 09 ECDHE-ECDSA-AES128-SHA \ 10 ECDHE-ECDSA-AES256-SHA \ 11 ECDHE-ECDSA-DES-CBC3-SHA \ 12 ECDHE-RSA-AES128-SHA \ 13 ECDHE-RSA-AES256-SHA \ 14 ECDHE-RSA-DES-CBC3-SHA \ 15 DHE-RSA-AES128-SHA \ 16 DHE-RSA-AES256-SHA \ 17 EDH-RSA-DES-CBC3-SHA \ 18 AES128-GCM-SHA256 \ 19 AES256-GCM-SHA384 \ 20 AES128-SHA \ 21 AES256-SHA \ 22 DES-CBC3-SHA" 23 24 # Only with Apache 2.2.24+ and Apache 2.4.3+ 25 SSLCompression Off 26 27 SSLSessionCache shmcb:/path/to/ssl_scache(1024000) 28 SSLSessionCacheTimeout 3600 29 30 # Only with Apache 2.4.x 31 SSLUseStapling On 32 SSLStaplingCache shmcb:/path/to/stapling_cache(128000) 33 # HSTS policies are persistent; learn more 34 # about HSTS before enabling the following 35 # rule for best security. 36 #Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Listing 3: Nginx Configuration
01 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 02 ssl_prefer_server_ciphers on; 03 ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-GCM-SHA256 \ ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA \ ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-DES-CBC3-SHA ECDHE-RSA-AES128-SHA ECDHE-RSA-AES256-SHA ECDHE-RSA-DES-CBC3-SHA \ DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA EDH-RSA-DES-CBC3-SHA AES128-GCM-SHA256 AES256-GCM-SHA384 AES128-SHA \ AES256-SHA DES-CBC3-SHA"; 04 ssl_session_cache shared:ssl_session_cache:1M; 05 ssl_session_timeout 60m; 06 # Only with Nginx 1.4.x and newer 07 ssl_stapling on; 08 09 # HSTS policies are persistent; learn more about HSTS 10 # before enabling the following rule for best security. 10 #add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
The instructions are contained in the http
section of the file, which typically resides in /etc/nginx/nginx.conf
. By the way, all the information must be in a single line for the ssl_ciphers
statement. See the Nginx project website for documentation on configuring SSL [4].