Dynamic DNS with Digital Ocean

Sergio Campamá - 20 Dec 2013

Hi! Today we're going to learn how to use Digital Ocean's API to create our own dynamic DNS, maybe for some server you've got at home and want to get to from the office? That's what I do with it!

First of all, the requirements! They're fairly simple: on the server side, we will need ruby, and from Digital Ocean, we will need a subdomain record to be already created and set to an A record type. So go ahead and create one now if you haven't. Also, we're going to be using @scottmotte's digitalocean gem (Github)

  gem install digitalocean -v 0.0.3
After you have the gem installed, create a file named dyndns.rb on your home, and populate it with the following snippet:
  require 'digitalocean'

  CLIENT_ID = "<DigitalOcean ClientId>"
  API_KEY = "<DigitalOcean ApiKey>"

  DOMAIN_ID = <DigitalOcean's Domain Id>
  RECORD_ID = <DigitalOcean Record Id>

  new_ip = `wget -qO- ipecho.net/plain`;

  Digitalocean.client_id = CLIENT_ID
  Digitalocean.api_key = API_KEY

  Digitalocean::Record.edit(DOMAIN_ID, RECORD_ID, {data: new_ip})

Remember to find which ruby you have installed and replace the top line. You can find your ruby with the following command:

  which ruby

Then we make the file executable with:

  chmod +x dyndns.rb

To get the external IP to your network, we use the ipecho.net free service. This is the IP that will be configured in Digital Ocean, as this is the IP to your house's modem.

You can get Digital Ocean's ClientId and ApiKey from this website (be sure to be logged in). The Domain Id is the reference to the domain you have configured in Digital Ocean, like example.com, and the Record Id is the reference to a record of that domain, for example, the A record for home.example.com. To get them, we will be using the following commands from the ruby interpreter IRB. We are assuming that you only have one domain configured in Digital Ocean.

  $ irb
  > require 'digitalocean'
  > Digitalocean.client_id = CLIENT_ID
  > Digitalocean.api_key = API_KEY
  > Digitalocean::Domain.all
  > domain_id = Digitalocean::Domain.all.domains.first.id
  > records = Digitalocean::Record.all(domain_id).records
  > record_id = records.select{|r| r.name == "<subdomain name>"}.last.id
  > puts "Domain Id: #{domain_id} and Record Id: #{record_id}"

With that information, you can now complete the dyndns.rb file with the correct data. Now we're going to configure cron to run the dyndns.rb script to update the DNS every hour.

  #To edit the crontab, use crontab -e

  0 * * * * /home/user/dyndns.rb

That's it! You now have your own dynamic DNS for your home server! You'll probably want to customize this instructions and place the script somewhere else, it's up to you now.

Edit: Changed the gem reference to original one instead of my fork.

comments powered by Disqus