John's Corner

Add SSL to Raspberry Pi

This tip covers how to add SSL to a Raspberry Pi using self signed certificates.

 

 STEP 1 - Install OpenSSL

The first step is to make sure that openssl and a webserver are installed. Apache2 is installed on Raspberry Pi by default and this guide assumes Apache2 is active on the system and serving web pages. Open a terminal session to the Raspberry Pi and update the system software to the latest version.

sudo apt-get update

Now install openssl

sudo apt-get install openssl

 STEP 2 - Generate self signed SSL certificate

Create a new directory to hold the custom self signed certificates:

sudo mkdir -p /etc/ssl/mycerts

Use openssl utility to generate a Self Signed certificate as shown in the example below. More detail can be found in the manual page (man openssl) or at https://www.openssl.org/:

sudo openssl req -new -x509 -days 365 -nodes -out /etc/ssl/mycerts/apache.pem -keyout /etc/ssl/mycerts/apache.key

The process to create a new certificate will ask several questions (i.e.: Location, Organisation, server Fully Qualified Domain Name, etc). This information must overall be unique for this server:

Generating a RSA private key
................................................................................
..................+++++
.........................................+++++
writing new private key to '/etc/ssl/mycerts/apache.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:AU
State or Province Name (full name) [Some-State]:Vic
Locality Name (eg, city) []:Melbourne
Organization Name (eg, company) [Internet Widgits Pty Ltd]:JSim
Organizational Unit Name (eg, section) []:.
Common Name (e.g. server FQDN or YOUR name) []:jsim.ddns.net
Email Address []:jsim@melbpc.org.au

The procedure will generate 2 files, apache.key (the private key) and apache.pem (the actual certificate file). Set the permissions to read/write owner with the following command:

sudo chmod 600 /etc/ssl/mycerts/apache*

 STEP 2 - Alternative using pre-installed certificate

A self-signed certificate and private key are automatically created as part of the Raspberry Pi system installation. These are stored at:

/etc/ssl/certs/ssl-cert-snakeoil.pem and /etc/ssl/private/ssl-cert-snakeoil.key

If needed, the certificate and key make be regenerated manually with the following command:

sudo make-ssl-cert generate-default-snakeoil --force-overwrite

 STEP 3 - Configure Fully Qualified Domain Name

Add the Fully Qualified Domain Name to your hosts file. This will allow access to the website via the FQDN even without an internet connection. Edit the hosts file using vi:

sudo vi /etc/hosts

Add a line to the following line to this file.

[RASPBERRY-IP-ADDRESS] jsim.ddns.net

 STEP 4 - Enable SSL

Enable the SSL module in Apache using the following command:

sudo a2enmod ssl

 STEP 5 - Configure Apache2 to use SSL certificate

This step configures Apache2 to use the private key and Self Signed SSL certificate generated previously by updating the default-ssl.conf file:

sudo vi /etc/apache2/sites-available/default-ssl.conf

Find the SSL section in this file. If necessary comment out the snakeoil certificates and add the lines for the apache certificates. The file should should look something like:

# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on

# A self-signed (snakeoil) certificate can be created by installing
# the ssl-cert package. See
# /usr/share/doc/apache2/README.Debian.gz for more info.
# If both key and certificate are stored in the same file, only the
# SSLCertificateFile directive is needed.
#SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
#SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

SSLCertificateFile /etc/ssl/mycerts/apache.pem
SSLCertificateKeyFile /etc/ssl/mycerts/apache.key

To enable the configuration, issue the following command:

sudo a2ensite default-ssl

This command creates a symlinks within /etc/apache2/sites-enabled folder.

 STEP 6 - Set port on Apache2

It is very important to tell the server to listen on port 443 in the ports.conf file. Go to:

sudo /etc/apache2/ports.conf

Check and if needed, update the file to include the lines below:

Listen 443
Listen 80

 STEP 7 - Restart Apache2

Activate the update configuration by restarting Apache2:

sudo service apache2 restart

 STEP 8 - Enable port 443 on router

This step allows https traffic from the internet through the router to the internal website. Exact details depend on the particular router.

For the TP-Link 1600v router, log in as admin and go to Advanced => NAT Forwarding => Virtual Servers. Check the virtual servers table. If required, add a new server directing TCP traffic on external port 443 to the internal IP of the website. The table should look similar to below.

ID Service Type External Port Internal IP Internal Port Protocol
1 HTTP 80 192.168.1.20 80 TCP
2 HTTPS 443 192.168.1.20 443 TCP

 STEP 9 - Verify Apache2

Verify that Apache2 is secured and uses the SSL certificate. Open a browser and point to the Raspberry PI server, something like https://jsim.ddns.net. Because the certificate is self signed, a security warning will display. Click "Advanced" and then proceed to the site.


Return to Tips and Tricks

John's Corner