Chroot NSD on Ubuntu Server 14.04

We’re going to mitigate some risks that are inherent when running a server by jailing our nsd authoritative name server into it’s own chroot and making sure it runs with the least privileges possible. This manual is split into two parts. The first part is what it’s all about when it comes to jailing your daemon. Luckily this is not a lot of work because nsd has builtin support for chroots. The second part serves as an example of where to put your zone files and how to include them in your configuration.

  1. Setup chroot
  2. Setup zone example.com

All commands should be executed as root.

1. Setup chroot

We’ll assume you have nsd installed, if not run apt-get install nsd.

Before we lock up the daemon into the jail we have to make sure it has some space where it can write out it’s thoughts. We’ll put the zone files in a different directory just to keep things clear.

1
2
3
4
# mkdir -m 775 /etc/nsd/db /etc/nsd/run /etc/nsd/run/xfr
# chgrp -R nsd /etc/nsd/db /etc/nsd/run
# chmod o-rwx /etc/nsd/run/xfr
# mkdir -m 755 /etc/nsd/zones

Create a logging socket in the chroot so that any complaints the daemon might have can be heard.

1
2
3
# mkdir -m 755 /etc/nsd/dev
# echo '$AddUnixListenSocket /etc/nsd/dev/log' > /etc/rsyslog.d/nsd.conf
# service rsyslog restart

Create a new config file in /etc/nsd/nsd.conf.d/local.conf that has pointers to the new writable locations and contains the instructions to chroot and drop privileges.

1
2
3
4
5
6
7
8
9
10
11
# cat > /etc/nsd/nsd.conf.d/local.conf <<EOF
server:
username: nsd
chroot: /etc/nsd
database: /etc/nsd/db/nsd.db
pidfile: /etc/nsd/run/nsd.pid
zonelistfile: /etc/nsd/db/zone.list
zonesdir: /etc/nsd/zones
xfrdfile: /etc/nsd/run/xfrd.state
xfrdir: /etc/nsd/run/xfr
EOF

Include the new config file and restart nsd.

1
2
# echo 'include: /etc/nsd/nsd.conf.d/local.conf' >> /etc/nsd/nsd.conf
# service nsd restart

At last pinch a hole in the firewall so it can communicate with the outside world.

1
# ufw allow from any to any port 53

Thanks to the fact that nsd has builtin support for chrooting this is all that comes to it.

2. Setup zone example.com

Now a chrooted authoritative name server without zones doesn’t make any sense, at all. I’ll show you how to link a zone by using an example. Say your name server is located at ns.example.net and it has to answer questions for example.com. Create a zone file for example.com in /etc/nsd/zones/example.com.zone.

1
2
3
4
5
6
7
# cat > /etc/nsd/zones/example.com.zone <<EOF
\$ORIGIN example.com.
\$TTL 86400
@ IN SOA ns.example.net. hostmaster.example.net. ( 2015033100 24h 2h 3W12h 2h20M )
IN NS ns.example.net.
www IN A 203.0.113.2
EOF

Add this zone to the configuration and restart nsd.

1
2
3
4
5
6
7
8
# cat >> /etc/nsd/nsd.conf.d/local.conf <<EOF

zone:
name: example.com
zonefile: example.com.zone
EOF

# service nsd restart

The new zone can be tested by using dig(1) to ask the name server the ip address of www.example.com.

1
2
$ dig @ns.example.net www.example.com +short
203.0.113.2

Well there you go. The name server at ns.example.net said that www.example.com is located at 203.0.113.2. You’ve chrooted the nsd daemon and setup an example zone. Once you’ve added all your zones you’re done.

Please contact me for any suggestions or criticism.