Create And Enable SSL On Ubuntu LAMP Server

Introduction

SSL is used to encrypt data between the client e.g a user viewing a website to the web server which hosts the site. SSL uses certificates which are signed and verify the validity of a website. Like any vendor based system the certificate is as secure as the issuer. This means anyone can generate an SSL certificate but only “certified vendors” are considered safe.

Pre-requisites

This post assumes Apache 2 is installed on Ubuntu 10.04 (other versions may apply) with no issues. The default virtual host will be used as the example.

Install SSL

  1. Ensure the SSL mod is installed so Apache can handle SSL requests sudo apt-get install ssl-cert
  2. Enable the SSL module sudo a2enmod ssl
  3. Before restarting the service, edit /etc/apache2/ports.conf and make sure there is a Listen 443 in the file. Alternatively add it in and if the entry is invalid apache won’t start.
  4. Create a directory to store the SSL certificates sudo mkdir /etc/apache2/ssl
  5. Restart apache service sudo service apache2 restart

Generate SSL Certificate

Only run steps in this section if the certificate to be used is not going to be issued by a vendor.

  1. Create the certificate in the Apache SSL directory sudo make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/apache2/ssl/www.dannytsang.com.crt

Once complete go to Configure Apache 2

Applying For SSL

The steps may vary but this is what I had to go through to obtain an SSL certificate:

  1. Install OpenSSL sudo apt-get install openssl
  2. Generate a RSA private key. Enter a password when prompted openssl genrsa -des3 -out www.dannytsang.com.key 2048
  3. Create the CSR openssl req -new -key www.dannytsang.com.key -out www.dannytsang.com.csr Example information:
    • Country Name (2 letter code) [AU]:GB
    • State or Province Name (full name) [Some-State]:Hertfordshire
    • Locality Name (eg, city) []:Stevenage
    • Organization Name (eg, company) [GX Networks Ltd]:Danny Tsang
    • Organizational Unit Name (eg, section) []:
    • Common Name (eg, YOUR name) []:www.dannytsang.com
    • Leave the rest blank
  4. Ensure the CSR details are correct openssl req -noout -text -in www.dannytsang.com.csr If not go through the steps above again to re-generate the CSR
  5. Submit the CSR to the vendor.
  6. The vendor will verify details submitted before issuing the SSL certificate. Once that is complete continue to the next stage.
  7. Depending on the level of the SSL certificate applied there is always at least 2 certificates that have to be included in Apache. One is the Vendor who signs the SSL and the SSL certificate itself.

  8. Copy the vendor certificate to sudo mkdir /etc/apache2/ssl For example sudo vi /etc/apache2/ssl/CaCert.pem Update 13/02/2012: This may also be referred to as an “INTERMEDIATE CA” or Intermediate Certificate Authority” certificate
  9. Copy the site / domain SSL certificate sudo vi /etc/apache2/ssl/www.dannytsang.com.crt Update 13/02/2012: This may also be referred to as the web server certificate

Configure Apache 2

There are various ways to enable HTTPS on a website. The options described below are the ones discussed in this article:

For Login / Accounts only part, WordPress will be used as the example.

For both options there should be 2 virtual hosts configured in Apache. One for non encrypted and the other for encrypted. If the desired effect is for the user to explicitly type https into the browser then only the secure virtual host is need. Otherwise a redirect will be created so that users entering http://www.dannytsang.com will automatically go to https://www.dannytsang.com. The following will assume the virtual host file have already been created and working. The virtual host file will be called dannytsang.

  1. Make a copy of the virtual host which will be used for the SSL part of the site sudo cp /etc/apache2/sites-available/dannytsang /etc/apache2/sites-available/dannytsangssl
  2. Edit the secure virtual host file and make the following changes:
    • Change the port to 443, the default port for HTTPS traffic e.g <VirtualHost *:443>
    • ServerName – Ensure this directive is set to the same as the SSL certificate e.g ServerName www.dannytsang.com
    • SSLEngine – Turn SSL on e.g SSLEngine On
    • SSLCACertificateFile – Path to the vendor or “Certificate Authority” signing certificate. This may be optional and not required if it was not mentioned by the issuer e.g SSLCACertificateFile /etc/apache2/ssl/CaCert.pem
    • SSLCertificateChainFile – Intermediate CA. Same as above e.g SSLCertificateChainFile /etc/apache2/ssl/ICaCert.pem
    • SSLCertificateFile – Path to site SSL e.g SSLCertificateFile /etc/apache2/ssl/www.dannytsang.com.crt
    • SSLCertificateKeyFile – The file path to the private key used to sign the CSR e.g SSLCertificateKeyFile /etc/apache2/ssl/www.dannytsang.com.key
    • Save and exit the file

Example of the secure virtual host configuration file so far:

<VirtualHost *:443>
ServerName www.dannytsang.com

SSLEngine On
SSLCertificateChainFile /etc/apache2/ssl/ICaCert.pem
SSLCertificateFile /etc/apache2/ssl/www.dannytsang.com.crt
SSLCertificateKeyFile /etc/apache2/ssl/www.dannytsang.com.key

DocumentRoot /var/www/dannytsang

</VirtualHost>

Note that my example does not contain SSLCACertificateFile. For a self generated SSL the only SSLCertificateFile is needed.
Update 27/05/2012: For a self signed certificated (a certificate no issued by a CA) then the only 2 lines that need to be added are:

SSLEngine On
SSLCertificateFile /etc/apache2/ssl/www.dannytsang.com.crt

Site Wide HTTPS

One of the pit falls of site wide encryption is that all content must reside on the https domain or from other https sources. Below is an example of what Google’s Chrome browser would show if content didn’t come from a secured resource. In my case it was Ads:

  1. Edit the non secure virtual host file of the site sudo vi /etc/apache2/sites-available/dannytsang
  2. Add the following lines below the SSL related directives:

    <IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{SERVER_PORT} !^443$
    RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
    </IfModule>
  3. Save and exit the virtual host file.
  4. Enable the new secure virtual host sudo a2ensite dannytsangssl
  5. Restart Apache sudo service apache2 restart

Login HTTPS For WordPress

  1. Edit the non secure virtual host file sudo vi /etc/apache2/sites-available/dannytsang
  2. Add the following inside the <Directory /var/www/dannytsang>:

    <Directory /var/www/dannytsang>
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^wp-(admin|login|register)(.*) https://%{SERVER_NAME}/wp-$1$2 [L]
    </IfModule>
    </Directory>

    The RewriteRule is the rule for when it would change the URL to https. In this case it looks for any of the following combinations after the domain wp-admin, wp-login, wp-register e.g www.dannytsang.com/wp-login.php. Multiple rules may be added to match all sorts of sub directories.
  3. Save and exit the virtual host file.
  4. Add the following line to the non secure site so that going from a login / admin page to the normal part of the site e.g logging out and going back to the front page will change it to non https
    vi /etc/apache2/sites-available/dannytsang

    <Directory /var/www/dannytsang>
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule !^wp-(admin|login|register)(.*) - [C]
    RewriteRule ^(.*)$ http://%{SERVER_NAME}/$1 [L]
    </IfModule>
    </Directory>
  5. Save and exit the virtual host file.
  6. Enable mod_rewrite in Apache sudo a2enmod rewrite
  7. Enable the new secure virtual host sudo a2ensite dannytsangssl
  8. Restart Apache sudo service apache2 restart
  9. Edit the WordPress config file (wp-config.php) and add the following line to the bottom of the file define('FORCE_SSL_ADMIN', true);

Debugging Tools & Methods

I found Google Chrome to be the best browser to troubleshoot SSL problems. Chrome is the most promient in showing HTTPS problems (see non secure sources screenshot above). The problem with Chrome was that it was more strict on showing the “padlock” HTTPS icon.

Go to the Console in Chrome (Ctrl+Shift+j > Console tab) lists insure content warnings.

Summary

Whilst going through this setup process myself it has been a long and arduous process (even if it doesn’t look it from this write up). I have learnt:

forumserverapache2SSL

Generate a CSR: Apache (Open SSL)

WordPress Administration Over SSL

apache2 – redirect http to https

Intermediate Certificate Authority (CA) & SSL Installation Instructions for Apache

About Danny

I.T software professional always studying and applying the knowledge gained and one way of doing this is to blog. Danny also has participates in a part time project called Energy@Home [http://code.google.com/p/energyathome/] for monitoring energy usage on a premise. Dedicated to I.T since studying pure Information Technology since the age of 16, Danny Tsang working in the field that he has aimed for since leaving school. View all posts by Danny → This entry was posted in Linux, Web Server, Website, WordPress and tagged , , , , , , , . Bookmark the permalink.

One Response to Create And Enable SSL On Ubuntu LAMP Server

Leave a Reply