From Bind to nsd and unbound on OpenBSD 5.6
652 words, 4 minutes
I’ve been using Bind as a primary, slave or cache name server for all my IT life. But it seems Bind is being kicked out of OpenBSD. So far so good, I’m gonna use what’s provided by my favorite OS to do the job.
Here’s how to use nsd and unbound daemons to serve as an internal authoritative DNS nameserver and DNS resolver. Both will be running on the same machine.
The system
The server will be running OpenBSD 5.6 amd64. It ships with native nsd and unbound daemons. So since you install the OS, you get the toys.
# uname -a
OpenBSD cheetara.tumfatig.net 5.6 GENERIC.MP#333 amd64
# nsd -v
NSD version 4.0.3
# unbound -dv
[1424036203] unbound[24599:0] notice: Start of unbound 1.4.22.
The authoritative DNS nameserver
I’ll run both authoritative and resolver on the same host. I could either use different IP adresses and/or ports. Since I only have one authoritative nameserver, I don’t care using unusual ports. So I choose to use same IP and different ports. Only the resolver with query the authoritative nameserver.
Tell OpenBSD to start nsd on boot:
# vi /etc/rc.conf.local
(...)
nsd_flags=""
(...)
Then edit the configuration file. The daemon will “bind” on port 8053 for all IPv4 adresses. I have 3 authoritative zones for which I want to use private name resolution.
# vi /var/nsd/etc/nsd.conf
server:
hide-version: yes
ip-address: 0.0.0.0@8053
remote-control:
control-enable: yes
zone:
name: "tumfatig.net"
zonefile: "tumfatig.net"
zone:
name: "carnat.net"
zonefile: "carnat.net"
zone:
name: "192.in-addr.arpa"
zonefile: "192.in-addr.arpa"
The zone files are stored in /var/nsd/zones/
. Zones files are compatible with
Bind format so you can simply scp them ; or use AXFR ; or write from scratch.
The file name is the one referenced in the “zonefile” parameter.
That’s it. Just start the daemon and you’re done.
# /etc/rc.d/nsd start
nsd(ok)
# nsd-control status
version: 4.0.3
verbosity: 0
ratelimit: 200
# nsd-control zonestatus tumfatig.net
zone: tumfatig.net
state: master
# nsd-control zonestatus openbsd.org
error zone openbsd.org not configured
The DNS resolver
The DNS resolver is the daemon that will query the DNS world on behalf of my LAN’s DNS clients. It’ll use Internet root DNS servers for general queries. For my “private” DNS zones, it will query the authoritative DNS nameserver previously created.
Tell the system that unbound will have to be launched at boot time:
# vi /etc/rc.conf.local
(...)
unbound_flags=""
(...)
Then edit the configuration file. The daemon will listen on every IP adresses, usual port. It will be told to use the local nsd daemon for my private zones.
# vi /var/unbound/etc/unbound.conf
server:
interface: 0.0.0.0
interface: ::0
access-control: 192.168.0.0/24 allow
access-control: 127.0.0.0/8 allow
access-control: ::0/0 refuse
access-control: ::1 allow
hide-identity: yes
hide-version: yes
auto-trust-anchor-file: "/var/unbound/db/root.key"
local-zone: "168.192.in-addr.arpa." nodefault
remote-control:
control-enable: yes
control-interface: 127.0.0.1
control-interface: ::0
stub-zone:
name: "tumfatig.net"
stub-addr: 192.168.0.60@8053
stub-zone:
name: "carnat.net"
stub-addr: 192.168.0.60@8053
stub-zone:
name: "0.168.192.in-addr.arpa."
stub-addr: 192.168.0.60@8053
Control keys are to be created to enable remote management:
# unbound-control-setup
setup in directory /var/unbound/etc
generating unbound_server.key
(...)
generating unbound_control.key
(...)
create unbound_server.pem (self signed certificate)
create unbound_control.pem (signed client certificate)
(...)
Setup success. Certificates created. Enable in unbound.conf file to use
By default, those keys are used if they exists. So there’s nothing more to do.
That’s all. Now start the daemon and enjoy:
# /etc/rc.d/unbound start
unbound(ok)
# unbound-control status
version: 1.4.22
verbosity: 1
threads: 1
modules: 2 [ validator iterator ]
uptime: 8 seconds
unbound (pid 5712) is running...
# unbound-control list_stubs
. IN stub prime: M.ROOT-SERVERS.NET. L.ROOT-SERVERS.NET. K.ROOT-SERVERS.NET. J.ROOT-SERVERS.NET. I.ROOT-SERVERS.NET. H.ROOT-SERVERS.NET. G.ROOT-SERVERS.NET. F.ROOT-SERVERS.NET. E.ROOT-SERVERS.NET. D.ROOT-SERVERS.NET. C.ROOT-SERVERS.NET. B.ROOT-SERVERS.NET. A.ROOT-SERVERS.NET. 2001:dc3::35 2001:500:3::42 2001:7fd::1 2001:503:c27::2:30 2001:7fe::53 2001:500:1::803f:235 2001:500:2f::f 2001:500:2d::d 2001:503:ba3e::2:30 202.12.27.33 199.7.83.42 193.0.14.129 192.58.128.30 192.36.148.17 128.63.2.53 192.112.36.4 192.5.5.241 192.203.230.10 199.7.91.13 192.33.4.12 192.228.79.201 198.41.0.4
carnat.net. IN stub noprime: 192.168.0.60
tumfatig.net. IN stub noprime: 192.168.0.60
168.192.in-addr.arpa. IN stub noprime: 192.168.0.60
So far, it took only a few couple of minutes to set this up.
Later on, I’ll dig around statistics for those ; and how to draw pretty
graphics out of them.
Cheers!