Creating Bind DNS-Entries with regular dyndns-clients in routers
Posted by stefanbauer on Thu 31 Dec 2009 at 10:46
Recently there was a message posted upon the debian-user-german mailing list asking 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 independent 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:
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.
In this example I have the following details:
username is stefan in this example pass = supersecret hostname = dyndnstest.plzk.de
(ipaddr get replaced by the current ip-address of the routers wan-interface)
On the server-side, save the following perl snippet in your cgi-bin directory and call it dns.cgi:
#!/usr/bin/perl -w
# Print a CGI-header.
print "Content-type: text/plain\n\n";
#
# 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 'supersecret')
{
#
# then confirm the update with an OK (good)
#
print "$3 IN A $4 good";
# add a nsupdate-compliant line to a temporary file
# can be used afterward with 'nsupdate /tmp/zonetest'
# this can be done automatically by a cronjob
#
# NOTE: This file needs to be writeable by your webserver
#
`/bin/echo "update add $3 600 IN A $4" > /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=supersecret&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
# cat /tmp/zonetest update add dyndnstest.plzk.de 600 IN A 91.8.21.139
This file could now be used with nsupdate to update the zone-informations for the domain *.plzk.de
Personally I'd use PowerDNS with a MySQL backend to store both user credentials and DNS record information, and PHP on Apache to handle the user's update request.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]