I l@ve RuBoard Previous Section Next Section

Hack 76 Running BIND in a chroot Jail

figs/moderate.giffigs/hack76.gif

Keep your named isolated from the rest of the system with the judicious use of chroot

The vast majority of the Internet relies on BIND for its name resolution needs. While tremendous effort has gone toward shoring up potential security holes in BIND, you can never be absolutely certain that any code is completely free of possible exploits. To minimize the possible damage done by remote root exploits (due to buffer overflows, bugs, or misconfiguration), many sites choose to run their named service in a chroot jail. This helps ensure that even if the named process is compromised, the attacker's job won't be finished yet. While a chroot jail isn't necessarily impenetrable, it poses a very difficult challenge for a would-be system cracker.

These steps outline the minimum effort required to get BIND 9 running in a chroot jail. DNS security is a large and complex issue, and should be taken very seriously. Consult the resources at the end of this hack for more information.

To begin with, we'll want to run named as some user other than root. Create a named user and group that will only be used for running the named process:

root@gemini:~# groupadd -g 53 named
root@gemini:~# useradd -u 53 -g named -c "chroot BIND user" \
  -d /var/named/jail -m named

We'll instruct named to chroot to /var/named/jail at startup. We will need to create enough of a skeleton file structure under this directory to allow named to start normally. Create the /var structure, and copy your DNS data into it:

root@gemini:~# cd ~named
root@gemini:/var/named/jail# mkdir -p var/{run,named}
root@gemini:/var/named/jail# cp -Rav /var/named/data var/named/

If you act as a slave for any zones, then the named process will need write access to a directory (to keep track of updated slave data). Create a directory specifically for slave data, independent of your regular data files:

root@gemini:/var/named/jail# mkdir var/named/slave
root@gemini:/var/named/jail# chown named.named var/named/slave

Next, create the dev/ and etc/ directories, and copy the critical system files and devices to them:

root@gemini:/var/named/jail# mkdir {dev,etc}
root@gemini:/var/named/jail# cp -av /dev/{null,random} dev/
root@gemini:/var/named/jail# cp -av \
  /etc/{localtime,named.conf,rndc.key} etc/

Clean up the ownership and permissions of these directories:

root@gemini:/var/named/jail# chown root.root .
root@gemini:/var/named/jail# chmod 0755 .
root@gemini:/var/named/jail# chown named.named var/named/data/
root@gemini:/var/named/jail# chmod 0700 var/named/data/
root@gemini:/var/named/jail# chown named.named var/run/

If you're using syslog for your DNS logs, you'll need to add a switch like this to your syslogd startup rc. It will tell syslog to listen on that socket as well (which is needed since the system's /dev/log won't be reachable from inside the jail):

syslogd -m 0 -a /var/named/jail/dev/log

If you're using filesystem logs, you won't need to change your syslogd configuration. Just be sure that the log files are writable by the named user, and that your log directory exists under /var/named/jail/.

Finally, fire up named, passing the username, chroot directory, and initial configuration file on the command line:

root@gemini:~# /usr/sbin/named -u named -t /var/named/jail \
  -c /etc/named.conf

If your named doesn't start cleanly, take a look at the system's /var/log/syslog or /var/log/messages, and track down the source of the trouble. It can be tricky to be sure that your permissions are all what they need to be. Here's a sample recursive ls output from a machine with a running chroot'd BIND:

root@gemini:/var/named/jail# ls -lR
.:
total 12
drwxr-xr-x 2 root root 4096 Sep 20 12:45 dev/
drwxr-xr-x 2 root root 4096 Sep 20 13:08 etc/
drwxr-xr-x 5 root root 4096 Sep 20 13:04 var/

./dev:
total 0
crw-rw-rw- 1 root root 1, 3 Jul 17 1994 null
crw-r--r-- 1 root root 1, 8 Dec 11 1995 random

./etc:
total 16
-rw-r--r-- 1 root root 1017 Sep 20 12:46 localtime
-r--r--r-- 1 root root 1381 Sep 20 13:08 named.conf
-rw------- 1 root root 77 Sep 11 04:22 rndc.key

./var:
total 12
drwxr-xr-x 4 root root 4096 Sep 20 13:01 named/
drwxr-xr-x 2 named named 4096 Sep 20 13:15 run/

./var/named:
total 8
drwx------ 3 named named 4096 Sep 20 13:03 data/
drwxr-xr-x 2 named named 4096 Sep 20 12:43 slave/

./var/named/data:
total 42
-rw-r--r-- 1 root root 381 Apr 30 16:32 localhost.rev
-rw-r--r-- 1 root root 2769 Sep 20 13:03 named.ca
-r--r--r-- 1 root root 1412 Sep 17 16:44 nocat.net

./var/named/slave:
total 0

./var/run:
total 4
-rw-r--r-- 1 named named 6 Sep 20 13:15 named.pid

A chroot'd environment can help keep daemons sequestered away from the rest of a running system, but they're not a magic bullet for instant system security. This hack should get you started, but be sure to read up on the complexities of using and running BIND.

76.1 See also:

    I l@ve RuBoard Previous Section Next Section