learn by doing

Dynamic DNS using your own domain

I have recently changed my ISP and the new one is providing me an IP address through PPPoE that’s changing after every disconnect. Being in this situation I had two options: set up a dynamic DNS client on my router using a dynamic DNS service such as or use my current DNS server and automatically update its zone records. I decided to go for the latter.

The mechanism I will use is pretty simple: a client inside my LAN will periodically initiate an HTTP request to a particular section of this website that is password protected. The web server I am running on is also the authoritative name server of The server will run a script every couple of minutes that checks the source IP address of completed HTTP requests, it will update the zone file records and increment the zone’s serial number.

First, let’s install the required servers: Bind9 DNS server and Apache HTTP server:

aptitude install bind9 apache2

By default Apache’s default DocumentRoot is placed in /var/www. Let’s create a section inside it that is password protected:

root@remote-lab:~# mkdir /var/www/randomstring
root@remote-lab:~# echo "Dynamic DNS" > /var/www/randomstring/index.html
root@remote-lab:~# vim /var/www/randomstring/.htaccess
AuthUserFile /etc/apache2/htpasswd
AuthName "Please Log In"
AuthType Basic
require user admin
root@remote-lab:~# htpasswd -c /etc/apache2/htpasswd admin
New password:
Re-type new password:
Adding password for user admin
root@remote-lab:~# cat /etc/apache2/htpasswd

Now let’s try a test that sends an HTTP request and see if the server returns a 200 OK.

marius@remoteur:~\> curl -s http://admin:[email protected]/randomstring/index.html

Check the apache logs:, - admin [20/Jan/2013:12:21:39 +0200] "GET /randomstring/index.html HTTP/1.1" 200 23 "-" "curl/7.26.0"

Setting up the DNS server. I will use bind9 and show the config files used for domain as example: Create the zone file of your domain:

root@remote-lab:~# vim /etc/bind/
$TTL    120
@   IN  SOA (
            2012121951  ; Serial
            120         ; Refresh
            86400       ; Retry
            2419200     ; Expire
            120 )   ; Negative Cache TTL
@       IN  NS
ns      IN  A
@       IN  A
@       IN  MX  1
@       IN  MX  5
@       IN  MX  5
@       IN  MX  10
@       IN  MX  10
@       IN  MX  10
@       IN  MX  10
@       IN  TXT "v=spf1 ip4: ~all"
mail    IN  CNAME
www     IN  CNAME
virtual IN  A

One thing to notice is that I set the TTL value to 3 minutes so that the changes will be quickly propagated. is the hostname assigned to my lab ip address. Edit the named.conf.local file and add your zone to the config :

root@remote-lab:~# vim /etc/bind/named.conf.local
zone "" {
        type master;
        file "/etc/bind/";
root@remote-lab:~# /etc/init.d/bind9 restart

Restart the server and it should be up and running. You can do a quick test by querying the server for a specific record:

marius@remoteur:~\> dig @
;		IN      	A
;; ANSWER SECTION:	120     	IN      	A
;; AUTHORITY SECTION:  	        120     IN      	NS
;; ADDITIONAL SECTION:	120     	IN      	A

Create a bash script that checks the web server logs, updates the zone records based on the source IP address of the HTTP requests and sends you an email when a change occurs:

IPCLIENT=`grep 'randomstring/index.html HTTP/1.1" 200' /var/log/apache2/access_log | tail -1 | awk '{print $2}'`
SERIAL=`grep Serial /etc/bind/ | sed -e 's/; Serial//'`
IPLAB=`grep virtual /etc/bind/ | awk -F" " '{print $4}'`
if [ "$IPCLIENT" == "$IPLAB" ]
    sed -i "s/$SERIAL/$SERIALNEW/" /etc/bind/
    sed -i "s/$IPLAB/$IPCLIENT/" /etc/bind/
    /etc/init.d/bind9 reload
    echo "The new LAB IP is $IPCLIENT" | mail -s "Your ISP has just changed your assigned IP" -r [email protected] [email protected]


The last thing to do is to add our script to the cron jobs and run every several minutes.

Please let me know if you have any questions or if I missed something in this setup.