Hardening the BIND DNS Server
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.
- 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).
- 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.
- Start BIND chroot'ed:
/usr/sbin/chroot /home/dns /usr/local/sbin/named -u named
- 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.
- 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." fi
Troubleshooting
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.
- Send a HUP signal to named, to reread the config file after changes.
- 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 namedOne reader (J. S. Townsley) had similar problems, so he replaced ndc with a script:
#!/bin/sh case "$1" in start) /etc/rc.d/init.d/named start; ;; stop) /etc/rc.d/init.d/named stop; ;; restart) /etc/rc.d/init.d/named restart; ;; *) /usr/sbin/chroot /chroot/named /usr/sbin/ndc $1 esac
Page 3 of 5
This article was originally published on December 5, 2000