Dynamic DNS with BIND

From Devpit
Jump to: navigation, search

Recently, I was trying to find documentation on how to set up dynamic DNS updates with BIND and nsupdate. Right. Lots of cryptic documentation with no working end-to-end examples. This is really simple, but nobody explains how! If you've seen these errors, you've encountered old or incorrect or really confusing documentation: "dnssec-keygen: a key with algorithm 'HMAC-MD5' cannot be a zone key" "TSIG error with server: tsig indicates error" "could not read key from ... bad key type" (I'm mostly listing these for people who, like myself, tried searching Google for the error messages and found only condescending answers from mailing lists.)

Here's how. First, forget about dnssec-keygen; it doesn't work for this anyway, or if it does, nobody explains it. The only command you need to generate a key is this:

$ dd count=1 < /dev/random | sha256

In named.conf, you need the following, for example:

key "dynamic.example.com" {
        algorithm hmac-md5;
        secret "output from random sha256";
zone "dynamic.example.com" {
        type master;
        allow-update {
                key "dynamic.example.com";
        file "dynamic/dynamic.example.com";

Then create an initial zone file called dynamic/dynamic.example.com. Note the low TTL values for quick updates.

$TTL 5 ; Default TTL
@               IN      SOA     ns1.example.com. me.example.com. (
                                ;       Serial     Refresh Retry Expire Neg-TTL
                                        1          86400   3600  604800 5 )
                IN      NS      ns1.example.com.
                IN      NS      ns2.example.com.

Execute (and edit the username "bind" to suit, obviously):

$ chown bind dynamic dynamic/dynamic.example.com
$ rndc reload

Then, to make changes, use the following command:

$ nsupdate -t 5 -v -y "dynamic.example.com:output from random sha256"
update delete foobar.example.com
update add foobar.example.com 1 A


  • BIND applies the changes in memory and to a journal file, but does not actually flush them to the zone file until you stop the daemon. If you want to make manual changes, you must run "rndc freeze <zone>", make changes, then "rndc unfreeze <zone>". Alternately, you can stop BIND, remove the journal file, make changes, and start BIND again.
  • You probably want to use a separate zone for your dynamic stuff, because all your changes to this zone must go through nsupdate (unless you're prepared to do the troublesome steps above). Otherwise, BIND will probably clobber your changes, send old serial numbers to slaves, and generally make a mess of things. If, in the example, you'd want to use the name foobar.example.com, you can make that a CNAME record pointing to foobar.dynamic.example.com.
  • You may want to run both of your DNSs as independent masters for this zone and make sure your application updates both concurrently. Remember to consider what happens when each DNS is down, and what happens when it comes back up. If you run two independent master DNSs, remember to also specify "server" and "zone" to nsupdate to control which it updates.