Some tech documentation and snippets, finally organized.

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, LAN, the router's hostname is raspi and its LAN IP 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"

    access-control: 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"
    local-data:             "$HOSTNAME.lan. IN A"
    local-data:             "$HOSTNAME1.lan. IN A"
    private-domain:         "lan"

    name:                   "."
    forward-addr:           $DNS_IP
    forward-addr:           $DNS_IP1
    forward-addr:           $DNS_IP2

The $HOSTNAMEs und $DNS_IPs 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
# ...


### 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

default-lease-time 7200;
max-lease-time 14400;

subnet netmask {

subnet netmask {
option domain-name "lan";
option domain-name-servers;

host $HOSTNAME {
hardware ethernet 00:11:22:33:44:55;

host $HOSTNAME1 {
hardware ethernet 01:11:22:33:44:55;

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 -C /etc/unbound/unbound.conf -rd

Also nice to have is the DNSSEC/TLSA Validator Mozilla add-on by cz.nic.