Securing web traffic with HTTPS
HTTP is a non-secure protocol commonly used to communicate over the Web. The traffic is transferred in plain text form and can be captured and interpreted by a third-party attacker. Transport Layer Security and Secure Socket Layer protocols (TLS/SSL) can be used to secure the traffic between client and server. These protocols encapsulate normal traffic in an encrypted and secure wrapper. It also validates the identity of the client and server with SSL keys, certificates, and certification authorities.
When HTTP is combined with TLS or SSL, it is abbreviated as HTTPS or HTTP secure. Port 443
is used as a standard port for secured HTTP communication. Nearly all leading web servers provide inbuilt support for enabling HTTPS. Apache has a module called mod_ssl
that enables the use of HTTPS.
To set up your servers with SSL/TLS encrypted traffic, you will need an SSL certificate and a key pair that can be used to encrypt traffic. Generally, the certificate and keys are obtained from a trusted signing authority. They charge you some fees to verify your ownership of the web property and allocate the required signed certificates. You can also generate self-signed certificates for internal use. Few certification authorities provide a free SSL certificate. Recently, Mozilla has started a free and automated certificate authority named Let's Encrypt. At the time of writing, the service is in public beta and has started allocating certificates. Let's Encrypt offers a client that can be used to obtain certificates and set up automated renewal. You can also find various unofficial clients for Apache and Nginx servers.
In this recipe, we will learn how to create our own self-signed certificate and set up the Apache server to serve contents over a secure channel.
Getting ready
You will need access to a root account or an account with sudo
privileges. I assume that you have the Apache server preinstalled. You will also need OpenSSL installed.
Make sure your firewall, if any, allows traffic on port 443
. Check Chapter 2, Networking, Securing network with uncomplicated firewall recipe for more details on Uncomplicated Firewall.
How to do it…
Follow these steps to secure web traffic with HTTPS:
- First, we will start by creating a self-signed SSL certificate. Create a directory under
/etc/apache2
to hold the certificate and key:$ sudo mkdir /etc/apache2/ssl
- Change to the new directory and enter the following command to create a certificate and SSL key:
$ cd /etc/apache2/ssl $ sudo openssl req -x509 -nodes -days 365 \ -newkey rsa:2048 -keyout ssl.key -out ssl.crt
- This will prompt you to enter some information about your company and website. Enter the respective details and press Enter for each prompt:
- After you are done with it, you can check the generated certificate and key:
$ ls -l
- Next, we need to configure Apache to use SSL. We will enable SSL for the previously created virtual host.
- Open the Virtual Host configuration file,
example.com.conf
. After removing comments, it should look similar to the following: - Now, copy the entire
<VirtualHost *:80> ... </VirtualHost>
tag and paste it at the end of the file. - Under the newly copied contents, change the port from
80
to443
. - Add the following lines below the
DocumentRoot
line. This will enable SSL and specify the path to the certificate and key:SSLEngine on SSLCertificateFile /etc/apache2/ssl/ssl.crt SSLCertificateKeyFile /etc/apache2/ssl/ssl.key
- The final file should look something like this:
- Save the changes, exit
example.com.conf
, and enable themod_ssl
module on the Apache server:$ sudo a2enmod ssl
- Next, enable the Virtual Host
example.com
. If it's already enabled, it will return a message sayingsite example.com already enabled
:$ sudo a2ensite example.com.conf
- Reload the Apache server for the changes to take effect:
$ sudo service apache2 reload
- Now, open your browser on the client system and point it to your domain name or IP address with HTTPS at the start:
https://example.com
- Your browser may return an error saying Invalid Certification Authority. This is fine as we are using a self-signed certificate. Click Advanced and then click Proceed to example.com to open a specified page:
- Once the page is loaded completely, find the padlock icon in the upper right corner of the browser and click on it. The second section with the green lock icon will display the encryption status. Now your communication with the server is encrypted and secure:
How it works…
We have created a self-signed certificate to secure an HTTP communication. The key will be used to encrypt all communication with clients. Another thing to note is that we have defined a separate Virtual Host entry on port 443
. This Virtual Host will be used for all requests that are received over port 443
. At the same time, we have allowed non-secured HTTP communication for the same Virtual Host. To disable non-secure communication on port 80
, you can simply comment out the original Virtual Host configuration. Alternatively, you can separate both configurations into two files and enable or disable with the a2ensite
and a2dissite
commands.
Some of the parameters used for generating a key and certificate are as follows:
- nodes
specifies that we do not want to use a passphrase for a key.- days
this specifies the number of days the certificate is valid for. Our certificate is valid for 365 days, that is, a year.- newkey rsa:2048
this option is used to generate a certificate along with a private key.rsa:2048
specifies the 2048 bit long RSA private key.
I have modified the existing Virtual Host entry to demonstrate the minimal configuration required to enable secure HTTP communication. You can always use the default secure Virtual Host configuration available under sites-available/default-ssl.conf
. This file provides some additional parameters with respective comments.
The certificate created in this recipe will not be trusted over the Internet but can be used for securing local or internal communication. For production use, it is advisable to get a certificate signed from an external, well known certification authority. This will avoid the initial errors in browsers.
There's more…
To get a signed certificate from an external certification authority, you will need a CSR document.
The following are the steps to generate a CSR:
- Generate a key for the CSR:
$ openssl genrsa -des3 -out server.key 2048
- You will be asked to enter a passphrase for the key and then verify it. They will be generated with name
server.key
. - Now, remove the passphrase from the key. We don't want to enter a passphrase each time a key is used:
$ openssl rsa -in server.key -out server.key.insecure $ mv server.key server.key.secure $ mv server.key.insecure server.key
- Next, create the CSR with the following command:
$ openssl req -new -key server.key -out server.csr
- A CSR file is created with the name
server.csr
, and now you can submit this CSR for signing purposes.
See also
- Refer to the Installing and configuring the Apache web server recipe for the installation and configuration of the Apache web server.
- Check out the certificates and security in the Ubuntu server guide at https://help.ubuntu.com/lts/serverguide/certificates-and-security.html
- How to set up client verification at http://askubuntu.com/questions/511149/how-to-setup-ssl-https-for-your-site-on-ubuntu-linux-two-way-ssl
- Apache documentation on SSL configuration at http://httpd.apache.org/docs/2.4/ssl/ssl_howto.html
- Free SSL certificate with Mozilla Let's Encrypt at https://letsencrypt.org/getting-started/
- Easily generate SSL configuration for your web server at Mozilla SSL Configuration Generator at https://mozilla.github.io/server-side-tls/ssl-config-generator/