[SIZE="4"]Dynamic DNS with BIND and ISC DHCP SERVER[/SIZE] I decided to write a HOWTO about dynamic DNS updates with BIND DNS server and ISC DHCP server. Automatic registration of DHCP client hostnames to DNS is something that is almost taken for granted nowadays. However, there are not too many good articles on how to set it up with just the standard tools, a DNS server like BIND (included in base in FreeBSD) and a DHCP server like net/isc-dhcp-server42. I'm assuming you already have both BIND and the DHCP server running and serving clients, this HOWTO doesn't cover installing and configuring them for standard (non-DDNS) use. I’m also assuming that you have at least a basic understanding of how DNS and DHCP work. [SIZE="4"]0. Prerequisites[/SIZE] The DNS server serving the local network must be an authoritative server for the domain, this is an absolute requirement. [SIZE="4"]1. Creating a key for DDNS updates[/SIZE] The DDNS updates should be allowed only to the DHCP server serving DCHP leases on the local network(s), that’s why a cryptographic key for authentication is needed. The key is created with [man]ddns-confgen(8)[/man]. The key is created using the MD5 hash algorithm. The isc-dhcpd doesn’t support any other hash algorithms than MD5 at the moment even if use of other algorithms is possible with [man]nsupdate(1)[/man]. Note that rerunning the key generation will result in a different key every time. This and all other examples involving commands run on the command line assume that they are run as the root user. [cmd=#]ddns-confgen -a hmac-md5 -z mydomain[/cmd] Output will be like this (I’m using [COLOR="Red"]longrandomstring[/COLOR] in place of the real key here): [code]# To activate this key, place the following in named.conf, and # in a separate keyfile on the system or systems from which nsupdate # will be run: key "ddns-key.mydomain" { algorithm hmac-md5; secret "[COLOR="red"]longrandomstring[/COLOR]"; }; # Then, in the "zone" statement for each zone you wish to dynamically # update, place an "update-policy" statement granting update permission # to this key. For example, the following statement grants this key # permission to update any name within the zone: update-policy { grant ddns-key zonesub ANY; }; # After the keyfile has been placed, the following command will # execute nsupdate using this key: nsupdate -k Copy the key -statement and save it in a file called ddns-key.mydomain. Make sure the file is only root readable.[/code] [SIZE="4"]2. Configuring BIND for dynamic updates[/SIZE] First thing to do is to move the zone files of the to be dynamically updated zones from [file]/etc/namedb/master[/file] to [file]/etc/namedb/dynamic[/file], the bind user has no write permissions to the master directory but does have them to the dynamic directory. Adjust the zone definitions in named.conf accordingly: [code]zone “mydomain” { type master; file “/etc/namedb/dynamic/forward-zone-file”; }; zone “1.168.192.in-addr.arpa” { type master; file “/etc/namedb/dynamic/reverse-zone-file”; };[/code] Add the ddns-key.mydomain key to [file]/etc/namedb/named.conf[/file]: [code]key “ddns-key.mydomain” { algorithm hmac-md5; secret "[COLOR="Red"]longrandomstring[/COLOR]"; };[/code] Modify the zone definitions in [file]/etc/namedb/named.conf[/file] to have an update-policy section: [code]zone “myzone” { type master; file “/etc/namedb/dynamic/forward-zone-file”; update-policy { grant ddns-key.mydomain zonesub ALL; }; }; zone “1.168.192.in-addr.arpa” { type master; file “/etc/namedb/dynamic/reverse-zone-file”; update-policy { grant ddns-key.mydomain zonesub ALL; }; };[/code] Add logging directives to [file]/etc/namedb/named.conf[/file] to catch update and update-security messages in to a separate log file. [code]logging { ... channel update_log { file "/var/log/named/bind-updates.log"; severity debug; print-category yes; print-severity yes; print-time yes; }; ... category update { update_log; }; category update-security { update_log; }; ... };[/code] Restart the DNS server. [cmd=#]service named restart[/cmd] An important note to remember about editing dynamic zones manually: If you have to edit the zone files of dynamic zones manually while the DNS server is running, you’ll have to freeze the zones with [cmd=#]rdnc freeze [myzone][/cmd] before editing and unfreeze them with [cmd=#]rndc thaw [myzone][/cmd] after editing. This is because [man]named(8)[/man] has internal state information and external journal files attached to dynamic zones that have to be kept in sync with the zone files. [SIZE="4"]3. Testing dynamic DNS updates[/SIZE] The dynamic DNS updates can be tested without the DHCP server using the [man]nsupdate(8)[/man] tool. If you saved the ddns-key.mydomain into a separate file with the same name the following should add a new A record testhost.mydomain with address 192.168.1.200: [cmd=#]nsupdate -k ddns-key.mydomain > update add testhost.mydomain 3600 A 192.168.1.200 > send > ^D[/cmd] This should now return 192.168.1.200. [cmd=#]dig testhost.mydomain.[/cmd] [SIZE="4"]4. Configuring the DHCP server for dynamic updates.[/SIZE] Tell the DHCP server to use the key created earlier to send its updates to the DNS server. Add this to dhcpd.conf: [code]# Key for DDNS updates key ddns-key.myzone { algorithm hmac-md5; secret "longrandomstring"; };[/code] Next add update instructions for every zone that is going to updated automatically: [code]zone myzone. { primary 127.0.0.1; key ddns-key.myzone; } zone 1.168.192.in-addr.arpa. { primary 127.0.0.1; key ddns-key.myzone; }[/code] The primary
line tells [man]dhcpd(8)[/man] where to send updates for the zone. The key line tells it which key to use. In this example the DNS server and the DHCP server are on the same host and the updates are sent to localhost but it’s not a requirement for dynamic DNS updates to work, the DHCP server could be running on another host. In such case the primary
would have the address of the DNS server on the local network. Make sure that dhcpd.conf is not world readable: [cmd=#]chmod 640 /usr/local/etc/dhcpd.conf[/cmd] Restart the DHCP server. [cmd=#]service isc-dhcpd restart[/cmd]