Table of Contents

Chrooting BIND9 in Debian

 apt-get install bind9

For security reasons we want to run BIND chrooted so we have to do the following steps:

 /etc/init.d/bind9 stop

Edit the file /etc/default/bind9 so that the daemon will run as the unprivileged user 'bind', chrooted to /var/lib/named. Modify the line: OPTS=“-u bind” so that it reads OPTS=“-u bind -t /var/lib/named”:

 OPTIONS="-u bind -t /var/lib/named"

Create the necessary directories under /var/lib:

 mkdir -p /var/lib/named/etc
 mkdir /var/lib/named/dev
 mkdir -p /var/lib/named/var/cache/bind
 mkdir -p /var/lib/named/var/run/bind/run

Then move the config directory from /etc to /var/lib/named/etc:

 mv /etc/bind /var/lib/named/etc

Create a symlink to the new config directory from the old location (to avoid problems when bind is upgraded in the future):

 ln -s /var/lib/named/etc/bind /etc/bind

Make null and random devices, and fix permissions of the directories:

 mknod /var/lib/named/dev/null c 1 3
 mknod /var/lib/named/dev/random c 1 8
 chmod 666 /var/lib/named/dev/null /var/lib/named/dev/random
 chown -R bind:bind /var/lib/named/var/*
 chown -R bind:bind /var/lib/named/etc/bind

We need to modify the startup script /etc/init.d/sysklogd of sysklogd so that we can still get important messages logged to the system logs. Modify the line: SYSLOGD=“” so that it reads: SYSLOGD=“-a /var/lib/named/dev/log”:

Debian Lenny++ users that uses rsyslogd:
# Tell rsyslog to listen for log events in the chroot:
# vi /etc/rsyslog.d/bind-chroot.conf

and add the line:

$AddUnixListenSocket /var/lib/named/dev/log

 #! /bin/sh
 # /etc/init.d/sysklogd: start the system log daemon.
 
 PATH=/bin:/usr/bin:/sbin:/usr/sbin
 
 pidfile=/var/run/syslogd.pid
 binpath=/sbin/syslogd
 
 test -x $binpath || exit 0
 
 # Options for start/restart the daemons
 #   For remote UDP logging use SYSLOGD="-r"
 #
 SYSLOGD="-a /var/lib/named/dev/log"
 create_xconsole()
 {
     if [ ! -e /dev/xconsole ]; then
         mknod -m 640 /dev/xconsole p
     else
         chmod 0640 /dev/xconsole
     fi
     chown root:adm /dev/xconsole
 }
 
 running()
 {
     # No pidfile, probably no daemon present
     #
     if [ ! -f $pidfile ]
     then
         return 1
    fi

     pid=`cat $pidfile`
 
     # No pid, probably no daemon present
     #
     if [ -z "$pid" ]
     then
        return 1
     fi

     if [ ! -d /proc/$pid ]
     then
         return 1
     fi
 
     cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"|head -n 1`
 
     # No syslogd?
     #
     if [ "$cmd" != "$binpath" ]
     then
         return 1
     fi
 
     return 0
 }

 case "$1" in
   start)
     echo -n "Starting system log daemon: syslogd"
     create_xconsole
     start-stop-daemon --start --quiet --exec $binpath -- $SYSLOGD
     echo "."
     ;;
   stop)
     echo -n "Stopping system log daemon: syslogd"
     start-stop-daemon --stop --quiet --exec $binpath --pidfile $pidfile
     echo "."
    ;;
  reload|force-reload)
    echo -n "Reloading system log daemon: syslogd"
    start-stop-daemon --stop --quiet --signal 1 --exec $binpath --pidfile $pidfile
    echo "."
    ;;
  restart)
    echo -n "Restarting system log daemon: syslogd"
    start-stop-daemon --stop --quiet --exec $binpath --pidfile $pidfile
    sleep 1
    start-stop-daemon --start --quiet --exec $binpath -- $SYSLOGD
    echo "."
    ;;
  reload-or-restart)
    if running
    then
        echo -n "Reloading system log daemon: syslogd"
        start-stop-daemon --stop --quiet --signal 1 --exec $binpath --pidfile $pidfile
    else
         echo -n "Restarting system log daemon: syslogd"
         start-stop-daemon --start --quiet --exec $binpath -- $SYSLOGD
    fi
    echo "."
  ;;
  *)
    echo "Usage: /etc/init.d/sysklogd {start|stop|reload|restart|force-reload|reload-or-restart}"
    exit 1
esac

exit 0

Restart the logging daemon:

 /etc/init.d/sysklogd restart

Start up BIND, and check /var/log/syslog for any errors:

 /etc/init.d/bind9 start

Ubuntu troubleshooting

you might get this kind of errors in syslog

f syslog

1 gauloises kernel: [180942.452046] audit(1217451274.744:5): type=1503 operation="inode_permission" requested_mask="::r" denied_mask="::r" name="/var/chroot/named/etc/localtime" pid=14130 profile="/usr/sbin/named" namespace="default"
1 gauloises kernel: [180942.453222] audit(1217451274.748:6): type=1503 operation="inode_permission" requested_mask="::r" denied_mask="::r" name="/var/chroot/named/etc/localtime" pid=14130 profile="/usr/sbin/named" namespace="default"
1 gauloises named: none:0: open: /etc/bind/named.conf: permission denied
1 gauloises named: loading configuration: permission denied
1 gauloises kernel: [180942.460655] audit(1217451274.756:7): type=1503 operation="inode_permission" requested_mask="::r" denied_mask="::r" name="/var/chroot/named/etc/localtime" pid=14131 profile="/usr/sbin/named" namespace="default"
1 gauloises kernel: [180942.460761] audit(1217451274.756:8): type=1503 operation="inode_permission" requested_mask="r::" denied_mask="r::" name="/var/chroot/named/etc/bind/named.conf" pid=14131 profile="/usr/sbin/named" namespace="default"
1 gauloises kernel: [180942.460812] audit(1217451274.756:9): type=1503 operation="inode_permission" requested_mask="::r" denied_mask="::r" name="/var/chroot/named/etc/localtime" pid=14131 profile="/usr/sbin/named" namespace="default"
1 gauloises kernel: [180942.461179] audit(1217451274.756:10): type=1503 operation="inode_permission" requested_mask="::r" denied_mask="::r" name="/var/chroot/named/etc/localtime" pid=14131 profile="/usr/sbin/named" namespace="default"
1 gauloises kernel: [180942.461221] audit(1217451274.756:11): type=1503 operation="inode_permission" requested_mask="::r" denied_mask="::r" name="/var/chroot/named/etc/localtime" pid=14131 profile="/usr/sbin/named" namespace="default"

Work-around

Here's my /etc/apparmor.d/usr.sbin.named file. I've noted where I think the changes should be made.

f /etc/apparmor.d/usr.sbin.named


#include <tunables/global>

/usr/sbin/named {
  #include <abstractions/base>
  #include <abstractions/nameservice>

  capability net_bind_service,
  capability setgid,
  capability setuid,
  capability sys_chroot,

  # /etc/bind should be read-only for bind
  # /var/lib/bind is for dynamically updated zone (and journal) files.
  # /var/cache/bind is for slave/stub data, since we're not the origin of it.
  # See /usr/share/doc/bind9/README.Debian.gz

### Changing these to the chroot location is part of the solution. ###
  /etc/bind/** r,
  /var/lib/bind/** rw,
  /var/cache/bind/** rw,
###

# added 20080914 --amj to give named access to log file
  /var/log/named.log w,

### As are these, but I haven't tinkered with them yet ###
  /proc/net/if_inet6 r,
  /usr/sbin/named mr,
  /var/run/bind/run/named.pid w,
  # support for resolvconf
  /var/run/bind/named.options r,
###
}
 # /etc/init.d/apparmor restart
     Reloading AppArmor profiles : done.

and then restart BIND