I just switched to bind
9.9.5 dynamic DNS feature with semi-automatic management of DNSSEC entries, the whole process went good and my zone files were updated well, but now I can't update or add entries via nsupdate
tool.
The /etc/bind/named.conf.local
:
// 1
view "localhost_view" {
allow-query-on { 127.0.0.1; };
allow-query { localhost_acl; };
match-clients { localhost_acl; };
zone "somehost.tld" {
type master;
file "/etc/bind/db.somehost.tld_10";
};
zone "168.192.in-addr.arpa" {
type master;
notify no;
file "/etc/bind/db.192.168.10";
};
// formerly named.conf.default-zones
zone "." {
type hint;
file "/etc/bind/db.root";
};
zone "localhost" {
type master;
file "/etc/bind/db.local";
};
zone "127.in-addr.arpa" {
type master;
file "/etc/bind/db.127";
};
zone "0.in-addr.arpa" {
type master;
file "/etc/bind/db.0";
};
zone "255.in-addr.arpa" {
type master;
file "/etc/bind/db.255";
};
// formerly zones.rfc1918
zone "10.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "16.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "17.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "18.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "19.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "20.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "21.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "22.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "23.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "24.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "25.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "26.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "27.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "28.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "29.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "30.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "31.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
};
// 2
view "internal_10_view" {
allow-query-on { 192.168.10.1; };
allow-query { internal_10_acl; };
match-clients { internal_10_acl; };
zone "somehost.tld" {
type master;
file "/etc/bind/db.somehost.tld_10";
};
zone "168.192.in-addr.arpa" {
type master;
notify no;
file "/etc/bind/db.192.168.10";
};
// formerly named.conf.default-zones
zone "." {
type hint;
file "/etc/bind/db.root";
};
zone "localhost" {
type master;
file "/etc/bind/db.local";
};
zone "127.in-addr.arpa" {
type master;
file "/etc/bind/db.127";
};
zone "0.in-addr.arpa" {
type master;
file "/etc/bind/db.0";
};
zone "255.in-addr.arpa" {
type master;
file "/etc/bind/db.255";
};
// formerly zones.rfc1918
zone "10.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "16.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "17.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "18.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "19.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "20.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "21.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "22.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "23.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "24.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "25.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "26.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "27.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "28.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "29.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "30.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "31.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
};
// 3
view "internal_150_view" {
allow-query-on { 192.168.150.1; };
allow-query { internal_150_acl; };
match-clients { internal_150_acl; };
zone "somehost.tld" {
type master;
file "/etc/bind/db.somehost.tld_150";
};
zone "168.192.in-addr.arpa" {
type master;
notify no;
file "/etc/bind/db.192.168.150";
};
// formerly named.conf.default-zones
zone "." {
type hint;
file "/etc/bind/db.root";
};
zone "localhost" {
type master;
file "/etc/bind/db.local";
};
zone "127.in-addr.arpa" {
type master;
file "/etc/bind/db.127";
};
zone "0.in-addr.arpa" {
type master;
file "/etc/bind/db.0";
};
zone "255.in-addr.arpa" {
type master;
file "/etc/bind/db.255";
};
// formerly zones.rfc1918
zone "10.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "16.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "17.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "18.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "19.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "20.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "21.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "22.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "23.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "24.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "25.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "26.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "27.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "28.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "29.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "30.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "31.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
};
// 4
view "vpn_view" {
allow-query-on { 192.168.200.1; };
allow-query { vpn_acl; };
match-clients { vpn_acl; };
zone "somehost.tld" {
type master;
file "/etc/bind/db.somehost.tld_vpn";
};
// formerly named.conf.default-zones
zone "." {
type hint;
file "/etc/bind/db.root";
};
zone "localhost" {
type master;
file "/etc/bind/db.local";
};
zone "127.in-addr.arpa" {
type master;
file "/etc/bind/db.127";
};
zone "0.in-addr.arpa" {
type master;
file "/etc/bind/db.0";
};
zone "255.in-addr.arpa" {
type master;
file "/etc/bind/db.255";
};
// formerly zones.rfc1918
zone "10.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "16.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "17.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "18.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "19.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "20.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "21.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "22.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "23.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "24.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "25.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "26.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "27.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "28.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "29.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "30.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "32.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
};
// 5
view "global_view" {
allow-query-on { 1.2.3.4; };
// match-clients { any; !localhost_acl; !internal_10_acl; !internal_150_acl; !vpn_acl; };
recursion no;
zone "somehost.tld" {
type master;
update-policy local;
auto-dnssec maintain;
file "/etc/bind/db.somehost.tld_global";
key-directory "/etc/bind/keys";
};
zone "26/4.3.2.1.in-addr.arpa" IN {
type master;
file "/etc/bind/db.rev";
};
// formerly named.conf.default-zones
zone "." {
type hint;
file "/etc/bind/db.root";
};
zone "localhost" {
type master;
file "/etc/bind/db.local";
};
zone "127.in-addr.arpa" {
type master;
file "/etc/bind/db.127";
};
zone "0.in-addr.arpa" {
type master;
file "/etc/bind/db.0";
};
zone "255.in-addr.arpa" {
type master;
file "/etc/bind/db.255";
};
// formerly zones.rfc1918
zone "10.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "16.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "17.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "18.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "19.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "20.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "21.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "22.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "23.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "24.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "25.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "26.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "27.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "28.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "29.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "30.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
zone "32.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
};
ACLs:
acl localhost_acl {
127.0.0.0/8;
};
acl internal_10_acl {
192.168.10.0/24;
};
acl internal_150_acl {
192.168.150.0/24;
};
acl vpn_acl {
192.168.200.2;
192.168.200.5;
};
So the update-policy local;
is here, /var/run/named/session.key
is successfully generated and user bind
readable, but when I perform the add command via nsupdate -l
(as root), I always get the update failed: REFUSED
error (here with debug messages):
root@somehost:/etc/bind# nsupdate -l -v -D
setup_system()
Creating key...
namefromtext
keycreate
reset_system()
user_interaction()
> ttl 46000
do_next_command()
> zone somehost.tld.
do_next_command()
> update add whatever.somehost.tld. A 1.1.1.1
do_next_command()
evaluate_update()
update_addordelete()
> send
do_next_command()
start_update()
send_update()
Sending update to 127.0.0.1#53
show_message()
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 15363
;; flags:; ZONE: 1, PREREQ: 0, UPDATE: 1, ADDITIONAL: 1
;; ZONE SECTION:
;somehost.tld. IN SOA
;; UPDATE SECTION:
whatever.somehost.tld. 46000 IN A 1.1.1.1
;; TSIG PSEUDOSECTION:
local-ddns. 0 ANY TSIG hmac-sha256. 1446539060 300 32 r2lt18dGihGnJepoUjvIKx8l5BPMohNJvsLoO+WQiBE = 15363 NOERROR 0
update_completed()
tsig verification successful
show_message()
Reply from update query:
;; ->>HEADER<<- opcode: UPDATE, status: REFUSED, id: 15363
;; flags: qr ra; ZONE: 1, PREREQ: 0, UPDATE: 0, ADDITIONAL: 1
;; ZONE SECTION:
;somehost.tld. IN SOA
;; TSIG PSEUDOSECTION:
local-ddns. 0 ANY TSIG hmac-sha256. 1446539060 300 32 Cnh9Tgg5vhKngPRk2J8n0wiRzdBLlQrp0F0qmfUotN8 = 15363 NOERROR 0
done_update()
reset_system()
user_interaction()
> quit
It is some kind of permission issue? What's wrong?
Best Answer
Finally figured it out. Thanks to @HÃ¥kan Lindqvist for inspiration.
These solutions are probably Debian/Ubuntu-specific and weren't tested in other distros.
1. FIRST SOLUTION
(Using
update-policy local;
).You may actually use
update-policy local;
directive in/etc/bind/named.conf.local
in each zone declaration you want, which restricts update requests from the internet or LAN for better security. In this case the key is generated automatically andnsupdate
will use it if run with-l
option.Instead of
server X.X.X.X
command one should uselocal X.X.X.X
. It accepts even public IP as argument if it is local to the system!Note: the key is not world-readable, so use
sudo
.Example:
2. SECOND SOLUTION
(Using
ddns-confgen
).I have plenty of views (
localhost_view
,global_view
etc.), some of which have common zones (somehost.tld
in my example). If I want to dynamically update them, I should useserver X.X.X.X
command when donsupdate
. Thereforensupdate
will send an update request to the appropriate interface and the appropriate view will handle it.update-policy local;
is not suitable in this configuration because it forbids use of theserver
command innsupdate
. So it is needed to generate a DDNS key and specify it in all of the zones declarations, which should be dynamically updated bynsupdate
. In the Debian universe there is addns-confgen
command which simplifies this task a lot:The output of this command is quite self-descriptive. It is needed to add
key...
snippet to the/etc/bind/named.conf
and separate file with any name, andupdate-policy...
snippet into eachzone
declaration, which will be managed bynsupdate
.To properly use
nsupdate
tool in multi-view BIND environment, it is needed to explicitly specify aserver
directive before executing any other command. So, for updatinglocalhost_view
'ssomehost.tld
zone (consideringkey...
snippet was saved to the/etc/bind/ddns-key.key
) the commands are as follows (note theserver 127.0.0.1
):whereas to manipulate
global_view
'ssomehost.tld
zone the commands are essentially the same, but with differentserver
. In this case it is needed to use public IP (1.2.3.4
in my example):Therefore
nsupdate
sends a request to a proper interface (which may or may not be the local one) and a specific view works.