Unbound configuration for LAN

unbound

As stated in the OpenBSD manual, unbound is a DNS validating resolver. It could be used to resolve local LAN names providing an answer for a DNS query and the reverse operation. Unbound is installed by default since it is part of the base OpenBSD installation. The user can proceed to configure it using:

$ doas vim /var/unbound/etc/unbound.conf

Note: The character '#' always starts a comment from its position to end of the line.

# $OpenBSD: unbound.conf,v 1.21 2020/10/28 11:35:58 sthen Exp $

server:
        use-syslog: yes
        verbosity: 4
        prefetch: yes
        interface: 0.0.0.0
        do-ip4: yes
        do-ip6: no
        do-udp: yes
        do-tcp: yes
        access-control: 0.0.0.0/0 refuse        # block all users by default
        access-control: 192.168.254.0/24 allow  # allow users on the internal network to use unbound
        access-control: 127.0.0.0/8 allow       # allow localhost to use unbound
        hide-identity: yes
        hide-version: yes
        do-not-query-localhost: no
        private-address: 192.168.254.0/24
        private-domain: "homelab.local"
        private-domain: "254.168.192.in-addr.arpa"
        domain-insecure: "homelab.local"
        unblock-lan-zones: yes
        insecure-lan-zones: no

        local-zone: "home.local." static
        local-data: "ALPHA.home.local IN A 10.0.0.1"
        local-data: "BETA.home.local IN A 10.0.0.2"
        local-data: "GAMMA.home.local IN A 10.0.0.3"
        local-data: "DELTA.home.local IN A 10.0.0.4"

        local-data-ptr: "10.0.0.1 ALPHA.home.local"
        local-data-ptr: "10.0.0.2 BETA.home.local"
        local-data-ptr: "10.0.0.3 GAMMA.home.local"
        local-data-ptr: "10.0.0.4 DELTA.home.local"

remote-control:
        control-enable: yes
        control-interface: /var/run/unbound.sock

forward-zone:
        name: "."                               # use for ALL queries
        forward-addr: 208.67.222.222
        forward-addr: 208.67.220.220
        forward-addr: 8.8.8.8

Let's comment single sections in the above file. First of all there's the server: section. It is a general config entry for which the user can specify daemon behavior and so on:

use-syslog: yes - tells to unbound daemon to send to syslog facility. The default is to send logs to syslog.

verbosity: 4 - spans from 0 to 5, 1 is the default. A 0 value disable verbosity and only errors will be displayed.

prefetch: yes - with yes the messages in cache are fetched before they expire in order to keep the cache always updated.

interface: 0.0.0.0 - the unbound daemon will listen on all available interfaces.

do-ip4: yes - enable the IPv4 queries. Default is yes.

do-ip6: no - disable the IPv6 queries. Default is yes.

do-udp: yes and do-tcp: yes - enable respectively the udp and tcp queries. Default is yes for both.

access-control: <address>/<size> <action> - These three access control settings set how the unbound daemon has to respond to queries. The first, access-control: 0.0.0.0/0 refuse - blocks all users to the query system by default. The second, access-control 192.168.254.0/24 allow - allow users on the network 192.168.254.0/24 to query the daemon. Finally the third configuration, access-control: 127.0.0.1/8 allow - tells unbound daemon to allow queries coming from localhost.

hide-identity: yes and hide-version: yes - the first block id.server and hostname.bind queries. The second blocks version.server and version.bind queries.

do-not-query-localhost: no - enables localhost to send queries.

private-address: 10.0.0.0/24 - specifies the LAN address space where public internet could not access LAN names.

private-domain: "0.0.10.in-addr.arpa" - this domain is allowed with all its subdomains.

domain-insecure: "home.local" - set the home.local domain to be insecure.

unblock-lan-zones: yes - the reverse lookup for the names are not restricted for private address space.

insecure-lan-zones: no - reverse lookups in private address space are validated.

This group of keywords repeats for every host in the LAN, for example:

local-zone "home.local." static local-data: "ALPHA.home.local IN A 10.0.0.1" local-data-ptr:"10.0.0.1 ALPHA.home.local

local-zone "home.local." static local-data: "BETA.home.local IN A 10.0.0.2" local-data-ptr:"10.0.0.2 BETA.home.local

...

remote-control: - if configured the unbound-control utility can be used to send commands to the server.

control-enable: yes - enable the access to unbound-control utility

control-interface: /var/run/unbound.sock - the socket to send command to the unbound server.

forward-zone: - catch-all configuration. Each clause specifies the target server for the queries to other servers (DNS).

name: "." - all servers.

The group of keywords configures the external DNS server:

forward-addr: 208.67.222.222 forward-addr: 208.67.220.220 forward-addr: 8.8.8.8

After edited unbound.conf, /etc/resolv.conf should be edited too:

nameserver 127.0.0.1
lookup file bind

the unbound server must enabled and then started:

$ rcctl enable unbound
$ rcctl start unbound

Let's try it with dig. Note that the unbound server has LAN ip equals to 10.0.0.200 in this example. We can use another PC connected in the same LAN, then:

$ dig @10.0.0.200 ALPHA

; <<>> dig 9.10.8-P1 <<>> @10.0.0.200 ALPHA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 27611
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;ALPHA.                         IN      A

;; AUTHORITY SECTION:
.                       3600    IN      SOA     a.root-servers.net. nstld.verisign-grs.com. 2024053000 1800 900 604800 86400

;; Query time: 4 msec
;; SERVER: 10.0.0.200#53(10.0.0.200)
;; WHEN: Thu May 30 14:29:41 CEST 2024
;; MSG SIZE  rcvd: 116

See also:

$ man unbound.conf