Broken down that way, the migration didn't look terribly scary—and it's made easier by the fact that the Kea default config files come filled with descriptive comments and configuration examples to crib from. (And, again, ISC has done an outstanding job with the docs for Kea. All versions, from deprecated to bleeding-edge, have thorough and extensive online documentation if you're curious about what a given option does or where to apply it—and, as noted above, there are also the supplied sample config files to tear apart if you want more detailed examples.)
Configuration time for DHCP
We have two Kea applications to configure, so we'll do DHCP first and then get to the DDNS side. (Though the DHCP config file also contains a bunch of DDNS stuff, so I guess if we're being pedantic, we're setting both up at once.)
The first file to edit, if you installed Kea via package manager, is /etc/kea/kea-dhcp4.conf. The file should already have some reasonably sane defaults in it, and it's worth taking a moment to look through the comments and see what those defaults are and what they mean.
Here's a lightly sanitized version of my working kea-dhcp4.conf file:
{ "Dhcp4": { "control-socket": { "socket-type": "unix", "socket-name": "/tmp/kea4-ctrl-socket" }, "interfaces-config": { "interfaces": ["eth0"], "dhcp-socket-type": "raw" }, "dhcp-ddns": { "enable-updates": true }, "ddns-conflict-resolution-mode": "no-check-with-dhcid", "ddns-override-client-update": true, "ddns-override-no-update": true, "ddns-qualifying-suffix": "bigdinosaur.lan", "authoritative": true, "valid-lifetime": 86400, "renew-timer": 43200, "expired-leases-processing": { "reclaim-timer-wait-time": 3600, "hold-reclaimed-time": 3600, "max-reclaim-leases": 0, "max-reclaim-time": 0 }, "loggers": [ { "name": "kea-dhcp4", "output_options": [ { "output": "syslog", "pattern": "%-5p %m\n", "maxsize": 1048576, "maxver": 8 } ], "severity": "INFO", "debuglevel": 0 } ], "reservations-global": false, "reservations-in-subnet": true, "reservations-out-of-pool": true, "host-reservation-identifiers": [ "hw-address" ], "subnet4": [ { "id": 1, "subnet": "10.10.10.0/24", "pools": [ { "pool": "10.10.10.170 - 10.10.10.254" } ], "option-data": [ { "name": "subnet-mask", "data": "255.255.255.0" }, { "name": "routers", "data": "10.10.10.1" }, { "name": "broadcast-address", "data": "10.10.10.255" }, { "name": "domain-name-servers", "data": "10.10.10.53" }, { "name": "domain-name", "data": "bigdinosaur.lan" } ], "reservations": [ { "hostname": "host1.bigdinosaur.lan", "hw-address": "aa:bb:cc:dd:ee:ff", "ip-address": "10.10.10.100" }, { "hostname": "host2.bigdinosaur.lan", "hw-address": "ff:ee:dd:cc:bb:aa", "ip-address": "10.10.10.101" } ] } ] } }The first stanzas set up the control socket on which the DHCP process listens for management API commands (we're not going to set up the management tool, which is overkill for a homelab, but this will ensure the socket exists if you ever decide to go in that direction). They also set up the interface on which Kea listens for DHCP requests, and they tell Kea to listen for those requests in raw socket mode. You almost certainly want raw as your DHCP socket type (see here for why), but this can also be set to udp if needed.