Home DNS with Unbound and NSD 12 Nov 2023
I recently redid the DNS on my home network, moving from dnsmasq to Unbound and NSD. Unbound acts as the DNS server the network uses, and Unbound hosts losts local zones for my search domains. For reasons, this is really across two sites: our home, and a barn we own a few miles away. Because I am a dork, I have things at both sites :-)
My network controller has a built in DNS server which assigns a local domain, a la
brians-laptop.local to anything which gets a DHCP lease. I wanted to be able to respect these, but also assign a diferent domain to statically assigned things on the network, such as printers and our NAS. For these I set up a
.barn respectively, for things in the home and in the barn. Those zones are hosted on NSD, with a config like:
# /usr/local/etc/nsd/nsd.conf server: ip-address: 127.0.0.1 port: 53530 zone: name: home zonefile: "home.zone" zone: name: barn zonefile: "barn.zone"
Note that NSD is only listening on
127.0.0.1 and on port 53530. It should only ever be queried from the unbound instance on the same host (which is using port 53).
The zone files referenced are just stubs, not really correct, but they don't need to be :-)
; /usr/local/etc/nsd/home.zone $ORIGIN home. ; 'default' domain as FQDN for this zone $TTL 600 ; default time-to-live for this zone home. IN SOA ns.home. noc.dns.icann.org. ( 16 ;Serial 7200 ;Refresh 3600 ;Retry 1209600 ;Expire 3600 ;Negative response caching TTL ) ; The nameserver that are authoritative for this zone. NS ns.home. nas.home. A 192.168.2.114 printer.home. A 192.168.2.140 m0001.home. A 192.168.2.101 m0002.home. A 192.168.2.102
and the barn:
$ORIGIN barn. ; 'default' domain as FQDN for this zone $TTL 600 ; default time-to-live for this zone barn. IN SOA ns.barn. noc.dns.icann.org. ( 17 ;Serial 7200 ;Refresh 3600 ;Retry 1209600 ;Expire 3600 ;Negative response caching TTL ) ; The nameserver that are authoritative for this zone. NS ns.barn. m0003.barn. A 192.168.81.101 m0004.barn. A 192.168.81.102 dvr.barn. A 192.168.81.110
With NSD up and running, I set up Unbound to make use of those local zones. It runs on the same instance as NSD, and is configured ot use it for those domains:
# /usr/local/etc/unbound/unbound.conf server: # This is a CARP interface, which apparently # requires explicitely listing interface: 192.168.2.100 interface: 0.0.0.0 do-not-query-localhost: no access-control: 192.168.0.0/16 allow local-zone: "home" nodefault domain-insecure: "home" local-zone: "barn" nodefault domain-insecure: "barn" stub-zone: name: "home." stub-addr: 127.0.0.1@53530 stub-zone: name: "barn." stub-addr: 127.0.0.1@53530 forward-zone: name: "local." forward-addr: 192.168.1.1
Unbound is set up to listen on all interfaces, but because I am using a CARP interface as well, it seems to require seperately listing that one to avoid confusions. The two local zones are configured to be insecure (no DNSSEC) and to forward to the NSD instance as a
stub-zone for each domain, respectively.
The dynamically assigned
.local domain is forwarded to the router to pick up the names of things which get DHCP leases via the
Finally, to make it all work, I hand out three search domains on DHCP,
.barn. This is DHCP code 119 with a value
local,home,barn, for future reference.
Deployment wise, this is running on two servers in each location, with each server running both NSD and Unbound. The CARP interface is used to provide a single IP address for the DNS servers, and the DHCP server is configured to hand out that IP address as the DNS server for the network.
Fun fact along the way: I learned emacs has a mode for zone files which automatically increments
serial when you save. Handy!