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!