setting up bind to work with nsupdate (SERVFAIL)
Solution 1
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
Solution 2
I was having very similar issues until I changed the location of where I stored my zone files.
Bind had permission to write to /var/cache/bind
, but your zone files are stored in /etc/bind/...
. Bind does not currently have permission to write to files in /etc/bind/...
, so you would need to update Bind's permissions or store the zone files in a directory where Bind has the proper permissions. I will cover the simple steps to move the zone files to the directory recommended for dynamic zones (/var/lib/bind/
).
Move the zone files with
mv
(likely needs to be executed as root)mv /etc/bind/primary/example.com /var/lib/bind/primary/ mv /etc/bind/primary/sub.example.com /var/lib/bind/primary/
Update the file path in your
named.conf
configurations. In your case this means updating/etc/bind/named.conf.local
zone "example.com" { type master; file "/var/lib/bind/primary/example.com"; //this line changed //other stuff removed for clarity }; zone "sub.example.com" { type master; file "/var/lib/bind/primary/sub.example.com"; //this line changed //other stuff removed for clarity };
Restart Bind with
service bind9 restart
Solution 3
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}.*
Solution 4
For dyndns updates BIND must be able to write to the folders used by the zones. It seems to me that /etc is not a right place to store such information, and looking at your permissions, etc is not writable by bind.
I suggest to try the /var/bind directory, so that bind can write to it.
Related videos on Youtube
![Marco](https://i.stack.imgur.com/4hOmn.png?s=256&g=1)
Marco
Updated on September 18, 2022Comments
-
Marco almost 2 years
I'm trying to update my DNS-Server dynamically using nsupdate.
Prerequisite
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 10.10.10.1 show send
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 ;; ZONE SECTION: ;sub.example.com. IN SOA ;; UPDATE SECTION: sub.example.com. 86400 IN A 10.10.10.1 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
-
user3099887 almost 6 yearsJust a tip: I had the same problem. No selinux, working on one zone bot with "sERVFAIL" error on another. I solved it by removing the .jnl file that bind generates.
-
-
Håkan Lindqvist almost 10 yearsI 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 wherenamed
is allowed to change files under/etc
. -
Håkan Lindqvist almost 10 yearsRegarding the comment at the top of the zone template, that will be expected to disappear after the file has been rewritten by bind.
-
Alexis Wilke over 5 yearsThat worked! I use Ubuntu and restart with
systemctl restart bind9
but outside of that, moving the files under/var/lib/bind/...
made it work. Even changing the ownership of the files under/etc/bind/...
was not sufficient. I think thatbind9
checks the path and if it starts with/etc
, it prevents any updates. -
jchook about 4 yearsJust wanted to mention (at least on Debian-based systems),
/etc/apparmor.d/usr.sbin.named
also suggests putting dynamic configs in/var/lib/bind
, and indicates that/etc/bind
configs should not change dynamically