dynamic dns with djbdns

First set up djbdns (debian-flavored!):1

apt-get install dbndns

Create users:

adduser --no-create-home --disabled-login --shell /bin/false dnslog adduser --no-create-home --disabled-login --shell /bin/false tinydns

Make sure tinydns is linked in the right place:

cd /etc/service ; ln -sf /etc/tinydns/

Set up tinydns and check that it's running:

MYIPADDRESS=1.2.3.4 tinydns-conf tinydns dnslog /etc/tinydns/ $MYIPADDRESS svstat /etc/service/tinydns svc -d /etc/service/tinydns svc -u /etc/service/tinydns

Configure tinydns to answer nameserver requests for the subdomain:2

cd /service/tinydns/root ./add-ns dyn.servername.com $MYIPADDRESS

Tinydns will now respond to dns requests on a.ns.dyn.servername.com. Also add the subdomain as a normal host:

./add-host dyn.servername.com $MYIPADDRESS

And finally compile tinydns' data file:

make

Next, the dynamic domain needs to be registered and delegated to the correct IP address. Zone file:

dyn 86400 IN NS a.ns.dyn.servername.com. dyn 86400 IN A MYIPADDRESS a.ns.dyn 86400 IN A MYIPADDRESS

This tells clients to check with a.ns.dyn.servername.com for all requests heading to a subdomain of dyn.servername.com. I'm not sure if the dyn 86400 IN A MYIPADDRESS rule is necessary, since the same subdomain is registered with tinydns. After these changes propagate, tinydns should answer all requests to *.dyn.servername.com.

Next the computer with a dynamic IP address needs a way to update tinydns. As root, create dyn-update.sh in /etc/service/tinydns/root/:

#!/bin/bash cd /etc/service/tinydns/root IP=$1 HOST=$2 sed -i "/${HOST}/d" data echo "Setting ${HOST}.dyn.servername.com to ${IP}" ./add-alias "${HOST}.dyn.servername.com" $IP sed -i "/${HOST}/{s|86400$|300|g}" data make

The script takes two parameters: an IP address and a hostname; it removes lines matching HOST (anywhere on the line, so don't reuse-hostnames!) and sets HOST.dyn.server.name.com to the given IP.

Create a new user as whom the dynamic server can connect:

adduser dyn-update

And give them NOPASSWD sudo rights to the update script:

Cmnd_Alias DYNUPDATE=/etc/service/tinydns/root/dyn-update.sh dyn-update ALL=(ALL) NOPASSWD: DYNUPDATE

As auser On the dynamic machine, create a password-free public key, and put it on the dns host:

ssh-keygen cat .ssh/id_rsa.pub | ssh dyn-update@dyn.servername.com 'cat >> .ssh/authorized_keys'

Finally, as root on the dynamic machine, create dyn-update in /etc/network/if-up.d/:

#!/bin/bash su -c 'ssh dyn-update@dyn.servername.com '\''IP=`echo $SSH_CLIENT | sed "s| .*$||g"`; sudo /etc/service/tinydns/root/dyn-update.sh $IP mydynamichostname'\' auser

This su's to auser and then executes a command as dyn-update on dyn.servername.com. The command fetches the current IP address of the dynamic machine from SSH_CLIENT, then passes this as a parameter to dyn-update.sh along with mydynamichostname, effectively registering mydynamichostname.dyn.servername.com.

AND WE'RE DONE!