Hardening the BIND DNS Server - Page 3

This paper presents the risks posed by an insecure DNS server and walks through compiling, installing, configuring and optionally, chroot'ing BIND 8. The test environment is Solaris 2.5, 2.6, 7 and 8. Many configuration and troubleshooting tips are provided, along with up-to-date references on BIND and alternatives for NT, Linux and Solaris.

 By Sean Boran
Page 3 of 5   |  Back to Page 1
Print Article

Copying BIND to the Jail

We assume bind was already in /usr/local, so copy the BIND files over from there:

cd $jail; 
mkdir -p usr/local/{bin,lib,sbin,bind,etc}
cd $jail/usr/local/sbin;
(cd /usr/local/sbin; tar cf - dnskeygen named* irpd ndc ) |tar xvf -
cd $jail/usr/local/bin;
(cd /usr/local/bin; tar cf - dnsquery dig host nslookup nsupdate) |tar xvf -
cd $jail/usr/local;
cp /usr/local/etc/named.conf etc;
(cd /usr/local; tar cf - bind) |tar xvf -

Your DNS data can be located in several directories; here we present two examples. The location is specified in named.conf.

1. Data in /etc/named/

mkdir -p $jail/etc/named;  cd $jail/etc/named;
(cd /etc/named; tar cf - * ) | tar xvf -

2. or DNS data in /var/named (my preference)

cd $jail/var/named;
(cd /var/named; tar cf - * ) | tar xvf -

Next, set permissions on files, so that root owns files and named can read all files and write some files. And, disable any SUID/SGID files.
The PID file is put in /var/run and not /usr/local, because we don't want the named user to be able to write to /usr/local/etc (and hence named.conf). The location of the PID file is specified in named.conf.

cd $jail
chmod -R g-w var;
chmod -R a-w opt usr
chmod g+w var/run var/log
chgrp named var/log var/run;
touch var/log/all.log var/run/named.pid;
/usr/ucb/chown named.named
var/log/all.log var/run/named.pid;
chgrp named $jail/usr/local/etc;
/usr/ucb/chown root.named $jail/usr/local/etc/named.conf;
find . -type f -exec chmod ug-s {} \;

See the eighth footnote 8 for an example of an "ls -alR" on a production DNS primary.

Edit DNS config file: if the PID or data location has changed from your original installation, then $jail/usr/local/etc/named.conf needs to be adapted (see also the section BIND Configuration Notes).

Starting BIND

The chroot environment is set up and BIND is installed, so the current (non-chroot'ed) BIND can be stopped and the new one started.

  1. Set up a tail on the (syslog) logs, to watch BIND activity:
    tail -f local0log | grep server1
    The logs may be in /var/adm/messages or on a remote server, depending on your /etc/syslog.conf configuration. In this example, a centralized server collects logs and we look for messages from server1 (my test server).
  2. Stop the existing BIND...
    On Solaris 2.7: kill `pgrep named`
    On Solaris 2.5/6: ps -ef |grep named   then kill the appropriate PID.
  3. Start BIND chroot'ed:
    /usr/sbin/chroot /home/dns /usr/local/sbin/named -u named
  4. Check for errors:
        • in the syslog log
        • do nslookups
        • make sure the secondary can do zone transfers
        • send a HUP signal to named, to ensure that it reloads configuration correctly.
        • Check the domains using the IP-Plus tool 4.
  5. If everything still looks good, change the /etc/rc2.d/S72inetsvc (or equivalent startup file) entries for starting BIND to something like this:
    if [ -f /home/dns/usr/local/sbin/named -a -f /home/dns/usr/local/etc/named.conf ]; then 
    /usr/sbin/chroot /home/dns /usr/local/sbin/named -u named; 
    echo "Started chroot'ed BIND domain name server." 


If you have a problem, a few tips:

  • Use nslookup or dig to check server results.
  • Client:
    • Check /etc/nsswitch.conf and /etc/resolv.conf.
    • Start nslookup with the "-d2" option to get buckets of debugging info, or start it without any argurments and type "help" at the prompt. There is also a "debug" command from the interactive prompt.
    • Try killing the nscd daemon.
  • Server
    • Send a HUP signal to named, to reread the config file after changes.
      kill -HUP `cat /var/run/named.pid`
    • Look at the syslog entries. Typically logs are found in the syslog "daemon" section.
    • Named has a "-d X" option, which switches on debugging (X is a number indicating the debug level).
    • To get statistics from the name server into /usr/tmp/named.stats:
      kill -ABRT `cat /var/run/named.pid`
    • If the logs indicate permission problems, check your file permissions against the example of an "ls -alR" on a production DNS primary 8.
  • If domain transfers are not working, try manual transfers, for example:
    truss >/usr/local/sbin/named -u named
    truss /usr/sbin/chroot /home/dns /usr/local/sbin/named -u named

  • Check the domains using the IP-Plus tool 4.
  • Read the sections Known Problems and Configuration Notes below.
  • Join the FOCUS-SUN@SECURITYFOCUS.COM list and discuss the problem ;-)

Known Problems

  • BIND will still log to syslog "daemon" for certain events, even if the logging directive tells BIND to local to "local1" (as in our example).
  • ndc does not work correctly in a chroot'ed environment. It would be better to start BIND via ndc:
    /usr/sbin/chroot /home/dns /usr/local/sbin/ndc -c /var/run/ndc start -u named

rather than:

/usr/sbin/chroot /home/dns /usr/local/sbin/named -u named

One reader (J. S. Townsley) had similar problems, so he replaced ndc with a script:

case "$1" in
    /etc/rc.d/init.d/named start;
    /etc/rc.d/init.d/named stop;
    /etc/rc.d/init.d/named restart;
    /usr/sbin/chroot /chroot/named /usr/sbin/ndc $1
This article was originally published on Dec 5, 2000
Get the Latest Scoop with Networking Update Newsletter