Exercise 4: Dynamic DNS (DDNS) with DHCP and BIND9
Building on Exercises 1–3, extend srv1 so that every client that receives a lease from the DHCP service is automatically registered in DNS. Nobody should have to edit a zone file by hand when a new machine joins the LAN segment, and nobody who is not srv1’s DHCP service should be able to change DNS records.
1. BIND9: Accept Secured Dynamic Updates
Configure BIND9 on srv1 so that the forward zone mydomain.intern and the reverse zone for 172.30.0.0/16 accept dynamic DNS updates (RFC 2136).
- Updates must be authenticated with a TSIG key (shared secret). Updates without a valid key must be rejected. Restricting updates by source IP address alone is not sufficient.
- Generate a dedicated key for DDNS and store it so that only the services that need it can read it.
- Only the two zones above may be updated. Do not open up anything else.
- Both zones must still load without errors, and all existing lookups from Exercises 1–3 (
srv1,ns1, reverse lookup of172.30.0.1, forwarder) must keep working. - Think about the static
client1records you added in Exercise 2.client1now gets its address via DHCP, so decide how those records fit into a zone that is managed dynamically.
Hint
tsig-keygen(packagebind9-utils) creates a key in BIND syntax. Keep it in its own file andincludeit from your BIND configuration.allow-updateorupdate-policyin the zone definitions.- For a
/16network the reverse zone is usually named30.172.in-addr.arpa. Use the name you already set up in Exercise 1.- BIND stores dynamic changes in a journal file (
.jnl) next to the zone file. Thenamedprocess must be allowed to write there. On Debian, AppArmor restricts wherenamedmay write, so checkjournalctl/dmesgfor denials if updates fail with permission errors.- Once a zone is dynamic, do not edit its zone file while
namedis running withoutrndc freeze/rndc thaw.named-checkconfandnamed-checkzonevalidate your changes before you restart the service.
2. DHCP Server: Send DDNS Updates
Extend the isc-dhcp-server configuration from Exercise 3 so that for every lease:
- a forward record (A) and a reverse record (PTR) are created automatically in the correct zones,
- the updates are sent to BIND9 on
srv1and signed with the TSIG key from step 1, - the hostname is taken from what the client announces in its DHCP request, and the domain part is
mydomain.intern.
The key secret is now part of your DHCP configuration as well, so make sure it is not readable by unprivileged users.
Hint
- Relevant
dhcpd.confdirectives:ddns-updates,ddns-update-style,ddns-domainname,ddns-rev-domainname,key, andzoneblocks withprimaryandkey.- Zone names in
dhcpd.confmust match the BIND zone names exactly (mind the trailing dot).- The
primaryaddress must be one thatnamedactually listens on (checklisten-onin the BIND options).dhcpd -t -cf /etc/dhcp/dhcpd.confchecks the configuration syntax.- Both services log update attempts and failures:
journalctl -u bind9andjournalctl -u isc-dhcp-server.
3. New Client VM: client2
Create a third VM that joins the network without any manual DNS or address configuration on srv1.
- Debian 13 (Trixie) minimal installation (no GUI), hostname
client2. - Two network cards: Interface 1 (WAN) via DHCP (NAT), Interface 2 (LAN) attached to the same host-only network as
srv1andclient1. - The LAN interface must obtain its configuration via DHCP (no static address).
- IPv4 only, same as the other VMs.
Hint
- The DDNS update can only use a hostname if the client sends one in its DHCP request. How this is configured depends on the DHCP client in use (e.g.
dhcpcd,dhclient,systemd-networkd, NetworkManager). Check in thedhcpdlog which hostname the server actually received.- If you clone an existing VM, make sure MAC address, hostname and machine-id are unique. Otherwise the DHCP server may treat the clone as the same client and hand out the same lease.
4. Verification & Proof
Test and document the following:
- Before joining: Before the LAN interface of
client2is brought up for the first time, confirm thatclient2.mydomain.interndoes not resolve (e.g.NXDOMAINfromdig). - Lease and update: Confirm
client2received an IPv4 address from the DHCP pool and thatsrv1shows the corresponding lease. Show the log lines onsrv1that prove the DDNS update was sent and accepted. - Forward lookup: Resolve
client2.mydomain.internwithdigandnslookupfromclient2,client1andsrv1. The result must be the addressclient2received via DHCP. - Reverse lookup: Resolve the IP address of
client2back to its hostname withdig -xandnslookup, again from all three machines. - What else is in the zone? Look at which additional record(s) the DHCP server stored next to the A record of
client2and explain their purpose. (e.g.digfor different record types, ornamed-journalprinton the journal file) - Security — unauthorized update: Try to add or change a record with
nsupdatefromclient2without a key and with a wrong key. Both attempts must fail. Document the error and the corresponding BIND log entry. - Security — authorized update: From
srv1, perform a manual update with the correct key (nsupdate -k), confirm it works withdig, and delete the test record again. - Security — key handling: Show the file permissions of every file that contains the TSIG secret, and show that the BIND zone configuration does not allow updates from
anyor from an IP address alone. - Persistence: Restart BIND9 on
srv1and confirm the dynamic records ofclient2are still resolvable afterwards. - Existing client: Renew the lease on
client1(or reboot it) and confirm that its records are now consistent (one correct A record, one correct PTR record, no stale static leftovers). Repeat the forward and reverse lookup.
Optional
Temporarily set a short lease time on srv1. Release the lease on client2 (or shut it down and wait for expiry) and observe what happens to its DNS records.