Updating dynamic DNS on Amazon EC2
basic idea
There are two steps to updating your dynamic DNS.
- Get your IP address
- 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.
1 2 |
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:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#!/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
1 2 3 4 5 6 7 8 9 |
# 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
Comments
-
Scott, We recently started working with EC2 and keeping a dynamic DNS in sync was a big question mark for us. This is exactly what we were looking for and it worked perfectly on our first try! Thanks! Jim
-
Jim, Thanks for the comment. It's good to hear that people are using the stuff I post here, especially if it goes well. Scott
-
Scott, I am running an ubuntu system and this worked for me on the first try. This will now allow me to completely get rid of my last windows system. Thanks, Steven
-
Glad to hear that it worked for you, Steven. Scott
-
Hey, I am using EC2 too, but my question is : if I stop my instance and decide to run another one a few hours later, do I have to upload the script again? and configure again? Is there any way to avoid this? Like, for example by saving this on my S3 bucket?
-
Julien: The easiest way to avoid having to configure and upload everything again is to create an AMI (Amazon Machine Image) file once you have everything set up how you like it (see "here":http://docs.amazonwebservices.com/AmazonEC2/dg/2006-06-26/creating-an-ami.html). This will save the state of your machine on S3. When you start up a new machine, use your new AMI and everything should be all set for you.
-
Hum... That's what I thought. You should really try to convince Paul Dowman to integrate your script in his image... I am sure that almost everyuser of ec2onrails will make use of your script sooner of later! Anyway, thanks for the good work!
-
I know, I really do need to do that. Before I do that, though I want to update the script to take advantage of instance data. I want to be able to start up a test instance without it clobbering the DNS of my real instance. -- Scott
