Sunday, 14 October 2012

A secure home gateway on the Raspberry Pi in four parts. Part three, free HTTPS to the rescue

I have some very nifty devices lying around in my home:
  • A couple of computers
  • A very smart router with the Tomato firmware
  • A Raspberry Pi model B (the only one you can get right now)
  • A Popcorn Hour A200
Besides that, I have full control over a domain name (

The amount of cool things you can do with this is enormous. However, until yesterday morning, these devices were working with most of their default settings (BOOOORING). Here's how I made it awesome in one evening.

Part three, free HTTPS to the rescue

  1. Part one - Dynamic DNS
  2. Part two - nginx on the Raspberry Pi

Objective: You want to wear protection before we take this to the next level

Congratulations to you all, you now have a working http server on the RaspberryPi in your home, accessible from a nice url. Sure, it's not fast, and only serves static pages, but that doesn't matter.

I said earlier that opening up your router's web interface over http to the entire internet was a bad idea. Eavesdroppers are able to see your credentials and do all kinds of nasty stuff to your router. However, having access to your router from the outside would be very useful! And this is just one of the many cool things you want to do that requires authentication and security. We need an encrypted connection.

As many of you will now, StartSSL offers free SSL certificates to natural persons. I happen to be just that. This is absolutely fantastic. I went the the express lane on their site, filled out my info, and selected to create a certificate for I already had a paid SSL certificate for that, but you can select one additional subdomain in the class one certificate that you get for free. For my paid certificate I chose and subdomain

For this new certificate I chose and (I'm not going to use it for, I just want the subdomain here).

Somewhere in the process you can create your own private key for which you need a passphrase. I created a random passphrase and put it in my password safe. Out of the StartSSL express lane, you end up with two files: the certificate (ssl.crt) and the key (ssl.key). You need to download two more: ca.pem and from Move all of these files to a location on the Raspberry Pi. Let's say /usr/local/etc/ssl. Do this:

cd /usr/local/etc/ssl
cat ca.pem ssl.crt > crt.pem
This will create a certificate chain, from the root certificate of StartCOM to their intermediate certificate and then down to our certificate. We'll present this entire chain to the clients, so we conCATenate all these certificates into one large certificate chain file.

Now, in nginx, let's configure the server section (/etc/nginx/sites-enabled/ once more.

server {
listen 80;
rewrite ^(.*) https://$host$1 permanent;
server {
listen 443 ssl;
error_log /var/log/nginx/home.error;
access_log /var/log/nginx/home.access;
ssl on;
ssl_certificate /usr/local/etc/ssl/crt.pem;
ssl_certificate_key /usr/local/etc/ssl/ssl.key;
root /srv/www;
index index.html /index.html;
To everyone connecting on port 80 we say: "No way man. Be secure. Connect on port 443 and you'd better remember it, forever!"

Now when we try to restart the server:
/etc/init.d/nginx restart
we'll get asked for the passphrase because the server needs to access the private key.

You could type it in, but I don't recommend it. We don't want to do this every time we restart the server. So instead we go back to the certificate directory and store a decrypted version of the private key.
cd /usr/local/etc/ssl
mv ssl.key
openssl rsa -in -out ssl.key (Now you enter the passphrase)
/etc/init.d/nginx restart
Try opening the site again! If everything went alright, you will now see a secure version of the index.html file.

Objective three accomplished, we now have a protected connection.

Read on: part four - proxying to your devices