26 August 2015

Who needs dynamic DNS anyway

Dynamic DNS. That wonderful third party service that should really have been provided by your ISP anyway. Who really needs it?

DNS is the system which resolves those lines you type into your browser into an IP address (IPv4 or IPv6). It's simple to spot an IPv4 address - it looks like four numbers (0-255) seperated by full-stops. Of course the allocating authorities eventually ran out of these addresses and so IPv6 was born. There are also ways to reduce the required number by using NAT (Network Address Translation). The idea of NAT is that a company could have one address to link to the internet and behind this gateway they could have an entire network (made possible by some of the ip addresses being unallocated to anyone so they can be used for private internal networks). At least that's my understanding of it anyway. Companies can then have their own 'internal' DNS system so all their corporate machines can communicate together effectively, while anything leaving the corporate private network has to go through the NAT gateway.

ISP's with their money saving measures and beleif that not everyone is constantly using their connection have similar systems. Your home link is unlikely to be a fixed IP address which is the same every time you turn your PC (or other device) on. Instead they are allocated by your ISP's DHCP server. A system which gives you an IP address when your system is turned on. Good for them (as it saves money by allowing them to give your IP address to someone else when you're offline) but not so good if you want to connect to your home server to download that cat picture you forgot to put on your memory stick. And so the ISP's gave birth to a new service - dynamic-DNS. You can get this as a free service from the likes of no-ip.org and for several years I had the basic free equivalent from DynDNS until they started charging for it. The free service usually requires you to re-activate your host registration every month which can be a pain if you don't have an automatic script to do this. Of course these companies would prefer you to pay an annual fee of around $20 and will leave you alone for 10-11 months if you send them money.

The thing is, your ISP has already given you your IP address. You're only paying the other company to help keep track of it when it changes, and you still need to do that from some device on your home network which tells their service what the new address is.

I will now digress slightly and tell you about how some time back I got hold of a Belkin WEMO home automation switch. The privacy professionals (I don't know who they are, they're that good) were a little concerned that these devices dialled home (metaphorically) to report, well we can't exactly be sure. The interesting aspect of this is that the WEMO app is capable of accessing these devices without requiring any dynamic host-name. We may not know what they send out, but it's a fair guess that to function effectively, they need to send back your current home IP address since that's what you would need to send a message to the device from the app on your phone/tablet. It's something that stuck in my mind at the time.

So if you use Belkin WEMO switches, Belkin will sort of very kindly sort out all this dynamic stuff for you, and you have a switch which can turn a device on or off remotely, without an annual fee. The only thing missing is some sort of system which lets you know what your home ip number is when you activate the switch. There are several possibilities here but most people are going to come up with at least two. The first is a device which will email your home IP address to you and there are numerous python scripts out their to do this with a Raspberry Pi. Of course you never know who's peeking at your emails and it's not a good idea to send your home network ip address this way (Twitter and Facebook might also have come to mind to some of you as alternatives to email)

For me, the perfect solution presented itself when I found Python scripts to upload files to dropbox. There's a smaller audit trail (no email logins), automatic encryption of the data (your home IP address), and less management since you don't need to delete old emails. Instead you have an extra folder in your dropbox containing one text file with your IP address. It updates every time you power-up the Pi and you can do that remotely via the WEMO. Ta-dah!!!! no more expiring hostnames or annual fees for dynamic DNS services.

So what magic is needed? Well the WEMO switch of course, and the remote app to go on your phone/tablet. A basic free dropbox account, some extra scripts and some patience as these things are always a bit fiddly to set-up. Start by setting up the Pi with a fresh Raspbian installation (which I won't go into here as there are plenty of tutorials on the net). Next set-up the WEMO using the instructions from Belkin so the Pi is turned on when you use the app on your phone to trigger the WEMO-switch. Now I will refer you to an excellent article for setting up the dropbox script:

Setting up the python dropbox script

Once that's working, you should be able to transfer a file from the Pi to a dropbox folder (which can exist on your other devices). What we need now is a file which gets your home IP address and stores it in a text file. While looking into ways to do this, I found this little gem over at stack-exchange

curl icanhazip.com

Type that into your internet-connected Raspberry Pi in a terminal and it should return your ISP-allocated IP address which is used by your router to connect all your home devices to the internet. As long as your router is properly configured, you should be able to put the resulting ip address into your browsers URL and connect remotely. If your router has good port-forwarding options, you can set-up some ports to be forwarded to devices on your internal network (such as port 22, typically used for SSH - could be forwarded to your Raspberry Pi for example). If you have multiple devices which want to use the same port, you will need to swap one (or more). Usually you can change the default port used and then you just have to set-up forwarding for the duplicate ports. For instance if you have two Pi's and you want the ability to SSH into both, you should set-up SSH on the second Pi to a different port number (23 maybe?) and then forward this port to your internal IP address for the second Pi (192.168.#.# in all probablility where the #'s are the subnet your network uses and the last number is the interal identifier for that device).

Anyway, refer to the router manual or Google if you have issues with port forwarding. Now we go back to the Pi and the scripts needed to upload your IP file to your dropbox app. The first script we create is a bash script and runs the curl command above, sending the output to a text file (publicip.txt).It's a good idea to create a new folder (/home/data) for all this stuff as you need it to run before anyone logs into the Pi (this makes it faster and more secure).

#!/bin/bash curl icanhazip.com > publicip.txt

Save this as /home/data/getip.sh

It's also good to be sure it's somewhere the system can get to it, as it will run before anyone logs in. The second script is the python script which uploads the publicip.txt file to your dropbox account which looks like this:

#!/usr/bin/python from subprocess import call ipfile = "/home/pi/Dropbox-uploader/dropbox_uploader.sh upload /home/data/publicip.txt publicip.txt" call([ipfile], shell=True)
Save this file as /home/data/dropip.py

Now all that is needed is to run these scripts automatically (by adding them to /etc/rc.local which runs at the end of the pi boot process). I had some issues getting this to work initially until I read through this article I found online. In order to get it to work, I had to comment out the parts in rc.local that produced screen output and run the scripts with the additional scripting to get the success result. My rc.local file now looks like below. Notice that in rc.local we also include paths to the script processors (bash and python). This ensures the script can find them as the path variable might not include them prior to logging in.

#!/bin/sh -e /bin/bash /home/data/getip.sh || /bin/true /usr/bin/python /home/data/dropip.py || /bin/true exit 0
Save as /etc/rc.local or combine with the existing rc.local avoiding duplicate lines

Finally, the first time I tried this I discovered it was a good idea to have a monitor and keyboard connected to my Pi and a laptop nearby. I put everything in place, powered up manually and was confronted by the dropbox script asking for the keys and secrets necessary to set-up the dropbox app (as detailed in the Raspi-TV article). Once I did this, it stored the details and now I get a dropbox notification a few seconds after powering up the WEMO to tell me the data file has been updated - so I know it's working. Now wherever I am, I can check my dropbox for my home network IP address and get to whatever I need and all without using any form of dynamic-DNS. As I connect to the IP address I'm also bypassing any local DNS service so I worry less about pharming (where hackers break into DNS services specifically to redirect requests to their own toxic servers). The only thing I need to worry about is my dropbox account being hacked and the data file being replaced, which in the grand scheme of things seems less likely to happen than the alternatives.