Categories
Linux

How to roll your own DynDNS…

I didn’t want to rely upon services like DynDNS.org (which obviously was a smart decision since they now pretty much closed their free service) so I rolled my own…

What you need is the following:

  1. Host your domain yourself using the popular nameserver “Bind.”
  2. Host a small CGI script that will tell you your external IP (or use one of the many free services available that do the same).
  3. Run a machine within your LAN 24×7 which can detect changes of your external IP and update your hostname accordingly.

Step 1: Setup Bind for Dynamic DNS Update

to do

Step 2: CGI Script

The CGI script that needs to be deployed somewhere in the Internet to tell you your external IP is very simple and tiny and looks like this:

#!/bin/bash
echo "Content-type: text/plain"
echo ""
echo "$REMOTE_ADDR"

Step 3: External IP Probe

Here’s the script that needs to run periodically on a machine (I use Ubuntu server) within your LAN (or on your Internet gateway, although if you have the means to run stuff on your gateway you could employ a more elegant, “proper” solution):

#!/bin/bash
lockfile="/run/extip"
lockfile-check $lockfile
if [ $? -eq 0 ]; then
    echo "Locked, bailing out..."
    exit 1
fi

lockfile-create $lockfile
filename="/var/lib/extip.txt"
logfile="/var/log/extip.log"
keyfile="/root/var/lib/dyndns/Kmyhost.dyn.example.org.+163+56719.key"
cur_ip=`curl -s http://example.org/cgi-bin/myip.sh`
prev_ip=`cat $filename`
if [ $cur_ip != $prev_ip ]; then
    echo "`date --rfc-3339=seconds` IP changed, old IP: $prev_ip, new IP: $cur_ip" >>$logfile
    echo "$cur_ip" >$filename
    # Wait 5 sec to complete, force kill if nsupdate not done after 10 sec
    timeout -k 10s 5s nsupdate -k $keyfile -v<<EOF
server example.org
zone dyn.example.org.
update delete myhost.dyn.example.org. A
update add myhost.dyn.example.org. 60 A $cur_ip
send
EOF
fi
lockfile-remove $lockfile

The above script — even though it’s pretty small — is not a quick’n’dirty hack, but even employs some sanity checks:

  • It makes sure that only one instance is running at any time, and
  • it uses the timeout command from the Linux coreutils package to enforce that the nsupdate command will be terminated if it takes longer than 10 s (e. g. due to network issues).

I run the above script once a minute as follows:

# cat /etc/cron.d/extip 
* * * * * root /usr/local/bin/pubextip.sh

That’s it!

Let me know what you think. Suggestions how to improve things are, as always, very welcome!

Categories
Networking Routers

OpenWRT and DNS UPDATE

I’m hosting my domain myself on a dedicated root server, and I wanted my Internet router to automatically update a hostname in my own domain (in a designated dynamic zone) with my current public IP. With OpenWRT this was easily accomplished. I used these instructions as a starting point.

When trying to check whether everything was set up correctly I always got some strange error from the following command:

# ACTION=update INTERFACE=wan /sbin/hotplug-call iface

It turned out that the following statement

config_get ipaddr wan ipaddr

did not return the currently assigned IP address in my case, but just an empty response, so I got the following error message:

could not read rdata
syntax error

(For testing I hooked a spare router with a fresh OpenWRT install with the WAN port into my LAN, and configured the WAN interface to receive its IP address via DHCP from out of the LAN. In “production” the WAN interface receives its IP via PPPoE.)

Some friendly guy in the OpenWRT forum suggested I try the following instead:

. /lib/functions/network.sh
network_get_ipaddr ipaddr wan

And indeed this worked well.