Dynamic updates using TSIGs are relatively easy to setup in BIND. The mechanism to limit keys to specific hosts and their IPs may not be apparent per se on the other hand. TSIGs provide point-to-point authentication and integrity between servers, they do not provide encryption on the transport layer.
First we will create a secret key which will be used to sign the communication using hashes between our primary and one of the secondary servers.
Each secondary server will ideally use a dedicated key.
dnssec-keygen -a hmac-sha512 -b 512 -r /dev/urandom -n HOSTns1-ns2.example.com
We populate the newly created key.
key ns1-ns2.example.com. { algorithm hmac-sha512; include "/k/ns1-ns2.example.com.key"; };
Our key needs to be wrapped in a secret
statement as if it would have been added to our named options configuration file directly.
secret "ikgnhCj+MPcNf8SjWqf8yxh2p...+9p59YhgKUzHax5calokZQA==";
Access control list
We define all authoritative name servers in a new Access Control List, let’s call it transfer_allowed
. We also define which private key is to be used with each remote host.
acl transfer_allowed { 10.0.0.1; 2a02:beef:fa:1000::1; 172.16.0.1; };
server 10.0.0.1 { keys { ns1-ns2.example.com. }; }; server 2a02:beef:fa:1000::1 { keys { ns1-ns2.example.com. }; };
Zone configuration
Next we use a !negated construct inside the allow-transfer
statement for our zone. By disallowing any host besides the IPs listed inside the ACL transfer_allowed
, zone transfers are effectively limited to hosts which are explicitly allowed in our ACL and which have to use a specific key at the same time.
zone "example.com" { type primary; file "/p/db.example.com"; key-directory "/k/example.com"; auto-dnssec maintain; inline-signing yes; notify yes; allow-query { any; };allow-transfer { !{!transfer_allowed; any;}; key ns1-ns2.example.com.; }; update-policy { grant admin.example.com. zonesub any; grant _acme-challenge.example.com. name _acme-challenge.example.com. TXT; grant mail.example.com. name _25._tcp.mail.example.com. TLSA; }; serial-update-method unixtime; zone-statistics full; };
A similar approach can be used to secure DDNS update propagation. Please note that update-policy
and allow-update
are mutually exclusive however.
allow-update { !{!update_allowed; any;}; key admin.example.com.; };
ISC explains the expression logic like this:
{ { !A; any; }; B; }
any address other than A is accepted at once, but A is only accepted if B matches too.
boolean translation: ((not A) or (A and B)){ !{ !A; any; }; B; }
any address other than A is *rejected* at once, but A is accepted as long as B matches too.
boolean translation: (A and B)
Test ACL
It’s possible to verify the effectiveness of our restriction using dig by specifying the signature key to use:
dig axfr example.com @ns1.example.com -y hmac-sha512:ns1-ns2.example.com:<secret>