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:
#!/bin/sh
# 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
[req_distinguished_name]
countryName=AU
stateOrProvinceName=Victoria
localityName=Port Melbourne
organizationName=Paul Shipley
emailAddress=paul@paulshipley.com.au
commonName=localhost
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = i5-4660.local
EOF
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 https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_Apache2.html
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
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/”
</VirtualHost>
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
</Directory>
</VirtualHost>
Change this to:
# Front Accounting
<VirtualHost *:80>
ServerName frontaccounting.local
Redirect “/” “https://frontaccounting.local/”
</VirtualHost>
<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
</Directory>
SSLEngine on
SSLCertificateFile /etc/ssl/certs/fa-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/fa-selfsigned.key
</VirtualHost>
</IfModule>
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:
Output
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.