Bind9 to NSD article

This commit is contained in:
Wxcafé (Clément Hertling) 2017-09-26 00:49:05 +02:00
parent ce10e0be36
commit b49c9228c3
2 changed files with 219 additions and 2 deletions

View File

@ -0,0 +1,217 @@
Title: From Bind9 to NSD, a (relatively short) DNS journey
Date: 2017-09-24T11:44+02:00
Author: Wxcafé
Category:
Slug: from_bind9_to_nsd_a_relatively_short_dns_journey
Hey! It's been a while...
I'm sorry, I've had a lot on my plate in august and at the beginning of
september.
Anyway. Recently (meaning, last week) I started having a bit of time on my hands
again, and as I had been planning for a few months I set to migrate my DNS
servers from Bind9 to NSD. There are a few reasons for that, mainly related to
how Bind has found itself in the subject line of several CVEs in the last few
months and that I wasn't using any of the thousand of features that Bind offers.
Okay, I'll admit that the "hype" around NSD/Unbound, if you can call it that,
played a bit of a role in the decision.
Anyways, my setup is pretty simple: I have two servers. Both are primary for
some zones and replicas for other zones, and one of them is behind a v4 NAT
(it's on my home network) and has to do recursive resolution in addition to
being an authoritative server. Both are IPv6-accessible.
So, the previous setup was a bind9 server on both, with a port-forwaring rule
for IPv4 for the server behind the NAT, and `allow-transfer {}` blocks instead
of keys to transfer the zones from the primary to the replica. It was pretty
ugly, but it worked fine and didn't have any glaring security problems (at
least, not that I could think of).
I set on moving the first part of the setup, which is the distant server (the
one that's not behind a NAT). The setup went like this:
```bash
$ sudo apt install nsd
$ sudo mkdir -p /etc/nsd/zones/{primary,replica}
$ sudo cp /etc/bind9/zones/primary/* /etc/nsd/zones/primary/
$ sudo vim /etc/nsd/nsd.conf
```
And here is the `nsd.conf` file:
```yaml
# NSD configuration file
server:
do-ip4: yes
ip4-only: no
hide-version: no
zonesdir: "/etc/nsd/zones/"
logfile: "/var/log/nsd.log"
pidfile: "/run/nsd/nsd.pid"
key:
name: "push-key"
algorithm: hmac-sha256
secret: "redacted"
pattern:
name: "copy-to"
notify: <other server's IP> push-key
provide-xfr: <other server's IP> push-key
pattern:
name: "copy-from"
allow-notify: <other server's IP> push-key
request-xfr: AXFR <other server's IP> push-key
# Primary Zones
zone:
name: wxcafe.net
zonefile: primary/wxcafe.net
include-pattern: "copy-to"
# [other zones ...]
# Replica zones
zone:
name: home.wxcafe.net
zonefile: replica/home.wxcafe.net
include-pattern: "copy-from"
# [other zones ...]
```
That should be pretty straightforward, but basically the first block defines
basic server options, the second one defines the push key and its settings, the
third and fourth define "patterns" that are repeatable configuration for zones,
and the rest are zone definitions.
Aaaaaand, that's it! Nothing more to do, everything works. Just
```bash
$ sudo systemctl stop bind9 && sudo systemctl disable bind9
$ sudo systemctl start nsd && sudo systemctl enable nsd
```
and you're done. Now, of course, since the other server isn't configured, the
replication doesn't actually happen yet. So let's configure the other server
then!
Well, we want it to do recursive resolving, so, since NSD doesn't do that, we're
gonna need to run Unbound too. So, to start off of course we need to install
Unbound so we're doing an `apt install unbound`. Then we start with the unbound
configuration:
```yaml
# Unbound configuration file for Debian.
include: "/etc/unbound/unbound.conf.d/*.conf"
server:
logfile: ""
interface: 0.0.0.0
access-control: 10.0.0.0/8 allow
```
That's it. That's all we have to do to configure Unbound. Now we start it and
enable it: `sudo systemctl start unbound && sudo systemctl enable unbound`, and
we're done with unbound
You'll notice that the server doesn't listen on v6. That's because it'd be
useless, since the DNS server is given to hosts on my network via DHCP, that
there's no v6-only hosts on my network, and that we're gonna play with the v6
port later in ways that would render the server inaccessible either way.
Anyways, it's now time to install and configure NSD on that server. Installation
is the same as earlier, and even the config file differs only a little bit:
```yaml
# NSD configuration file for Debian.
server:
do-ip4: yes
ip4-only: no
hide-version: no
zonesdir: "/etc/nsd/zones/"
logfile: "/var/log/nsd.log"
pidfile: "/run/nsd/nsd.pid"
port: 1053
remote-control:
control-enable: yes
control-interface: 127.0.0.1
control-port: 8952
server-key-file: "/etc/nsd/nsd_server.key"
server-cert-file: "/etc/nsd/nsd_server.pem"
control-key-file: "/etc/nsd/nsd_control.key"
control-cert-file: "/etc/nsd/nsd_control.pem"
key:
name: "push-key"
algorithm: hmac-sha256
secret: "redacted"
pattern:
name: "copy-to"
notify: <other server's ip> push-key
provide-xfr: <other server's ip> push-key
pattern:
name: "copy-from"
allow-notify: <other server's ip> push-key
request-xfr: AXFR <other server's ip> push-key
# Primary Zones
zone:
name: home.wxcafe.net
zonefile: primary/home.wxcafe.net
include-pattern: "copy-to"
# Replica zones
zone:
name: wxcafe.net
zonefile: replica/wxcafe.net
include-pattern: "copy-from"
```
As you can see, it's pretty similar, the only differences being that the primary
zones of the other server replicas on this one and vice-versa, and that the port
is 1053. This is the interesting part.
So, of course, since we now have two DNS servers running on the same host, one
is going to bind to port 53 and then the other one won't be able to. That's
problematic, obviously, since most hosts are going to do DNS queries on port 53
and I can't really change that. Since the authoritative part of this server is
behind a NAT, I can easily just port forward packets from the external IP's port
53 to any internal port, which is the obvious solution considering I have no
recourse changing which port internal hosts who get their DNS resolver through
DHCP query on.
Once I added the NAT port forwarding, there was still a small problem, tho...
external IPv6 hosts don't benefit from that port forward, they still get a reply
from Unbound (telling them they're not in the allowed range) instead of from
NSD.
To make that happen, I had to do something pretty ugly... a port forward in
IPv6. I used this `ip6tables` rule:
```
-A PREROUTING -p udp -m udp --dport 53 -j REDIRECT --to-ports 1053
```
YES, I KNOW, port forwarding in v6 is dirty, but right now it works! Next step
is moving each service (the authoritative name server and the recursive one) to
their own VM. For now, it works fine and was really easy to setup!
Hope that might be useful, or at least interesting, to you 😊! I'll be posting
a write-up of EuroBSDCon soon...-ish!
See ya!

View File

@ -91,8 +91,8 @@ cable and plugged it right in.
![closeup_serial](https://pub.wxcafe.net/img/10_closeup_serial.JPG)
This thing listens at 112500 bauds, instead of (the more usual) 9600. So just
start `screen /dev/ttyUSB0 112500` and it's all good. Then boot the thing.
This thing listens at 115200 bauds, instead of (the more usual) 9600. So just
start `screen /dev/ttyUSB0 115200` and it's all good. Then boot the thing.
You'll see a nice bootlog pass by, and then you'll be stuck without any response
to inputs.