24/7/365 Support

Securing web traffic with HTTPS in Ubuntu

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 article 2NetworkingSecuring 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 to 443.

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 the mod_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 saying site 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/

Help Category:

What Our Clients Say