How To... | Why not..? | Scripts | Patches |
Last update: 2020-08-14
OpenBSD comes with unbound(8) and nsd(8) in base. This post shows you how to combine these two tools to provide DNS for an internal network including an internal DNS zone.
In this first part you will configure nsd(8) as the authoritative name
server for forward and reverse lookup zones of your internal network.
I will call the forward zone example.net
and the reverse zone
2.0.192.in-addr.arpa
. The following entries belong into
/var/nsd/etc/nsd.conf
:
server:
hide-version: yes
ip-address: 127.0.0.1
server-count: 1
remote-control:
control-enable: yes
zone:
name: "example.net"
zonefile: "/var/nsd/zones/master/%s.dns"
zone:
name: "2.0.192.in-addr.arpa."
zonefile: "/var/nsd/zones/master/%s.dns"
The remote control tool nsd-control(8) let you send commands to the running nsd(8), e. g. to reread a changed zone file without restarting the whole daemon. You need to run a setup tool once to generate the certificates and keys for nsd-control(8):
$ doas nsd-control-setup
The next step is to write the zone files for nsd(8). First the forward
lookup zone example.net
:
$ORIGIN .
$TTL 3600 ; 1 hour
example.net IN SOA dns.example.net. admin.example.net. (
1 ; serial
86400 ; refresh (1 day)
3600 ; retry (1 hour)
604800 ; expire (1 week)
3600 ; minimum (1 hour)
)
NS dns.example.net.
$ORIGIN example.net.
dns A 192.0.2.11
router A 192.0.2.1
server A 192.0.2.80
www CNAME server
Save this zone file as /var/nsd/zones/master/example.net.dns
. Second,
the reverse lookup zone 2.0.192.in-addr.arpa.
:
$ORIGIN .
$TTL 3600 ; 1 hour
2.0.192.in-addr.arpa IN SOA dns.example.net. admin.example.net. (
1 ; serial
86400 ; refresh (1 day)
3600 ; retry (1 hour)
604800 ; expire (1 week)
3600 ; minimum (1 hour)
)
NS dns.example.net.
$ORIGIN 2.0.192.in-addr.arpa.
1 PTR router.example.net.
11 PTR dns.example.net.
80 PTR server.example.net.
Save this zone file as /var/nsd/zones/master/2.0.192.in-addr.arpa.dns
.
The configuration of unbound(8) I show you in this post turns unbound(8)
into a iterative, caching and validating resolver. The content of the
file /var/unbound/etc/unbound.conf
is:
server:
access-control: 192.0.2.0/24 allow
auto-trust-anchor-file: "/var/unbound/db/root.key"
do-not-query-localhost: no
domain-insecure: example.net
domain-insecure: 2.0.192.in-addr.arpa
hide-identity: yes
hide-version: yes
insecure-lan-zones: yes
interface: 192.0.2.11
local-zone: example.net nodefault
local-zone: 2.0.192.in-addr.arpa nodefault
num-threads: 1
prefetch: yes
private-domain: example.net
private-domain: 2.0.192.in-addr.arpa
qname-minimisation: yes
root-hints: "/var/unbound/db/root.hints"
remote-control:
control-enable: yes
control-interface: 192.0.2.11
stub-zone:
name: "example.net"
stub-addr: 127.0.0.1
stub-zone:
name: "2.0.192.in-addr.arpa"
stub-addr: 127.0.0.1
If the data in your zones changes very often you may consider setting
stub-no-cache: yes
for each of the affected stub zones. This disables
the caching for the zone it is set, making unbound always querying nsd
for the latest data.
The remote control tool unbound-control(8) let you send commands to the running unbound(8), e. g. to flush the cache without restarting the whole daemon. You need to run a setup tool once to generate the certificates and keys for unbound-control(8):
$ doas unbound-control-setup
Both nsd(8) and unbound(8) bring along a tool to check the configuration file before you start or reload the daemon. You should start with nsd(8):
$ doas nsd-checkconf
Any errors are reported, so no news are good news. You can go ahead and start nsd(8):
$ doas rcctl enable nsd
$ doas rcctl start nsd
Now repeat the dance for unbound(8). First check the configuration file for errors:
$ doas unbound-checkconf
unbound-checkconf: no errors in /var/unbound/etc/unbound.conf
Time to start unbound(8);
$ doas rcctl enable unbound
$ doas rcctl start unbound
If you want the server to use unbound(8) itself you must adapt resolv.conf(5) to use the IP address unbound(8) is listening on:
search example.net
nameserver 192.0.2.11
lookup file bind