Configuring Apache to use TLS 1.2

In this brief blog post, I wanted to run through the steps needed to configure Apache to use SSL and TLS. I will also discuss the importance of configuring the apache cryptosystem correctly, by disabling less preferable protocol versions due to a variety of security concerns (SSL 2.0, SSL 3.0, and TLS 1.0).

(I’m using the term “SSL” to generally refer to secure communications supporting HTTPS in this article, meaning in this case TLS 1.2.)

HTTPS support in Apache is a beneficial feature. By default, however, Ubuntu’s (18.04 LTS bionic) Apache installation will not provide services via port 443, as used by SSL/TLS for HTTPS, so you have to jump through a number of hoops to get it working, which I’ll explain.

Self-signed or CA?

At the outset, the most important decision to make is whether you want to use a self-signed certificate or a certificate from a recognised Certificate Authority. There are lots of advantages to using a recognised CA certificate, not least removing any risk of a MITM and implementing reliable server verification. The primary disadvantage would typically be cost, as a self-signed certificate will be free while the vast majority of CAs will charge (though some CAs, such as Lets Encrypt, offer free public CA alternatives that are supported in many browsers). Alternatively, if you have your own CA or have an interest in running one, you can use that resource to generate the certificate in response to the CSR.

If you do use a self-signed certificate, your users will encounter a browser warning, and they may be asked to add a permanent or temporary exception depending on their browser. Adding exceptions is a security problem, as it reinforces in the minds of users that exceptions are acceptable. Encouraging this behaviour for public sites, for obvious reasons, is not ideal, and would not be a good idea in the current legal and regulatory environment. For these reasons, a self-signed certificate is to be strongly discouraged!

Creating the folder structure

First off, create a folder for the certificate:

# mkdir /etc/apache2/tls
# cd /etc/apache2/tls

Using a CA provisioned certificate

To use a CA provisioned certificate, you’ll need to create a CSR that you’ll submit to the CA. It’s best to follow the process mandated by the CA, but a typical command to generate CSR is as follows:

# openssl req –new --newkey rsa:2048 --nodes --keyout
server.key --out server.csr

You’ll be prompted to enter information as described below. The CSR file will contain the information that would need to be submitted to the CA service, and the private key will be contained in server.key. The private key should only ever be held by the entity that is requesting a certificate, and should never leave that system.

The CA service will provide a certificate file and potentially an intermediate certificate chain file. Follow the instructions from the CA service to configure Apache for both downloaded files.

Using a self-signed certificate

For most purposes using the following command to generate a 2048 bit RSA key will be adequate, following NIST guidelines:

# openssl req -x509 -days 365 -newkey rsa:2048 -nodes -keyout
site01.key -out site01.crt

If you are keen to trade off performance of encryption for potentially better C&I of encryption, then you can use this alternate command to use a 4096 bits. (Be aware that some devices do not support bit lengths greater than 2048.)

# openssl req -x509 -days 365 -newkey rsa:4096 -nodes -keyout
site01.key -out site01.crt

Once your chosen openssl command gets going, you’ll be prompted to enter some information. Always fill in this kind of data correctly and fully, to avoid issues later on. It’s important to specify the Common Name (CN).

Country Name (2 letter code) [AU]: [enter your ISO country
code here, e.g. GB]
State or Province Name (full name) [Some-State]: [enter appropriate value]
Locality Name (eg, city) []: [enter appropriate value]
Organization Name (eg, company) [Internet Widgits Pty Ltd]: [enter appropriate value]
Organizational Unit Name (eg, section) []: [enter appropriate value, e.g. IT Services Department]
Common Name (e.g. server FQDN or YOUR name) []: [very important – enter either the IP address or the host plus domain name. This field must match the addressed used in the client web browser.]
Email Address []: [contact address of the certificate owner. If you don’t have suitable ones, at a minimum use the RFC standard aliases such as postmaster/webmaster etc.]

Configuring Apache

The Apache configuration uses a series of configuration files under “sites-available” and symbolic links under “sites-enabled”. This is a smart setup and avoids duplication and version control issues.

To correctly configure an SSL service, it will need to know about both the certificate and the private key.

Re-using this scheme, we’ll edit as follows:

# pico -$ /etc/apache2/sites-available/default-ssl.conf

Within “<VirtualHost _default_:443>” add the following line:

ServerName <enter FQDN or IP address of the HTTPS
server>

Edit SSLCertificateFile and specify the file we created: /etc/apache2/tls/server01.crt

Edit SSLCertificateKeyFile and specify the file we created: /etc/apache2/tls/server01.key

By extension, the same process would apply for any other VirtualHost configurations that you choose to define in the Apache configuration.

Remember to configure the symbolic link:

# SSLCF="ssl.conf"; cd /etc/apache2/mods-enabled && ln -s ../mods-available/${SSLCF} ${SSLCF}

Hardening the Apache TLS configuration (both self-signed and CA)

Most tutorials stop at the end of the above steps, but there is more to do. We’ve only configured the basis for SSL and TLS operation, but there remains a whole raft of optimisation to do over how ciphering operates.

It’s best practice to configure Apache to use a suitable TLS configuration. Again, Ubuntu uses “available” and “enabled” directories to switch functionality on and off, as we saw earlier.

The SSL hardening directives are contained in “ssl.conf”, located in /etc/apache2/mods-available.

Fortunately by default the symlink exists. But you can double check as follows:

# cd /etc/apache2/mods-enabled ; ln -s ../mods-available/ssl.conf ssl.conf

If the file exists, the mod is enabled (good).

Next, edit the mod file to review the SSL configuration settings:

# pico -$ /etc/apache2/mods-enabled/ssl.conf

By default the Ubuntu configuration omits SSLv2, and disables only SSLv3. You can, depending on your preference and client browsers, further limit this by disabling TLSv1 and TLSv1.1 by updating the line as follows:

SSLProtocol -ALL -TLSv1 -TLSv1.1 -SSLv3 TLSv1.2

It’s recommended to disable TLSv1 in all circumstances, and I’d recommend using TLSv1.2 without TLSv1.1. This is also consistent with recent PCI regulatory guidance (technically 1.1 or above is enough at the time of writing).

But, check for compatibility with your client browsers – this is where good testing matters and is why implementing security optimisations should always take place within change control process.

Note in the previous configuration directive, the negation character means disable.

Set up a redirect (both self-signed and CA)

Finally you can ease adoption of the new HTTPS service by creating a redirect in an existing insecure service on Port 80 to Port 443 by creating a htaccess file:

# pico /var/www/html/.htaccess

And add the following content (update www.example.com to either your IP address or domain name):

RewriteEngine On 
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

Restart

Restart Apache as normal:

# service apache2 restart

Verify the 443 port is being used by an active Apache instance:

# netstat -tanp | grep 443

You should see apache2 listed as LISTEN.

And hopefully, if everything has worked correctly, you should now be able to navigate to the HTTPS version of the site.

One thought on “Configuring Apache to use TLS 1.2”

Comments are closed.