A recent change in ISP triggered a trade in of the static IP for my home network. Dynamic DNS helps hide this away and continue operations as normal.
Checks
Bind version
The version of named on the server has to correspond to nsupdate on the client. There are a few ways to determine the bind version but the simplest for modern implementations is a simple named -v.
Time
The dynamic update will only work if the clocks are in sync (~5min skew allowed at most). This shouldn’t have to be said, but use ntp.
Any attempt at syncing the clock manually is likely to end in tears. You know that the clock will go out of sync and stop updating the ddns entries at the exact moment you need to get to your machine.
Seed zone
$TTL 10 ; 10 seconds
dyn.example.org IN SOA ns1.example.org. ns2.example.org. (
2010012004 ; serial
10800 ; refresh (3 hours)
3600 ; retry (1 hour)
604800 ; expire (1 week)
10 ; minimum (10 seconds)
)
$TTL 3600 ; 1 hour
NS ns1.example.org.
NS ns2.example.org.
$ORIGIN dyn.example.org.
Where:
dyn.example.orgis the dynamic sub-domain that you wish to keep track of.ns1.example.orgis the primary name server forexample.org(and where this zone file belongs).ns2.example.orgis the secondary name server forexample.org.
This file belongs on the named server. named lives in /etc/namedb on my servers, and I normally place all my dynamic zone files in /etc/namedb/dynamic.
Securing zone updates
Next you want to generate keys for securing the zone updates.
On the named server, create a directory for storing your keys. I use /etc/namedb/keys.
dnssec-keygen
# cd /etc/namedb/keys # dnssec-keygen -b 512 -a HMAC-MD5 -v 2 -n HOST dyn.example.org.
You now have a pair of keys that will be used for the TSIG during the DNS update.
Configuring the zone
The first thing you need is the value of you private key.
# cat /etc/namedb/keys/Kdyn.example.org.+111.+11111.private Private-key-format: v1.2 Algorithm: 157 (HMAC_MD5) Key: [some really long string of characters]
Next, update named.conf to include your seed zone and the private key:
key dyn.example.org. {
algorithm "HMAC-MD5";
secret "[some really long string of characters from your private key]";
};
zone "dyn.example.org" {
type master;
file "dynamic/dyn.example.org";
allow-update {
key syn.example.org;
};
};
Now you can restart bind and test.
# /etc/rc.d/named restartTo test (from named server) :
# dig @localhost dyn.example.org
Dig should give an answer showing the records for the name server and any other static records in the seed zone file.
Wiring it together
client preparation
Create a user:
# pw useradd ddns -s /sbin/nologin -d /home/ddns # mkdir /home/ddns # chown ddns /home/ddns
Copy keys from server, rsync/scp/copy and paste or whetever takes your fancy, but the keys need to end up in the home directory of your ddns user.
# ls -al /home/ddns -r-------- 1 ddns wheel 121 Apr 14 17:38 Kdyn.example.org.+111.+11111.key -r-------- 1 ddns wheel 156 Apr 14 17:39 Kdyn.example.org.+111.+11111.private
set-ddns.sh
Hack together a script to update the zone with the client ip details. There are two parts to the problem, determining your current public ip, and then calling nsupdate to push the details to named. I use an ultra simple script to do this as I run it on my router that owns the public interface.
#!/bin/sh
keyfile='Kdyn.example.org.+111.+11111.private'
nameserver='example.org.'
host='dyn.example.org'
ttl=10
####
# This is how I determine my ip, replace with a tailored solution.
####
ip=`ifconfig tun0 | grep inet | tail -n 1 | cut -c 7- | awk '{print $1}'`
/usr/bin/nsupdate -k $keyfile <<EOF
server $nameserver
update delete $host A
update add $host $ttl A $ip
show
send
EOF
If your client does not own the public interface then you will need to find an alternate mechanism to determine the ip. Normally mining one of the following sources with some combination of curl | grep | cut can be used (in order of the least likely to annoy someone a great deal):
- Most consumer routers have a web interface that can be scraped; or
- Public services like http://www.whatismyip.com/; or
- Sometimes ISPs provide a page that tells you your current ip.
rinse, wash, repeat
Add a crontab entry to execute the set-ddns script. crontab -u ddns -e and add the following entry to kick off the script every minute.
* * * * * /bin/sh /home/ddns/set-ddns.sh
Conclusion
DNS rocks.
Ref
http://www.freebsdwiki.net/index.php/BIND,_dynamic_DNS