5 minute read

Having a decent SSL/TLS configuration for your web server is all the rage lately. And for good reasons, too.

SSL/TLS being enabled alone does not give a good level of assurance against eavesdropping and authentication anymore. Safe ciphers, correct options, proper renegotiation, etc. are just as important, if not more (nothing like having a little “lock” icon in the browser that make you believe you’re safe - yet have an encryption cipher that is trivial to crack).


It’s complicated for everyone, even the professionals.

Anyhow, the current reference to test your website is Qualys’ tool at ssllabs and while it’s not perfect, it’s pretty good. I found quite a few guides on how to configure NGINX to get a decent score (here’s a good one, but not much about Apache. You see, Apache isn’t the cool kid on the block anymore… and the official “mod_ssl introduction” doc is missing some things.

This is an attempt to guide and explain how to do this on Apache - because it’s what I use.

Generating the certificate/keys is out of scope for this post.

What you want your config to include

This is as of 2013-10 - this stuff evolves over time

Click the clicky links if you don’t know what all this stuff means :-)

  • HSTS
  • OCSP stapling
  • Compression for SSL turned off (CRIME).
  • Provide the complete chain of certificates (concatenate all certificates in a file).
  • Ensure the certificate you get and the certificate chain are signed with SHA256 or better (i.e. not SHA1 or MD5).
  • Use a strong private key (RSA 2048 or above, or EC are the current recommendations).
  • A good cipher suite (no known-weak cipher).
  • Mitigate BEAST, when possible.
  • Mitigiate POODLE
  • Perfect Forward Secrecy (even thus there’s no such thing as perfect).
  • SNI, maybe (not a security measure).

Notes about Apache versions (=> use 2.4 or above)

mod_ssl in previous Apache versions (such as 2.2 which is quite popular, still) has issues with the cipher order and selection.

Also, 2.4 has support for OCSP stapling.

DH parameter

Sadly, Apache 2.4 does not have support for setting the DH parameter, and at the time of writing, there's no Apache 2.6 (unless you're running trunk) or backport available (there's a patch tho <https://issues.apache.org/bugzilla/show_bug.cgi?id=49559> ! and an ArchLinux backport) ;-)

Apache 2.4.7 has now been released with the DH parameter patch :-) When using the DH parameter patch with Apache, there is no need for any additional configuration. Apache will automatically use a DH param that is the same size as the private key.


Let’s get right into it!

Different distributions have different path for config files. In general it’s in /etc/httpd/* with files in /etc/httpd/conf and /etc/httpd/conf/extra. Refer to your distro documentation for more information, if you can’t find something.

Check mod_ssl is loaded (duh!)

It’s going to look like:

LoadModule ssl_module modules/mod_ssl.so

If you plan to support SSLv3 clients, and you use SNI, make sure they can get to the default site

SSLStrictSNIVHostCheck off

Enable HSTS everywhere

While there are other ways to do this, it’s easy to ensure in the Apache config. Set max-age to whatever you decide - clients won’t connect to your site in non-SSL/TLS mode after their first visit for that amount of time. If you plan to revert that later (you really should not do that) - still - well, be careful while testing.

Header add Strict-Transport-Security "max-age=15768000"

Enable OCSP stapling

In the main SSL config

SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)

In each virtual host (or the main config if no virtual hosts are used)

SSLCACertificateFile /etc/ssl/apache/ca.pem

Where ca.pem is the CA certificate file (from your CA!).

Turn off SSL compression (CRIME mitigation)

SSLCompression off

Provide the SSL certificate chain to the client directly

In each virtual host (or the main config if no virtual hosts are used):

SSLCertificateChainFile "/etc/ssl/apache/sub.class1.server.ca.pem"

If like many of us, you are a startcom (startssl) user, make sure you get their SHA2-signed certificates from startssl not the default SHA1-signed certs.

Use a (current as of 2014-10) good cipher suite

Only RC4 with TLS 1.0, or TLS 1.1 and above mitigate BEAST. However, RC4 is also considered a weak cipher. RC4 is pretty much considered broken nowadays. Since even the current Firefox does not have TLS 1.1 enabled (note that Nightly can go up to TLS 1.2 with an about:config flag) - I'm choosing to keep TLS 1.0 enabled and provide the RC4 cipher.

I now only provide TLS1.2 as all recent browsers support this properly. This means also no RC4, and also that BEAST is no longer an issue.

Enable only recent TLS protocols

This selection means only recent browsers/clients will be able to connect. You may still allow TLSv1 if you’re supporting older clients (<2013).

# Best but least compatible with older browsers
SSLProtocol all -SSLv2 -SSLv3 -TLSv1

In particular, GoogleBot (and probably some other crawlers) does not support most recent TLS versions. Thus, you may want to keep TLSv1 enabled if you need your site to be indexed.

# Allow GoogleBot and other older clients
SSLProtocol all -SSLv2 -SSLv3

If you do choose to enable SSLv3 for some reason, make sure your version of apache supports TLS_FALLBACK_SCSV. This ensures clients supporting TLS will not be tricked into falling back to SSLv3 (exposing them to the POODLE vulnerability).

Cipher suite settings

Honor the cipher suite, so that clients get the best possible selection of ciphers, depending on what they support:

SSLHonorCipherOrder on

Legacy ciphers support

See Mozilla Server Side TLS for legacy cipher support.

This is the recommended cipher suite I am using (“modern” as per Server_Side_TLS):


The end & TL;DR; copy-pastable configs

Well, that wasn’t so hard after all now was it?

Don’t forget to test your setup at SSL Labs for example :)

For convenience, here’s the complete config options that you’ll generally want to add to your setup (including RC4 support).

File: /etc/httpd/conf/extra/httpd-ssl.conf

# Note: Remove -TLSv1 if you want your site to be indexed by GoogleBot
SSLProtocol all -SSLv2 -SSLv3 -TLSv1
SSLCompression off
SSLHonorCipherOrder on
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)
Header add Strict-Transport-Security "max-age=15768000"

File: /etc/httpd/conf/vhosts.d/yourvirtualhost.conf

This can also go in /etc/httpd/conf/extra/httpd-ssl.conf if you have only the default virtual host, or don’t use virtual hosts, of course.

SSLCertificateChainFile "/etc/ssl/apache/sub.class1.server.ca.pem"
SSLCACertificateFile /etc/ssl/apache/ca.pem