Christian

Kildau

Network Engineer


Welcome to my little blog. I am mostly techie over here, blogging about networking and system administration topics, but there will also be some Travel Reports from time to time…

How to Create your own ‘DynDNS’ Service

February 27, 2011Christian Kildau2 Comments

First off: This is not DynDNS as you might know it from dyndns.org. You can’t use clients like ddclient. I’m using DNSSEC and ‘nsupdate’. You’ll need to be familiar with Bind and some shell scripting… Also I only got this working on *nix and I don’t have any intention to try it on Windows.

Let’s start with what you have to do on your client:

1
$ dnssec-keygen -a HMAC-MD5 -b 512 -n USER -r /dev/urandom host1.dyn.example.org

Now copy Khost1.dyn.example.org.+157+39064.key (your pubkey) to your server’s configdir (in case of Debian: /etc/bind) and define it as follows:

1
2
3
4
5
6
7
8
9
key host1.dyn.example.org. {
        algorithm HMAC-MD5;
        secret "<put key from Khost1.dyn.example.org.+157+39064.private here>";
};
zone "dyn.example.org" {
        type master;
        file "master/dyn.example.org";
        allow-update { key host1.dyn.example.org.; };
};

This allows everyone with the Ktest.unixhosts.org.+157+39064.private key, to update zone ‘dyn.example.org’. Feel free to find out how to do privilege separation on your own Back to your client: Since we can’t use ddclient or similar clients, I wrote my own small script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/sh
dir=$(dirname $0)
old_ip=$(cat $dir/ip_cur.txt)
new_ip=$(ifconfig pppoe0 | grep -E 'inet.[0-9]' | 
       grep -v '127.0.0.1' | awk '{ print $2}')

if [ $old_ip != $new_ip ];
 then
  echo $new_ip >> $dir/ip_log.txt
  echo "server <yourserver>nzone dyn.example.org 
    nupdate delete host1.dyn.example.org. A
    nupdate add host1.dyn.example.org. 60 A $new_ip 
    nsend" > $dir/ip_nsupdate_instructions.txt
  nsupdate -k $dir/Kfhost1.dyn.example.org.+157+25504.private 
    $dir/ip_nsupdate_instructions.txt || exit 1
  echo $new_ip > $dir/ip_cur.txt
fi

My script get’s the current IP Address of pppoe0, compares it to the one from it’s previous run and executes ‘nsupdate’ if they mismatch. ‘nsupdate’ doesn’t accept it’s configuration from stdin, that’s why I needed to hack around with echo… If ‘nsupdate’ fails (due to connection issues or something like that) my script exits. If update was successful it writes the current ip into ip_cur.txt, so the script only executes ‘nsupdate’ on IP Address change and not every time your run it. Add my script to crontab to run it once a minute or so…

1
* * * * * ip_update.sh
This article has 2 comments
  1. Apo
    2011/11/24

    If you’re using pppd, you can just create an executable file in your pppd’s ip-up.d folder (in my case that’s /etc/ppp/ip-up.d), or edit the ip-up script.

    Contents of my /etc/ppp/ip-up.d/60-dyndns:

    #!/bin/sh
    nsupdate -k /etc/nsupdate/named.private << EOF
    server
    zone
    update delete foo.zone. A
    update add foo.zone. 60 A $4
    send
    EOF

    pppd will run the ip-up script every time you get a new IP, so you don’t have to poll your interface every minute.

    There’s also a patch for ddclient to run nsupdate, but that’d mean that you have to disable updates in your package manager, so meh.

    –Apo


Leave a Reply