Doing secure dynamic DNS updates with BIND
Monday, July 1. 2013
ISC BIND is the most popular DNS in the entire Internet. Most hostmasters never need to allow DNS-clients to change records, but then there are cases where it can be handy.
When thinking of the security, it will be very, very stupid to allow anybody to update records. Luckily there doesn't seem to be a script-kiddie-proof -tool for doing that (or at least I haven't found one yet). Most servers simply don't allow dynamic updates and those who do, don't allow it for all zones. Security-wise one of the simplest approaches is to allow updating a zone from specific subnet or hand-picked IP-addresses. That way most of the users have been excluded using a simple mechanism. Surely any motivated cracker will bend any rules, that exist.
To add security and allow updates only for those who actually are permitted, a smart move is to go TSIG. It is described in RFC 2845 Secret Key Transaction Authentication for DNS (TSIG) and is supported by many DNS-servers, including BIND. Getting it running is described poorly. Best description I found is in Jeff Garzik's blog the article is title "nsupdate: Painless Dynamic DNS".
The basic steps are pretty much following:
- Generate update key
- This will include executing a command like:
dnssec-keygen -a hmac-md5 -b 128 -n HOST my.dns.update.key. - Inform BIND-server about the key
- This will include changing the raw key-file into BIND-format, like:
key "my-key-name" {
algorithm hmac-md5;
secret "somethingcompletelybullshithere==";
}; - Allow a zone to be updateable by anybody knowing the key
- This can be accomplished with allow-update -configuration directive.
- Go update!
A test run for checking out if your setup succeeded would be:
# nsupdate -k my.dns.update.key
update delete a.record.my.zone. A
update add a.record.my.zone. 3600 A 192.168.0.198
show
send
If server's messsage log says something like "client 192.168.0.1#12790: request has invalid signature: TSIG dhis: tsig verify failure (BADKEY)", then your key setup failed. Either server doesn't recognize your client's key, or client failed to provide a valid key.
If server's message log says something like "client 192.168.0.1#39782: update 'my.zone/IN' denied", then the DNS-zone to be updated does not allow dynamic updates. Add something like allow-update { key "my-key-name"; }; into your zone-configuration.
A successful update will show something like this in your logs:
named[25415]: client 192.168.0.1#64975: signer "my-key-name" approved
named[25415]: client 192.168.0.1#64975: updating zone 'my.zone/IN': deleting rrset at 'a.record.my.zone' A
named[25415]: client 192.168.0.1#64975: updating zone 'my.zone/IN': adding an RR at 'a.record.my.zone' A
(Note: the named PID and client port-numbers are just copy/pasted from my log. They will differ in your case.)