I run a small, boring DNS server at home. It sits on a low-power VM and quietly keeps things reachable. That calm service saves time when other projects break. This is the setup I use for a home lab, with the filenames, commands and checks I actually care about. Reliability matters more than novelty.
Pick simple hardware and a minimal install. For a tiny home lab, a Raspberry Pi 4 or a VM with 1–2 GB RAM and 8–16 GB disk is fine. On the software side, pick the right tool for the job: Unbound as a resolver, BIND9 for authoritative zones, or dnsmasq for lightweight local names. On Debian or Ubuntu, the packages are:
apt update
apt install unbound
or:
apt install bind9 dnsmasq
Give the server a static IP on your LAN and set DHCP to hand out that address as the primary DNS. In network configuration, use a fixed address in your router’s DHCP reservations or set the address in /etc/network/interfaces or netplan. For security, limit recursion to your subnet and block port 53 from the internet. Turn on DNSSEC validation in Unbound or BIND if you want validation of signed zones, and keep the machine patched.
The DNS setup I use is small and repeatable. For BIND, create /etc/bind/named.conf.local with a zone block for lab.local and a zone file at /etc/bind/db.lab. A minimal A record looks like this:
myhost IN A 192.168.1.10
For Unbound, run it as a caching resolver and forward unresolved queries to a trusted upstream or to root servers. After installing, run:
systemctl start bind9
or:
systemctl start unbound
Test from another machine with:
dig @192.168.1.5 myhost.lab A
dig @192.168.1.5 google.com
If dig returns the A record and a sensible response time, the DNS setup is working. If clients still use ISP DNS, check the DHCP settings or force a client to use the server by setting its DNS entry manually for testing.
Troubleshooting is usually one of three things: the server is firewalled, the zone file has a syntax error, or DHCP still points elsewhere. Check iptables or UFW for port 53 rules. Use:
named-checkzone
named-checkconf
for BIND to find file errors. For Unbound, check logs in /var/log/syslog or use:
unbound-control status
For maintenance, back up /etc/bind and /etc/unbound regularly and keep a copy off the device. Run a secondary read-only slave on another machine if uptime matters; BIND and many DNS servers support zone transfers to a slave. Add simple monitoring: a cron job that runs dig and alerts if the server fails to answer. For dynamic clients, set up RFC2136 updates so DHCP can update DNS automatically, or run a small script that posts updates with nsupdate.
If you want reliability, keep things small and predictable. Use a local resolver so name lookup does not depend on the internet. Give the server a static IP, lock recursion to the LAN, keep some logging, and run a secondary if you can. Keep configuration files in a git repo or a tarball and test restores on a spare VM. That leaves you with a service that is boring, but it just works. That is the point.




