You must have Javascript enabled to experience this site.

HTTPS for Ubuntu Apache with Self-Signed Certificates

Posted & filed under Blog, Coding Tips.

As I mentioned in a previous post (HTTPS for XAMPP with Self-Signed Certificates), there is an initiative, lead by Google and Mozilla, to deprecate HTTP and migrate all web traffic to HTTPS.

Having migrated my development environment to HTTPS, I am now working on my private production environment. This is currently hosted on my Ubuntu 16.04 machine.

Create the certificates

The first step is to create the self-signed certificates using the openssl package. There was one additional requirement in this case as I wanted to be able to access this machine by both localhost and the machine name (i5-4660.local). This was achieved by using a configuration file to supply [alt-names] settings.

Start by creating a strong Diffie-Hellman group using:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

This is the script I used to create the certificates:
# create self-signed certificates for local web apps
# special case for default server as both localhost and i5-4660.local required
cat <<EOF | sudo tee /etc/ssl/apache-selfsigned.cfg
[ req ]
req_extensions = req_ext
distinguished_name = req_distinguished_name
prompt = no
localityName=Port Melbourne
organizationName=Paul Shipley
subjectAltName = @alt_names
DNS.1 = i5-4660.local
sudo openssl req -config /etc/ssl/apache-selfsigned.cfg -extensions req_ext -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt
# virtual hosts
sudo openssl req -subj “/C=AU/ST=Victoria/L=Port Melbourne/O=Paul Shipley/OU= /CN=frontaccounting.local” -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/fa-selfsigned.key -out /etc/ssl/certs/fa-selfsigned.crt

Note that in the subj only the /CN=xxxxx part is actually required; the rest is just recorded in the certificate to be displayed if required.

Keep this script as these certificates will expire in 365 days, when you will need to create them again.

Configure Apache

Create a new configuration file for the SSL parameters:
sudo gedit /etc/apache2/conf-available/ssl-params.conf

Insert the following:
# from
# and
SSLProtocol All -SSLv2 -SSLv3
SSLHonorCipherOrder On
Header always set Strict-Transport-Security “max-age=63072000; includeSubdomains”
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
# Requires Apache >= 2.4
SSLCompression off
SSLSessionTickets Off
SSLUseStapling on
SSLStaplingCache “shmcb:logs/stapling-cache(150000)”
SSLOpenSSLConfCmd DHParameters “/etc/ssl/certs/dhparam.pem”

Modify the default SSL virtual host file using:
sudo gedit /etc/apache2/sites-available/default-ssl.conf

Change these lines to use the self-signed certificate created earlier.
SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key

Modify the default unencrypted virtual host to redirect to HTTPS using:
sudo gedit /etc/apache2/sites-available/000-default.conf

Replace all lines with:
<VirtualHost *:80>
Redirect “/” “https://localhost/”

Change the project virtual host site configuration files. In my case this was frontaccounting.conf.
sudo gedit /etc/apache2/sites-available/frontaccounting.conf

My configuration was:
# Front Accounting
<VirtualHost *:80>
ServerName frontaccounting.local
DocumentRoot “/var/www/frontaccounting”
<Directory “/var/www/frontaccounting”>
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Order allow,deny
Allow from all

Change this to:
# Front Accounting
<VirtualHost *:80>
ServerName frontaccounting.local
Redirect “/” “https://frontaccounting.local/”
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName frontaccounting.local
DocumentRoot “/var/www/frontaccounting”
<Directory “/var/www/frontaccounting”>
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Order allow,deny
Allow from all
SSLEngine on
SSLCertificateFile /etc/ssl/certs/fa-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/fa-selfsigned.key

Enable the changes using:
sudo a2enmod ssl
sudo a2enmod headers
sudo a2ensite default-ssl
sudo a2enconf ssl-params

Test these using:
sudo apache2ctl configtest

The output should be:
Syntax OK

Restart Apache and check your sites are now working with HTTPS.
sudo service apache2 restart

The virtual hosts should now work with HTTPS and any references to HTTP will be redirected to HTTPS.