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:
- Host your domain yourself using the popular nameserver “Bind.”
- 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).
- 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!