From DNSmasq to Unbound with DNSSEC and ISC's DHCP server.
Fiddling with dnsmasq
to enable DNSSEC for my LAN convinced me of replacing it with unbound
as DNS resolver and the ISC dhpcd
.
Network overview: WAN 192.168.1.0/24
, LAN 192.168.21.0/24
, the router's hostname is raspi
and its LAN IP 192.168.21.1
. The local domain is lan
.
$ apt-get install unbound unbound-host resolvconf isc-dhcp-server
After installing the necessary software, configure the unbound
DNS server for LAN and loopback device. As unbound
doesn't parse /etc/hosts
, any LAN hosts to be resolved need to be defined as local-data
.
### File: /etc/unbound/unbound.conf
#include: "/etc/unbound/unbound.conf.d/*.conf"
server:
interface: 0.0.0.0
access-control: 192.168.21.0/24 allow
do-ip6: no
verbosity: 1
auto-trust-anchor-file: "/var/lib/unbound/root.key"
local-zone: "lan" static
local-data: "raspi.lan. IN A 192.168.21.1"
local-data: "$HOSTNAME.lan. IN A 192.168.21.10"
local-data: "$HOSTNAME1.lan. IN A 192.168.21.11"
private-address: 192.168.21.0/24
private-domain: "lan"
forward-zone:
name: "."
forward-addr: $DNS_IP
forward-addr: $DNS_IP1
forward-addr: $DNS_IP2
The $HOSTNAME
s und $DNS_IP
s need to be defined.
Note: The OpenNIC DNS servers don't support DNSSEC yet. To improve the experience, you may want to add the line "harden-dnssec-stripped: no
" to the server configuration, which makes dnssec validation optional. Otherwise many sites will fail to resolve due to missing DNSSEC data.
To test the configuration, disable dnsmasq
's DNS by adding the line port=0
to /etc/dnsmaq.conf
and restart the daemon (we still need its dhcp), before starting unbound
:
$ /etc/init.d/dnsmasq restart
$ /etc/init.d/unbound start
$ /etc/init.d/resolvconf restart
Note: After rebooting my Raspberry Pi, the auto-trust-anchor-file
mechanism failed to verify the anchor, due to the lack of a hardware clock while openntpd
not yet being ready with setting the time - so unbound
failed to start. Adding openntpd
to the Required-Start section of unbound
's init script solves this issue, if openntpd
is run with the -s
flag set. For Devuan's SysV-Init:
### File: /etc/init.d/unbound:
# ...
# Required-Start: $network $remote_fs $syslog $openntpd
# ...
and
### File: /etc/default/openntpd:
DAEMON_OPTS="-s -f /etc/openntpd/ntpd.conf"
If DNS works for the router itself and on the LAN, it's time to turn towards the new DHCP server. A simple configuration as the only authoritative DHCP Server on one subnet and with two static leases - the "empty" subnet definition for the uplink saves some lines of daemon.log
:
### File: /etc/dhcp/dhcpd.conf
authoritative;
default-lease-time 7200;
max-lease-time 14400;
subnet 192.168.1.0 netmask 255.255.255.0 {
}
subnet 192.168.21.0 netmask 255.255.255.0 {
range 192.168.21.100 192.168.21.120;
option domain-name "lan";
option domain-name-servers 192.168.21.1;
}
host $HOSTNAME {
hardware ethernet 00:11:22:33:44:55;
fixed-address 192.168.21.10;
}
host $HOSTNAME1 {
hardware ethernet 01:11:22:33:44:55;
fixed-address 192.168.21.11;
}
Now fully disable dnsmasq
by setting ENABLED=0
in /etc/default/dnsmasq
and run
$ /etc/init.d/dnsmasq restart
$ /etc/init.d/isc-dhcp-server start
Any typos in the configuration? Be prepared to edit your workstations /etc/network/interfaces
when you now request a new DHCP lease!
When back on the network, you can test the DNSSEC authentication chain by running dig
from the dnsutils
package
$ dig com. SOA +dnssec | grep flags
(dig
's output, on the router as on its DHCP clients, should include the ad
flag.), respectively unbound-host
on the router itself:
$ unbound-host devuan.org -C /etc/unbound/unbound.conf -rd
Also nice to have is the DNSSEC/TLSA Validator Mozilla add-on by cz.nic.