Creating A Dynamic DNS Script With Slicehost

Note: The script used here is written in Python. I did not write this script. However, in the time honored tradition of the Internet I am going to reiterate it here, as it was a little hard to find a solution via Google. The original script came from a Slicehost forum poster. I just want to make clear that I am not the author, just a fan of his work.

In all of my new server craze, I’ve come to have a need to be able to connect to it from where ever I am. Initially I thought that the best solution for this was to just use the DynDNS.com free service. It does exactly what I need with three exceptions.

  1. I have to use one of their canned domain names.
  2. After 1 month of inactivity, they will cancel your account.
  3. My current AirPort Extreme router does not support dyndns.com updating like my old LinkSys one did.

Now, most of these are either easily overcome or downright nit-picky. #2 and #3 could be easily overcome with a script that updates the IP address periodically. However if I’m going to need a script for this, I might as well go to the next step and use a solution that let’s me take care of #1 as well. Enter SliceHost.

I’ve been a very happy customer of SliceHost for a little over two years at this point. I started with a Gentoo slice and am currently rocking a Ubuntu install, simply so there is a little more fire and forget happening. I recently started using their wonderful DNS management system to add a post.drewbutler.name to point over at the Posterous servers. So I figured why not do the same thing but point it at my home server.

Setting Up A Type A Record On A Zone

In network terminology, your DNS is split into zones and records. The zone is the main domain name itself (drewbutler.name.) and the record is essentially the sub-domain (home). Now, I am going to say that this is an extreme simplification, however for our purposes, it is relatively accurate. For more in-depth information, please see the Wikipedia article related to DNS, zones and records.

I will assume for this exercise that you have your domain (zone) already set up and that we are simply adding a new sub-domain (record) to it. In the SliceManager, go to DNS -> Domains and click the Records link next to your domain. Once you’re in the records list for your zone, click on the New Record link. We’re going to set things similar to the image below, though substitute the Name field with your sub-domain and the data with your home IP address. You can use the dyndns checkip service to easily get your current ip address.

SliceManager Add New DNS Record

Hit update and you should be able to go to home.yourdomain.com and see your own server (assuming you have a web server set up). Otherwise, if you have a terminal available, run: “ping -c 1 home.yourdomain.com” and you should see your home ip address appear in parenthesis.

While we’re in the DNS records, you should see your new subdomain “home” listed. Hover over the edit link and copy the url there. It should be something like this:

1
https://manage.slicehost.com/zones/1234/records/123456/edit

The first number is your zone id and the second is the record id. Write down the record id (in this example, 123456) as we’ll need that in a little bit.

Using the SliceHost API to do some periodic updates for us.

First if you haven’t done so, let’s enable the API and/or get the API key. Go to the Account -> API Access in your SliceManager and click Enable API Access (if applicable). Now you should see you API password displayed. Copy and paste it into a document, write it down or whatever; we’ll need this in a bit as well.

For this next bit I am going to assume you are running some sort of *nix server and have 2 things installed, Python and Subversion. If you do not have them installed, please do so now. Both are very common packages and the installation should be very well documented for your distribution of Linux.

The script makes use of a great package called PyActiveResource. This is essentially a port of the ActiveResource module for Ruby, but in Python. At this moment, it seems the best way to get this package installed is via subversion, so let’s do that.

1
2
3
svn checkout http://pyactiveresource.googlecode.com/svn/trunk/ pyactiveresource-read-only
cd pyactiveresource-read-only
sudo python setup.py install

Assuming there were no errors, this should be installed as a python module now.

Next let’s setup a script to run. I’m gonna assume you are running Vim like I am, but please feel free to substitute that as appropriate.

1
sudo vim /home/drew/slicehost_dyndns.py

/home/drew/slicehost_dyndns.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import urllib, re, sys, os
from pyactiveresource.activeresource import ActiveResource

api_key = 'xxxxxx'
api_url = 'https://%s@api.slicehost.com/' % api_key
record_id = '123456'

class Record(ActiveResource):
  _site = api_url

results = Record.find(id=record_id)
if len(results) != 1:
  print "Can't find Record %s via SliceHost API." % record_id
  sys.exit(1)

salon = results[0]
found_ip = (re.findall('[0-9.]+', urllib.urlopen('http://checkip.dyndns.org/').read())[-1])
if salon.data != found_ip:
  salon.data = found_ip
  salon.save()
  print "IP Updated: " + found_ip
else:
  print "IP Unchanged: " + salon.data

Update the api_key and record_id with the information we wrote down before and save it. Be sure to maintain the spacing on lines as best as possible. Python is very strict about the use of white-space. The script from the forum post was actually not spaced properly and therefore didn’t run. That is really the only change I made. Otherwise it worked perfectly.

From the command prompt, you should now be able to run

1
sudo /home/drew/slicehost_dyndns.py

And will see either IP Updated or IP Unchanged. I suggest testing it at least once before moving forward.

1
crontab -e

Add this to have the script run every 10-minutes. As the script only does an actual update if the ip-address changes, it is fairly innocuous.

1
*/10 * * * * python /home/drew/slicehost_dyndns.py

You now have a working dynamic dns setup for your home server. I’ll be working on some updates to the script to do things like log when it actually changes the dns entry. I figure it’ll be helpful to monitor who often the script really needs to run and if there are any patterns in when the IP address expires. Might help in customizing the cron’s timing and thus decreasing load on the Slicehost servers. As it stands now though, this should be a very low impact solution, so I doubt they’ll notice.

Related Posts

  • Twitter
  • del.icio.us
  • Digg
  • Facebook
  • DZone
  • Reddit
  • FriendFeed
  • StumbleUpon
  • Slashdot
  • BlinkList
  • LinkedIn
  • RSS

Leave a Reply

What is this blog ?

My name is Drew and I am a self-professed geek and technology enthusiast. My day job involves me building web sites and maintaining frameworks. My dream is to perhaps write a novel (or ten) one day.

Search

© 2010 Abstracted Method | Powered by WordPress