Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm trying to update my DNS-Server dynamically using nsupdate.


I'm using Debian 6 on my DNS-Server and Debian 4 on my client.

I created a public/private key pair using:

dnssec-keygen -C -a HMAC-MD5 -b 512 -n USER sub.example.com.

I then edited my named.conf.local to contain my public key and the new zone i wish to update. It now looks like this (note: I also tried allow-update { any; }; without success):

zone "example.com" {
        type master;
        file "/etc/bind/primary/example.com";
        notify yes;
        allow-update { none; };
        allow-query { any; };

zone "sub.example.com" {
        type master;
        file "/etc/bind/primary/sub.example.com";
        notify yes;
        allow-update { key "sub.example.com."; };
        allow-query { any; };

key sub.example.com. {
        algorithm HMAC-MD5;
        secret "xxxx xxxx";

Next, I copied the private key file (key.private) to another server I want to update the zone from. I also created a textfile (update) on this server which contained the update information (note: I tried toying around with this stuff too. no success):

server example.com
zone sub.example.com
update add sub.example.com. 86400 A

Now I'm trying to update the zone using:

nsupdate -k key.private -v update

The Problem

Said command gives me the following output:

Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id:      0
;; flags: ; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
;sub.example.com.       IN  SOA

sub.example.com.    86400   IN  A

update failed: SERVFAIL

named debug Level 3 gives me the following information when I issue the nsupdate command on the remote server (note: I obfuscated the client IP):

06-Aug-2012 14:51:33.977 client X.X.X.X#33182: new TCP connection
06-Aug-2012 14:51:33.977 client X.X.X.X#33182: replace
06-Aug-2012 14:51:33.978 clientmgr @0x2ada3c7ee760: createclients
06-Aug-2012 14:51:33.978 clientmgr @0x2ada3c7ee760: recycle
06-Aug-2012 14:51:33.978 client @0x2ada475f1120: accept
06-Aug-2012 14:51:33.978 client X.X.X.X#33182: read
06-Aug-2012 14:51:33.978 client X.X.X.X#33182: TCP request
06-Aug-2012 14:51:33.978 client X.X.X.X#33182: request has valid signature
06-Aug-2012 14:51:33.978 client X.X.X.X#33182: recursion not available
06-Aug-2012 14:51:33.978 client X.X.X.X#33182: update
06-Aug-2012 14:51:33.978 client X.X.X.X#33182: send
06-Aug-2012 14:51:33.978 client X.X.X.X#33182: sendto
06-Aug-2012 14:51:33.979 client X.X.X.X#33182: senddone
06-Aug-2012 14:51:33.979 client X.X.X.X#33182: next
06-Aug-2012 14:51:33.979 client X.X.X.X#33182: endrequest
06-Aug-2012 14:51:33.979 client X.X.X.X#33182: read
06-Aug-2012 14:51:33.986 client X.X.X.X#33182: next
06-Aug-2012 14:51:33.986 client X.X.X.X#33182: request failed: end of file
06-Aug-2012 14:51:33.986 client X.X.X.X#33182: endrequest
06-Aug-2012 14:51:33.986 client X.X.X.X#33182: closetcp

But it doesn't do anything. The zone isn't updated, nor does my nsupdate change anything. I'm not sure if the file /etc/bind/primary/sub.example.com should exist prior to the first update or not. I tried it without the file, with an empty file and with a pre-configured zone file. Without success.

The sparse information I found on the net pointed me towards file and folder permissions regarding the bind working directory, so I changed the permissions of both /etc/bind and /var/cache/bind (which is the home dir of my "bind" user).

I'm not a 100% sure if the permissions are correct.. but it looks good to me:

ls -lah /var/cache/bind/
total 224K
drwxrwxr-x  2 bind bind 4.0K Aug  6 03:13 .
drwxr-xr-x 12 root root 4.0K Jul 21 11:27 ..
-rw-r--r--  1 bind bind 211K Aug  6 03:21 named.run

ls -lah /etc/bind/
total 72K
drwxr-sr-x  3 bind bind 4.0K Aug  6 14:41 .
drwxr-xr-x 87 root root 4.0K Jul 30 01:24 ..
-rw-------  1 bind bind  125 Aug  6 02:54 key.public
-rw-------  1 bind bind  156 Aug  6 02:54 key.private
-rw-r--r--  1 bind bind 2.5K Aug  6 03:07 bind.keys
-rw-r--r--  1 bind bind  237 Aug  6 03:07 db.0
-rw-r--r--  1 bind bind  271 Aug  6 03:07 db.127
-rw-r--r--  1 bind bind  237 Aug  6 03:07 db.255
-rw-r--r--  1 bind bind  353 Aug  6 03:07 db.empty
-rw-r--r--  1 bind bind  270 Aug  6 03:07 db.local
-rw-r--r--  1 bind bind 3.0K Aug  6 03:07 db.root
-rw-r--r--  1 bind bind  493 Aug  6 03:32 named.conf
-rw-r--r--  1 bind bind  490 Aug  6 03:07 named.conf.default-zones
-rw-r--r--  1 bind bind 1.2K Aug  6 14:18 named.conf.local
-rw-r--r--  1 bind bind  666 Jul 29 22:51 named.conf.options
drwxr-sr-x  2 bind bind 4.0K Aug  6 03:57 primary/
-rw-r-----  1 root bind   77 Mar 19 02:57 rndc.key
-rw-r--r--  1 bind bind 1.3K Aug  6 03:07 zones.rfc1918

ls -lah /etc/bind/primary/
total 20K
drwxr-sr-x 2 bind bind 4.0K Aug  6 03:57 .
drwxr-sr-x 3 bind bind 4.0K Aug  6 14:41 ..
-rw-r--r-- 1 bind bind  356 Jul 30 00:45 example.com
share|improve this question

2 Answers 2

I had pretty much exactly the same issue on an Ubuntu server and it turned out to be two problems:

(1) apparmor

I don't know if the same is true for Debian, but on Ubuntu bind9 is run with apparmor enabled. This means it is only allowed to write to certain places. The places are listed in /etc/apparmor.d/usr.sbin.named, and it is generally advisable to stay within these directories. You can install the apparmor-utils package and (temporarily) disable apparmor for bind to see if this causes your issue:

sudo aa-status

should show /usr/sbin/named in the list of enforced profiles. Then run

sudo aa-complain /usr/sbin/named

to put it into complain mode.

(2) zone file

Almost no manual/tutorial mentions this, but bind9 expects an (pre-)existing zone file to work properly. The end of file error could be caused by the fact that zone file doesn't exist yet (/etc/bind/primary/example.com and /etc/bind/primary/sub.example.com in your example). You can simply create one like this:

echo "; DO NOT EDIT MANUALLY - use the \"nsupdate\" utility to prevent data loss
\$ORIGIN example.com.
\$TTL 86400  ; 1 day
@    IN SOA  ns1.example.com. hostmaster.example.com. (
       2009074711 ; serial
       7200       ; refresh (2 hours)
       300        ; retry (5 minutes)
       604800     ; expire (1 week)
       60         ; minimum (1 minute)
   IN  NS  ns1.example.com.
ns1    IN  A  <IP of your bind server>" | sudo -u bind tee /etc/bind/primary/example.com
share|improve this answer
I would suggest simply following the configuration schema suggested in the Debian/Ubuntu documentation (in /usr/share/doc/bind9/README.Debian.gz) instead, which places dynamic zones in /var/lib/bind, something which apparmor in Ubuntu is already set up to deal with without any changes. This also avoids the unorthodox setup where named is allowed to change files under /etc. –  Håkan Lindqvist Jul 24 at 14:09
Regarding the comment at the top of the zone template, that will be expected to disappear after the file has been rewritten by bind. –  Håkan Lindqvist Jul 24 at 14:15

See the section in nsupdate

   With the -k option, nsupdate reads the shared secret from the file
   keyfile. Keyfiles may be in two formats: a single file containing a
   named.conf-format key statement, which may be generated automatically
   by ddns-confgen, or a pair of files whose names are of the format
   K{name}.+157.+{random}.key and K{name}.+157.+{random}.private, which
   can be generated by dnssec-keygen. The -k may also be used to specify a
   SIG(0) key used to authenticate Dynamic DNS update requests. In this
   case, the key specified is not an HMAC-MD5 key.

So if you were to reformat it into the

key sub.example.com. {
        algorithm HMAC-MD5;
        secret "xxxx xxxx";

form and leave that in a file it will work, or alternatively -k K{name}.+157.+{random}.*

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.