Apache Feather Apaches Secure Sockets Layer protocol is a protocol layer based between the TCP/IP protocol and the application protocol layer (HTTP). SSL provides for secure communication between client and server by allowing mutual authentication and the use of digital signatures for integrity and encryption for privacy.

In todays post I will look at configuring Apache, running on FreeBSD, to use SSL Certificates and provide further security best practices. You can obtain SSL certificates for your web service from Let’s Encrypt. Let’s Encrypt is a free, automated, and open certificate authority (CA), run for the public’s benefit.

Qualys SSL Report

Below is a report from Qualys SSL Labs that checks the most improtant security features for your web server. The site is available here. Also another site that is highly recommended is https://www.immuniweb.com/ssl/. This second site reports on PCI DSS, HIPAA & NIST compliance.

I will be configuring Apache, running on FreeBSD, to recieve an A+ score with Qualys (as below), which in turn will be a good start to keeping your Apache connections secure.

SSL Report

Apache SSL Configuration

I will step through configuring Apache from the most basic configuration, through to adding more advanced security features.

Basic SSL Configuration

Below is the most basic SSL configuration, SSL Certificates have been provided by Let’s Encrypt. I choose to put my global ditectives for SSL in the Includes/ssl.conf file, rather than the host.conf or the httpd.conf file.

Includes/ssl.conf

LoadModule ssl_module libexec/apache24/mod_ssl.so

Listen 443

Includes/pbdigital.org.conf

<VirtualHost *:80>
    ServerName www.pbdigital.org
</VirtualHost>

<VirtualHost *:443>
    ServerName www.pbdigital.org
    SSLEngine on
    SSLCertificateFile "/usr/local/etc/pki/tls/pbdigital.org/certs/pbdigital.org.crt"
    SSLCertificateKeyFile "/usr/local/etc/pki/tls/pbdigital.org/private/pbdigital.org.key"

    DocumentRoot "/usr/local/www/apache24/data"
    <Directory "/usr/local/www/apache24/data">
        Options FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>
</VirtualHost>

Beefing Up Security with Cipher Suites

Below I have added SSLCipherSuite options to further secure SSL connections. I have chosen the ciphersuites from recommendations at Apache SSL/TLS Strong Encryption How To. I have removed ECDHE-RSA-CHACHA20-POLY1305 as it is not HIPAA or NIST compliant.

Includes/pbdigital.org.conf

<VirtualHost *:80>
    ServerName www.pbdigital.org
</VirtualHost>

<VirtualHost *:443>
    ServerName www.pbdigital.org
    SSLEngine on
    SSLCertificateFile "/usr/local/etc/pki/tls/pbdigital.org/certs/pbdigital.org.crt"
    SSLCertificateKeyFile "/usr/local/etc/pki/tls/pbdigital.org/private/pbdigital.org.key"
    SSLHonorCipherOrder On
    SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite      ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SH
A256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256

    DocumentRoot "/usr/local/www/apache24/data"
    <Directory "/usr/local/www/apache24/data">
        Options FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>
</VirtualHost>

Adding OSCP Stapling

The Online Certificate Status Protocol (OCSP) stapling, formally known as the TLS Certificate Status Request extension, is a standard for checking the revocation status of X.509 digital certificates. It allows the presenter of a certificate to bear the resource cost involved in providing Online Certificate Status Protocol (OCSP) responses by appending (“stapling”) a time-stamped OCSP response signed by the CA to the initial TLS handshake, eliminating the need for clients to contact the CA, with the aim of improving both security and performance.

When Let’s encrypt issues certificates, they supply the obvious public cert and private key for for SSL configuration. The also provide chain.pem which is the CA Certificate, this will be used for OSCP Stapling. Of note, Let’s Encrypt also provides fullchain.pem which is a concatenation of the CA Certificate and the Public Cert.

Add the following lines to your conf files.

Includes/ssl.conf

SSLStaplingCache shmcb:/tmp/stapling_cache(128000)

Includes/pbdigital.org.conf

SSLUseStapling on
SSLCACertificateFile "/usr/local/etc/pki/tls/pbdigital.org/certs/letsencrypt-chain.pem"

Header Strict Transport Security

HTTP Strict Transport Security (HSTS) is a web security policy mechanism that helps to protect websites against protocol downgrade attacks and cookie hijacking. It allows web servers to declare that web browsers should interact with it using only HTTPS connections, which provide Transport Layer Security, unlike the insecure HTTP protocol used alone. HSTS is an IETF standards track protocol and is specified in RFC 6797

To implement HSTS, add the following lines to your configuration files.

httpd.conf

LoadModule headers_module modules/mod_headers.so

Includes/pbdigital.org.conf

Header always set Strict-Transport-Security "max-age=63072000; includeSubdomainsi; preload"

IMPORTANT!

You also need to redirect any requests to port 80 to the secure port 443. First you need to enable the rewrite module in httpd.conf. You should make sure the following line is uncommented.

httpd.conf

LoadModule rewrite_module libexec/apache24/mod_rewrite.so

and now add the rewrite rules to your host on port 80.

Includes/pbdigital.org.conf

<VirtualHost *:80>
    ServerName www.pbdigital.org
    <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteCond %{HTTPS} off
      RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
    </IfModule>
</VirtualHost>

HSTS Preloading

Finally, you will want to submit your domain for inclusion in Chrome’s HTTP Strict Transport Security (HSTS) preload list. This is a list of sites that are hardcoded into Chrome as being HTTPS only.

Most major browsers (Chrome, Firefox, Opera, Safari, IE 11 and Edge) also have HSTS preload lists based on the Chrome list.

You can submit your domain at hstspreload.org.

Forward Secrecy Ciphers

In cryptography, forward secrecy (FS), also known as perfect forward secrecy (PFS), is a feature of specific key agreement protocols that gives assurances that session keys will not be compromised even if the private key of the server is compromised.[1] Forward secrecy protects past sessions against future compromises of secret keys. By generating a unique session key for every session a user initiates, the compromise of a single session key will not affect any data other than that exchanged in the specific session protected by that particular key. Forward secrecy further protects data on the transport layer of a network that uses common SSL/TLS protocols, including OpenSSL,[2] which had previously been affected by the Heartbleed security bug. If forward secrecy is used, encrypted communications and sessions recorded in the past cannot be retrieved and decrypted should long-term secret keys or passwords be compromised in the future, even if the adversary actively interfered, for example via a man-in-the-middle attack.

To implement Forward Secrecy we first need to generate Diffie-Helman Parameters.

# openssl dhparam -out /usr/local/etc/pki/tls/pbdigital.org/certs/dhparam.pem 4096

Then add the following line to the host.conf.

Includes/pbdigital.org.conf

    SSLOpenSSLConfCmd DHParameters "/usr/local/etc/pki/tls/pbdigital.org/certs/dhparam.pem"

Header Security

In recent years, HTTP Headers have been introduced to enhance the security of a website. I look at setting some of the features here.

  • First is the Content-Security-Policy, which set headers to restrict what content that pages can load. We set this to use default-src & trust only local content via self. You may have different needs for your website and must change this accordingly.

  • Second is Expect-CT, which concerns Certificate Transparency. We set to enforce Certificate Transparency and how long the browser should cache the data. More information on Certificate Transparency Policy can be found here.

To implement these changes, add the following to your headers.conf file.

Includes/header.conf

Header set Content-Security-Policy "default-src 'self';"
Header set Expect-CT: "max-age=86400, enforce"

That’s it for the configuration of Apache!

Wrapping Up

After restarting Apache, let’s have a look at the report that is generated from https://www.immuniweb.com/ssl/.

SSL Report

For the sake of completeness below in there entirity I have listed the config files.

Includes/ssl.conf

LoadModule ssl_module libexec/apache24/mod_ssl.so

Listen 443

SSLStaplingCache shmcb:/tmp/stapling_cache(128000)

Includes/pbdigital.org.conf

<VirtualHost *:80>
    ServerName www.pbdigital.org
    <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteCond %{HTTPS} off
      RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
    </IfModule>
</VirtualHost>

<VirtualHost *:443>
    ServerName www.pbdigital.org
    SSLEngine on
    SSLCertificateFile "/usr/local/etc/pki/tls/pbdigital.org/certs/pbdigital.org.crt"
    SSLCertificateKeyFile "/usr/local/etc/pki/tls/pbdigital.org/private/pbdigital.org.key"
    SSLHonorCipherOrder On
    SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite      ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SH
A256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256

    SSLUseStapling on
    SSLCACertificateFile "/usr/local/etc/pki/tls/pbdigital.org/certs/letsencrypt-chain.pem"

    Header always set Strict-Transport-Security "max-age=63072000; includeSubdomainsi; preload"

    SSLOpenSSLConfCmd DHParameters "/usr/local/etc/pki/tls/pbdigital.org/certs/dhparam.pem"

    DocumentRoot "/usr/local/www/apache24/data"
    <Directory "/usr/local/www/apache24/data">
        Options FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>
</VirtualHost>

and the additions I have made to the main config file

httpd.conf

LoadModule rewrite_module libexec/apache24/mod_rewrite.so
LoadModule headers_module modules/mod_headers.so

Includes/header.conf

Header set Content-Security-Policy "default-src 'self';"
Header set Expect-CT: "max-age=86400, enforce"