DNS
AWS and DDNS
The Problem
Hiding in the small print of AWS' way of doing things is that if your instance is stopped or restarted (note, not rebooted) then your public and private AWS IP addresses will change. This is very boring.
The Solution
nsupdate (with a TSIG key, of course!) and AWS' meta data access.
AWS meta data
AWS let you look up a number of dynamically generated bits of meta data. In our case we want to know the public IP address we have been allocated:
curl -s http://169.254.169.254/latest/meta-data/public-ipv4
There's several other interesting titbits under meta-data and you can access:
curl http://169.254.169.254/latest/user-data
which is set through the AWS console. It might be your nominal hostname, for example.
Example
Let us suppose, for no pertinent reason, that you've discovered that AWS are changing your IP address but your IP address is quite important as you are a public DNS server. Hmm. Add to that the use of some split horizon work for your main domain, example.com.
We need to give our AWS host an A record in example.com otherwise the rest of the DNS (and named) get upset. But empirical study suggests that we can't alter the internal split horizon file.
We'll need to do some tricks.
- We'll set the A record in example.com directly and then we can use aws-host.example.com as a name server.
- We'll also update a new domain, dyn.example.com, with an A record for aws-host
- we'll make a one-off change to our internal split horizon domain such that aws-host.example.com is a CNAME record pointing to aws-host.dyn.example.com.
Hopefully, then, internal hosts will go via the CNAME entry to get the dynamic value set in the placeholder dyn.example.com domain and everyone else will get the regular A record in example.com.
There's a slight hiccup as nsupdate doesn't like operating on two zones in one update.
HOSTNAME=$(uname -n) # or FQDN calculated from meta-data? DOMAIN=${HOSTNAME#*.} HOST=${HOSTNAME%%.*} PUBIP4=$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4) soa=( $(host -t soa ${HOSTNAME#*.}) ) SOA=${soa[4]} KEY= ... nsupdate -k ${KEY} -v <<EOT server ${SOA} zone ${DOMAIN} update delete ${HOSTNAME} A update add ${HOSTNAME} 60 A ${PUBIP4} send EOT nsupdate -k ${KEY} -v <<EOT server ${SOA} zone dyn.${DOMAIN} update delete ${HOST}.dyn.${DOMAIN} A update add ${HOST}.dyn.${DOMAIN} 60 A ${PUBIP4} send EOT
Obviously, we need to run this every time we boot up.
DNS Server
key aws-host.example.com { ... }; zone "example.com" IN { type master; file "example.com.db"; allow-update { key aws-host.example.com.; }; }; zone "dyn.example.com" IN { type master; file "dyn.example.com.db"; allow-update { key aws-host.example.com.; }; };
Document Actions