If you are running a ADSL network, your external IP can change at times.

To keep track of this, you can setup a Dynamic DNS Server so that your external IP can be updated to your A-Record as soon as it changes.

We will be using:

  • BIND (Server Side)
  • Nsupdate and Cron (Client Side)

The BIND server will be residing outside the ADSL network

Server Side:

Installing Packages:

$ yum install bind bind-utils -y

Generate Private Keys:

$ mkdir -p /opt/ddns
$ cd /opt/ddns
$ dnssec-keygen -a HMAC-MD5 -b 512 -n HOST ddns.example.com.key

This will generate 2 files, which will be your private keys, keep this in a safe place. This will also withold the content that you need to configure for your secret phrase.

It will look like the following:

$ cat Kddns.example.com.key.+157+55575.key
ddns.example.com.key. IN KEY 512 3 157 WkTF9DYyK4hcboNK1cxHTK/WcFu7di/sdHkwrFJqKBJU YA+08otWNW31g==

Update your /etc/named.conf:

key "ddns.key" {
  algorithm hmac-md5;
  secret "WkTF9DYyK4hcboNK1cxHTK/WcFu7di/sdHkwrFJqKBJU YA+08otWNW31g==";
};

zone "ddns.example.com" {
  type master;
  file "example.com.zone";
  allow-query { any; };
  allow-transfer { none; };
  allow-update { key ddns.key; };
};

Update your /var/named/example.com.zone:

$ORIGIN .
$TTL 86400      ; 1 day
ddns.example.com IN SOA localhost. root.localhost. (
                                127        ; serial
                                3600       ; refresh (1 hour)
                                900        ; retry (15 minutes)
                                604800     ; expire (1 week)
                                86400      ; minimum (1 day)
                                )
                        NS      ns1.example.com.
$TTL 60 ; 1 minute
                        A       123.10.11.12

Start BIND:

$ /etc/init.d/named restart
$ chkconfig named on

Client Side:

Install Packages:

The script (client) will reference nsupdate which we need to install

$ yum install bind-utils -y

The Client Script:

$ mkdir /opt/scripts
$ vi /opt/script/ddns-update.sh

#!/bin/bash
# This script fetches the current external IP Address, writes out an nsupdate file
# Then performs an nsupdate to our remote server of choice
# This script should be placed on a 10 minute crontab

WGET=$(which wget)
ECHO=$(which echo)
NSUPDATE=$(which nsupdate)

IP=$($WGET -q -O - checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//')

$ECHO "server ns1.example.com" > /tmp/nsupdate
$ECHO "debug yes" >> /tmp/nsupdate
$ECHO "zone ddns.example.com." >> /tmp/nsupdate
$ECHO "update delete ddns.example.com" >> /tmp/nsupdate
$ECHO "update add ddns.example.com 60 A $IP" >> /tmp/nsupdate
$ECHO "send" >> /tmp/nsupdate

$NSUPDATE -k /etc/Kddns.example.com.key.+157+55575.key -v /tmp/nsupdate 2>&1

Change permissions:

$ chmod +x /opt/script/ddns-update.sh

Add to your Crontab:

*/10 * * * * /opt/script/ddns-update.sh  > /dev/null 2>&1

Once your script has executed, you can test it by doing a DIG to your A record that you have specified:

$ dig A ddns.example.com @ns1.example.com +short
123.11.12.13

Sources:

kirya.net