remote-lab.net 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 no-ip.com 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 remote-lab.net on is also the authoritative name server of remote-lab.net. 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:

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

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

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

Check the apache logs:

188.26.130.193, 188.26.130.193 - 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 remote-lab.net domain as example: Create the zone file of your domain:

[email protected]:~# vim /etc/bind/db.remote-lab.net
$TTL    120
@   IN  SOA ns.remote-lab.net. marius.remote-lab.net. (
            2012121951  ; Serial
            120         ; Refresh
            86400       ; Retry
            2419200     ; Expire
            120 )   ; Negative Cache TTL
;
@       IN  NS  ns.remote-lab.net.
ns      IN  A   188.240.48.106
@       IN  A   188.240.48.106
@       IN  MX  1 aspmx.l.google.com.
@       IN  MX  5 alt1.aspmx.l.google.com.
@       IN  MX  5 alt2.aspmx.l.google.com.
@       IN  MX  10 aspmx2.googlemail.com.
@       IN  MX  10 aspmx3.googlemail.com.
@       IN  MX  10 aspmx4.googlemail.com.
@       IN  MX  10 aspmx5.googlemail.com.
@       IN  TXT "v=spf1 include:_spf.google.com ip4:188.240.48.106 ~all"
mail    IN  CNAME  ghs.google.com.
www     IN  CNAME  remote-lab.net.
virtual IN  A   188.26.130.193

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

[email protected]:~# vim /etc/bind/named.conf.local
zone "remote-lab.net" {
        type master;
        file "/etc/bind/db.remote-lab.net";
};
[email protected]:~# /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:

[email protected]:~\> dig @188.240.48.106 virtual.remote-lab.net
;; QUESTION SECTION:
;virtual.remote-lab.net.		IN      	A
;; ANSWER SECTION:
virtual.remote-lab.net.	120     	IN      	A       	188.26.130.193
;; AUTHORITY SECTION:
remote-lab.net.  	        120     IN      	NS      	ns.remote-lab.net.
;; ADDITIONAL SECTION:
ns.remote-lab.net.	120     	IN      	A       	188.240.48.106

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:

#!/bin/bash
IPCLIENT=`grep 'randomstring/index.html HTTP/1.1" 200' /var/log/apache2/access_log | tail -1 | awk '{print $2}'`
SERIAL=`grep Serial /etc/bind/db.remote-lab.net | sed -e 's/; Serial//'`
SERIALNEW=$(($SERIAL+1))
IPLAB=`grep virtual /etc/bind/db.remote-lab.net | awk -F" " '{print $4}'`
if [ "$IPCLIENT" == "$IPLAB" ]
then
    :
else
    sed -i "s/$SERIAL/$SERIALNEW/" /etc/bind/db.remote-lab.net
    sed -i "s/$IPLAB/$IPCLIENT/" /etc/bind/db.remote-lab.net
    /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]

fi

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.