Notes on setting up a dynamic dns for home with bind-9.x
Generating Secure DNS Keys
On the home/client machine:
# mkdir /etc/bind/tsig
# cd /etc/bind/tsig
# dnssec-keygen -a HMAC-MD5 -b 128 -n HOST host.domain.tld.
Note the "." after the tld. This generates the public and the private keys.
named.conf
On the remote server:
Edit "/etc/named.conf" and add the generated key to the conf. (Note the trailing dot):
key host.domain.tld. {
algorithm hmac-md5;
secret "qUSfVtkYf7WLxiZaOTN3Ua==";
};
Grant Authority
Still on the remote server:
Edit the "/etc/bind/zone.domain.tld" file, and modify the current allow-update line to include the key.
allow-update { key "default_key."; key "host.domain.tld."; };
This allows full authority to modify any record within the domain (Be Warned).
Restart named and make sure nothing is broken.
nsupdate
Back to the client machine:
Run nsupdate to test that the client can now make updates.
# nsupdate -k /etc/bind/tsig/Khost.domain.tld.*.key
> update delete host.domain.tld A
> update add host.domain.tld. 600 A 1.2.3.4
> send
> quit
It first deletes host.domain.tld if it already exists, then recreates it with the given TTL, type, and IP address. The TTL is the time-to-live, which is a value used by other DNS servers to determine how often they refresh the entry for this host. A smaller values means they'll refresh more often, which is what you want for a dynamic entry. "send" tells nsupdate to send the updates to the server.
Automate
Create a script and put it in a 10 minute cron to check for changes in the wan ip address and run nsupdate automagically.
# cat /etc/cron.d/ddns
SHELL=/bin/sh
*/10 * * * * root /etc/bind/ddns
Below is an example script that gets the info from a Belkin wireless router within the home lan.
#!/bin/bash
# ddns
HOSTNAME="host.domain.tld"
KEYFILE="/etc/bind/tsig/Khost.domain.tld.*.key"
TTL=600
#LOG="/tmp/ddns_log"
LOG="/dev/null"
IP_FILE="/tmp/ddns_ip"
NEW_IP=`wget -q -O - 192.168.2.1 | grep "Up.*dw" | tr "\n" " " | awk -F "'" '{print $12}'`
function do_nsupdate {
echo "New IP address (${NEW_IP}) found. Updating..." >> $LOG
echo $NEW_IP > $IP_FILE
nsupdate -k $KEYFILE >> $LOG << EOF
update delete $HOSTNAME A
update add $HOSTNAME $TTL A $NEW_IP
send
quit
EOF
}
if [ ! -f $IP_FILE ]; then
echo "Creating $IP_FILE..." >> $LOG
do_nsupdate
else
OLD_IP=`cat $IP_FILE`
if [ "$NEW_IP" = "$OLD_IP" ]; then
echo "new and old IPs (${OLD_IP}) are same. Exiting..." >> $LOG
exit 0
else
do_nsupdate
fi
fi
exit 0