Updating DNS entries and static DHCP entries always seemed like a chore for me. Luckily, we can automate it. We will use DHCP to update/create entries in DNS. I used ISC BIND and ISC DHCP for my servers.

DHCP Config File

Add these lines to /etc/dhcp/dhcpd.conf. Don’t forget to change your mydomain.lan to your domain and use the correct reverse subnet IP. The primary 127.0.0.1 line can be changed to the IP of where your DNS server is if it isn’t running locally. I thought it was kind of weird at first, putting zones into the DHCP config, but you do need them.

ddns-guard-id-must-match false;
update-conflict-detection false;

zone mydomain.lan. {
	primary 127.0.0.1;
	key rndc-key;
}

zone 0.168.192.in-addr.arpa. {
	primary 127.0.0.1;
	key rndc-key;
}

Note: Setting the two options above makes it so any client can overwrite any DNS entry for ease of a home network. So basically, if server.mydomain.lan was statically set to 192.168.0.10 and a client with the host name of server received an IP address of 192.168.0.123, server.mydomain.lan would now point to the client and not the original server. This could have security implications in your environment, so beware!!! You will need to research the man pages (man 5 dhcpd.conf and search for DYNAMIC DNS UPDATE SECURITY) for further details to properly secure these.

We will use the rndc-confgen command, which comes with bind, to generate a random key for us. Add the rndc-key section from the output of the command to your /etc/dhcp/dhcpd.conf file.

server ~ # rndc-confgen
... output truncated ...
key "rndc-key" {
	algorithm hmac-sha256;
	secret "<randomstuffhere>";
};
... output truncated ...

BIND Config File

Copy and paste the same rndc-key section from above into your /etc/bind/named.conf file.

The allow-update lines need to be added to your zones. The other options may vary, depending on your server setup. By default, named will create a journal file in the same location as where the domain file is that will be used to store the updates from your DHCP server. On Gentoo, the pri and rev directories where the zone files are stored by default are not writable by the named daemon. So, we can change the path with the journal line.

zone "mydomain.lan" IN {
	type master;
	file "/etc/bind/pri/mydomain.lan.zone";
	allow-transfer { xfer; };
	allow-update { key rndc-key; };
	journal "/etc/bind/dyn/mydomain.lan.jnl";
	forwarders { };
};
zone "0.168.192.in-addr.arpa" IN {
	type master;
	file "/etc/bind/rev/0.168.192.in-addr.arpa.zone";
	allow-transfer { xfer; };
	allow-update { key rndc-key; };
	journal "/etc/bind/dyn/0.168.192.in-addr.arpa.jnl";
};

Verification

Logging on your DNS server can be set up with this config in your /etc/bind/named.conf file. The category line is what is important. We want to see updates.

logging {
	channel default_log {
		file "/var/log/named/named.log" versions 5 size 50M;
		severity dynamic;
		print-time yes;
		print-severity yes;
		print-category yes;
	};
	category update { default_log; };
};

Example log file output.

09-Aug-2020 16:08:04.883 update: info: client @0x7feb1c01f9e0 127.0.0.1#46049/key rndc-key: view default: updating zone 'mydomain.lan/IN': update unsuccessful: client.mydomain.lan: 'name not in use' prerequisite not satisfied (YXDOMAIN)
09-Aug-2020 16:08:04.895 update-security: info: client @0x7feb1c01f9e0 127.0.0.1#46049/key rndc-key: view default: signer "rndc-key" approved
09-Aug-2020 16:08:04.895 update: info: client @0x7feb1c01f9e0 127.0.0.1#46049/key rndc-key: view default: updating zone 'mydomain.lan/IN': deleting rrset at 'client.mydomain.lan' DHCID
09-Aug-2020 16:08:04.895 update: info: client @0x7feb1c01f9e0 127.0.0.1#46049/key rndc-key: view default: updating zone 'mydomain.lan/IN': adding an RR at 'client.mydomain.lan' DHCID AAEB6b6zR9Y4oKEL141DkjKmqdwaMuTRMN2Tpgs+xZPEGQg=
09-Aug-2020 16:08:04.895 update: info: client @0x7feb1c01f9e0 127.0.0.1#46049/key rndc-key: view default: updating zone 'mydomain.lan/IN': deleting rrset at 'client.mydomain.lan' A
09-Aug-2020 16:08:04.895 update: info: client @0x7feb1c01f9e0 127.0.0.1#46049/key rndc-key: view default: updating zone 'mydomain.lan/IN': adding an RR at 'client.mydomain.lan' A 192.168.0.131
09-Aug-2020 16:08:04.908 update-security: info: client @0x7feb1c01f9e0 127.0.0.1#46049/key rndc-key: view default: signer "rndc-key" approved
09-Aug-2020 16:08:04.908 update: info: client @0x7feb1c01f9e0 127.0.0.1#46049/key rndc-key: view default: updating zone '0.168.192.in-addr.arpa/IN': deleting rrset at '131.0.168.192.in-addr.arpa' PTR
09-Aug-2020 16:08:04.908 update: info: client @0x7feb1c01f9e0 127.0.0.1#46049/key rndc-key: view default: updating zone '0.168.192.in-addr.arpa/IN': adding an RR at '131.0.168.192.in-addr.arpa' PTR client.mydomain.lan.

References

  1. man 5 dhcpcd.conf and search for DYNAMIC DNS UPDATE SECURITY. Example config and more information.