Setting up BIND9 to allow dynamic updates for clients

There are a lot of tutorials out in the netland, but almost all of them are out of date, or didn’t address my use case. I run my own domain (can you guess what it is?), and I wanted to allow a couple of users I have that don’t have static IP addresses to be able to have a resolvable DNS names in my domain, rather than having to use one of the dynamic DNS services.

It turns out it’s a lot easier than it seems when doing searches.

In Ubuntu 20, the dnssec-keygen command that almost every tutorial refers to does not work as all the netland tutorials show. The command was replaced with either tsig-keygen or ddns-confgen. The latter is probably the one you want. It will generate the key, and give you the entries you can copy and paste into your bind configuration.

So an example command that worked for me:

ddns-confgen -a hmac-sha512 -k server1.technomancer.com. -s server1.technomancer.com. 

This will output information in the form:

# To activate this key, place the following in named.conf, and
# in a separate keyfile on the system or systems from which nsupdate
# will be run:
key "server1.technomancer.com." {
	algorithm hmac-sha512;
	secret "kNQk+yA0QbXvbX92n2+Btrx0LWSN7JFmcxTOPLAUon8TQvFakGsGmjd9VqySvXNbNzvrjiucR5zOFeMlSnv8/A==";
};

# Then, in the "zone" statement for the zone containing the
# name "server1.technomancer.com.", place an "update-policy" statement
# like this one, adjusted as needed for your preferred permissions:
update-policy {
	  grant server1.technomancer.com. name server1.technomancer.com. ANY;
};

# After the keyfile has been placed, the following command will
# execute nsupdate using this key:
nsupdate -k <keyfile>

Follow the instructions that it gives you and add the key to your named.conf.local file, and put the update-policy inside the relevant zone block.

Restart/reload bind:

rndc reload 

Then, on the host server1 you can use the nsupdate command to update the record. The script I’m using on server1 is:


#!/bin/bash

# The curl call just returns the IP address it sees me as coming from
# i.e. the public IP

MYIP=$( curl -s https://www.technomancer.com/ip/index.php )

# Query the same server I am updating, to make sure the old value isn't cached

MYDNS=$( host server1.technomancer.com ns.technomancer.com | awk '{ print $4; }' )

# Only send the update request if my IP has changed

if [ "${MYIP}" != "${MYDNS}" ]
then
# Change <yourname> to whatever user you are running the script as.

cat << EOF | nsupdate -k /Users/<yourname>/.dnsupdate.key
server ns.technomancer.com
update delete server1.technomancer.com A
update add server1.technomancer.com 86400 A ${MYIP}
send
EOF

fi

Just put the same key block from the above output into the file /Users/<yourname>/.dnsupdate.key and run the script from a cron job set to run as often as you think necessary.

Leave a Comment