Creating Bind DNS-Entries with regular dyndns-clients in routers

Today came a message on debian-user-german up if there is a way to create BIND-compliant DNS-Updates with regulars dyndns-clients from routers. The Idea behind this is to get rid of dyndns.org services and provide an independend way to maintain dynamic dns entries for boxes without a static ip-address without the need of dyndns providers. The goal was to create a text file which could be used as input for nsupdate with cron to run it frequently.

As this was a quick and dirty hack, ideas to improve the current setup are greatly appreciated.

Server side requirements:

Working Bind setup
Apache with cgi capabilites
perl
nsupdate

Router-requirments:

The router must be able to let the user specify a special update-url for dyndns-updates. In my case i used a FRITZ!Box Fon WLAN 7113

Specify the following URL as an UPDATE-Url in your routers dyndns-setup:

http://hostname.tld/cgi-bin/dns.cgi?user=<username>&pass=<pass>&hostname=<domain>&myip=<ipaddr>

Most routers provide fields to specify username and password as well as the domain. On my fritzbox the variables (marked in <variable>) get replaced at runtime.

username is stefan in this example
pass = geheim
hostname = dyndnstest.plzk.de
ipaddr get replaced by the current ip-address of the routers wan-interface

On the serverside, use the following perl snippet in your cgi-bin directory and call it dns.cgi:

#!/usr/bin/perl -w

# if the router sends a correct update string
if ($ENV{QUERY_STRING} =~ /username=(.*?)&pass=(.*?)hostname=(.*?)&myip=(.*)/) {

# and the supplied username & password is correct as well
if ($1 eq ’stefan‘ and $2 eq ‚geheim) {

# then confirm the update with an OK (good)
print print $3 IN A $4 good“;

# add a nsupdate-compliant line to a temporary file
# can be used afterwards with nsupdate /tmp/zonetest
# this can be done automatically by a cronjob

`/bin/echo „update add $3 600 IN A $4“ &gt; /tmp/zonetest`;
}
}
else
{

# if something went wrong, reply with a temporary error (911)
print „a problem occured – 911“;

If we setup everything correctly, the client sends the following string to the webserver

91.8.21.139 – – [29/Dec/2009:19:45:08 +0100] „GET /cgi-bin/dns.cgi?user=stefan&pass=geheim&hostname=dyndnstest.plzk.de&myip=91.8.21.139 HTTP/1.1“ 200 23 „-“ „Fritz!Box DDNS“

Right after that, we have a new entry in /tmp/zonetest

# more /tmp/zonetest
update add dyndnstest.plzk.de 600 IN A 91.8.21.139

which could be now used with nsupdate to update the zone-informations for the domain *.plzk.de