New User? Register here - Existing Users: Username: Password: [Advanced Login]

 

 

Current Poll

Your preferred Interactive shell?









( 1026 votes ~ 11 comments )

 

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

Share/Save/Bookmark


Posted by Anonymous (80.101.xx.xx) on Thu 31 Dec 2009 at 14:18
Nice hack,

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 ]

Posted by Anonymous (83.119.xx.xx) on Sat 2 Jan 2010 at 19:03
Well anonymous, I really like to know your setup as I'm also a mysql-powerdns user.

[ Parent | Reply to this comment ]

Posted by Anonymous (71.41.xx.xx) on Mon 25 Jan 2010 at 20:06
How about defaulting the IP address to $ENV{REMOTE_ADDR} if it's not specified? Most times it's the router itself that's hitting the CGI, right? So it's the remote host of the CGI.

[ Parent | Reply to this comment ]

Posted by Anonymous (2001:0xx:0xx:0xxx:0xxx:0xxx:xx) on Sat 1 Jan 2011 at 23:56
How can I start a update with nsupdate, what is the right syntax to use?

[ Parent | Reply to this comment ]

 

 

Flattr