Lock down your BIND setup to help contain potential security problems.
Due to BIND’s not-so-illustrious track record with regard to security, if you want to use it you’ll probably want to spend some time hardening your setup. One way to make running BIND a little safer is to run it inside a sandboxed environment [Hack #10]. This is easy to do with recent versions of BIND, since it natively supports running as a nonprivileged user within a chroot()
jail. All you need to do is set up the directory you’re going to have it chroot()
to and change the command you’re using to start
named to reflect this.
To begin, create a user and group to run named as (e.g., named). To prepare the sandboxed environment, you’ll need to create the appropriate directory structure. You can create the directories for such an environment within /named_chroot by running the following commands:
#mkdir /named_chroot
#cd /named_chroot
#mkdir -p dev etc/namedb/slave var/run
Next, you’ll need to copy your named.conf file and namedb directory to the sandboxed environment:
#cp /etc/named.conf /named_chroot/etc
#cp -a /var/namedb/* /named_chroot/etc/namedb
These commands assume you store your zone files in /var/namedb.
If you’re setting up BIND as a secondary DNS server, you will need to make the /named_chroot/etc/namedb/slave directory writable so that named can update the records it contains when it performs a domain transfer from the master DNS node:
# chown -R named:named /named_chroot/etc/namedb/slave
In addition, named will need to write its process ID (PID) file to /named_chroot/var/run, so you’ll have to make this directory writable by the named user as well:
# chown named:named /named_chroot/var/run
Now, create the device files that named will need to access after it has called chroot()
:
#cd /named_chroot/dev
#ls -la /dev/null /dev/random
crw-rw-rw- 1 root root 1, 3 Jan 30 2003 /dev/null crw-r--r-- 1 root root 1, 8 Jan 30 2003 /dev/random #mknod null c 1 3
#mknod random c 1 8
#chmod 666 null random
You’ll also need to copy your time zone file from /etc/localtime to /named_chroot/etc/localtime. Additionally, named usually uses /dev/log to communicate its log messages to syslogd. Since this doesn’t exist inside the sandboxed environment, you will need to tell
syslogd to create a socket that the chroot()
-ed named
process can write to. You can do this by modifying your syslogd startup command and adding -a /named_chroot/dev/log
to it. Usually, you can do this by modifying an existing file in /etc.
For instance, under Fedora, edit /etc/sysconfig/syslogd and modify the SYSLOGD_OPTIONS
line to read:
SYSLOGD_OPTIONS="-m 0 -a /named_chroot/dev/log"
Or, if you’re running FreeBSD, modify the syslogd_flags
line in /etc/rc.conf:
syslogd_flags="-s -a /named_chroot/dev/log"
After you restart syslogd, you should see a log socket in /named_chroot/dev.
Now, to start named, all you need to do is run this command:
# named -u named -t /named_chroot
Other tricks for increasing the security of your BIND installation include limiting zone transfers to your slave DNS servers and altering the response to BIND version queries. Restricting zone transfers ensures that random attackers will not be able to request a list of all the hostnames for the zones hosted by your name servers. You can globally restrict zone transfers to certain hosts by putting an allow-transfer
section within the options
section in your named.conf.
For instance, if you want to restrict transfers on all zones hosted by your DNS server to only 192.168.1.20 and 192.168.1.21, you can use an allow-transfer
section like this:
allow-transfer { 192.168.1.20; 192.168.1.21; };
If you don’t want to limit zone transfers globally and instead want to specify the allowed hosts on a zone-by-zone basis, you can put the allow-transfer
section inside the zone
section.
Before an attacker attempts to exploit a BIND vulnerability, she will often scan for vulnerable versions of BIND by connecting to name servers and performing a version query. Since you should never need to perform a version query on your own name server, you can modify the reply BIND sends to the requester. To do this, add a version
statement to the options
section in your named.conf:
version "SuperHappy DNS v1.5";
This statement doesn’t really provide extra security, but if you don’t want to advertise what software and version you’re running to the entire world, you don’t have to.
Also, if you’re running a publicly facing name server that is used to serve zones, you’ll want to disable recursion. Otherwise, your server could be used in a
denial of service (DoS) attack. To disable recursion, you’ll need to add a recursion
statement to the options
section of named.conf:
recursion no;
You should allow recursion only on servers where you have a reasonable level of trust in the clients that can query it, such as an internal name server on your network.