Updating dynamic DNS on Amazon EC2

published Oct 10, 2007

basic idea

There are two steps to updating your dynamic DNS.

  1. Get your IP address
  2. Tell your dynamic DNS provider the IP address

On EC2, things are a little different from your standard hosting setup. Here’s how you get dynamic DNS working on EC2.

Getting your IP address

See this Amazon article about getting data about your instance for more information about instance data.

To make a long story short, to find out the public IP address of your EC2 instance, you make a http get request to

http://169.254.169.254/latest/meta-data/public-ipv4

Note that this has to be done from your EC2 instance.

Try it out from the command line. Log-in to your EC2 instance and type

curl http://169.254.169.254/latest/meta-data/public-ipv4

From Ruby, it’s just as simple. Cut and paste this into a script, or just run it in irb.

require 'open-uri'
ip = open('http://169.254.169.254/latest/meta-data/public-ipv4').read

Updating your DNS with your dynamic DNS provider

The following instructions assume that you want to use ez-ipupdate to update your DNS. If you don’t want to, or if ez-ipupdate doesn’t support your dynamic DNS provider, it should be relatively simple to get it working anyways.

For example, easy-dns (who I use) just requires logging in and then sending a get request formatted like this:

http://members.easydns.com/dyn/dyndns.php?hostname=example.com&myip=10.0.0.2

Installing ez-ipupdate

If you’re running Ubuntu, then install it using sudo aptitude install ez-ipupdate or sudo apt-get install ez-ipupdate. On a RedHat installation sudo yum install ez-ipupdate.

You can also install from source, of course.

When you install it using aptitude or apt-get, it will ask you for some configuration info. This won’t work on EC2, so ignore the configuration and use the script below instead.

Installing the Ruby script

Here’s the script:

#!/usr/bin/env ruby
require 'open-uri'
require 'yaml'

DYNAMIC_DNS_CONFIG_FILE = '/etc/ez-ipupdate/dynamic_dns.yml'
AMAZON_INSTANCE_DATA_ADDRESS = "http://169.254.169.254"
api = "latest"
ip = open(File.join(AMAZON_INSTANCE_DATA_ADDRESS, api, 'meta-data', 'public-ipv4')).read

dns_config = YAML::load(File.open(DYNAMIC_DNS_CONFIG_FILE))
hosts = dns_config['host'].split(',')
hosts.each do |host|
  puts "updating dynamic dns to ip = #{ip} for host #{host} using dynamic DNS service " +
       "#{dns_config['service']}"
  command = "ez-ipupdate --address #{ip} --service-type #{dns_config['service']} " +
            "--user #{dns_config['username']}:#{dns_config['password']} --host #{host}"
  puts command
  system(command)
end

If you’re running an ec2-on-rails instance, place the script in /usr/local/ec2-on-rails/startup-scripts/every-startup/update_dynamic_dns.rb

Otherwise, place it somewhere in your path and create a shell script to call it in /etc/init.d.

Make sure that both update_dynamic_dns.rb and the init script are executable.

The config file

Create a file called /etc/ez-ipupdate/dynamic_dns.yml. It should look something like this

# service should be one of the services supported by ez-ipupdate. 
# Possible values: null  ezip  pgpow  dhs  dyndns  dyndns-static 
#                         dyndns-custom ods tzo easydns easydns-partner 
#                         gnudip justlinux dyns hn zoneedit heipv6tb
# (The above list is from man ez-ipupdate)
service: service_type 
username: username_for_your_dynamic_dns_provider
password: password_for_your_dynamic_dns_provider
host: example1.com,example2.com

To update multiple hosts, put them all on the host entry, separated by commas.

Testing and debugging

Test out the script:

  • run it: ./update_dynamic_dns.rb.
  • Wait a couple of minutes.
  • ping your domain name from a local machine and make sure that it points at the right IP address.

Hopefully that works for you. Let me know if you have any problems, comments or suggestions.

Scott

blog comments powered by Disqus