<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <HTML> <HEAD> <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9"> <TITLE>Chroot-BIND HOWTO: Preparing the Jail</TITLE> <LINK HREF="Chroot-BIND-HOWTO-3.html" REL=next> <LINK HREF="Chroot-BIND-HOWTO-1.html" REL=previous> <LINK HREF="Chroot-BIND-HOWTO.html#toc2" REL=contents> </HEAD> <BODY> <A HREF="Chroot-BIND-HOWTO-3.html">Next</A> <A HREF="Chroot-BIND-HOWTO-1.html">Previous</A> <A HREF="Chroot-BIND-HOWTO.html#toc2">Contents</A> <HR> <H2><A NAME="s2">2. Preparing the Jail</A></H2> <H2><A NAME="ss2.1">2.1 Creating a User</A> </H2> <P>As mentioned in the introduction, it's not a good idea to run BIND as root. So, before we begin, let's create a separate user for BIND. Note that you should never use an existing generic user like <CODE>nobody</CODE> for this purpose. However, some distributions, such as SuSE and Linux Mandrake have started providing a specific user (generally called <CODE>named</CODE>); you can simply adapt this user for our purposes, if you like. <P>This requires adding a line something like the following to <CODE>/etc/passwd</CODE>: <BLOCKQUOTE><CODE> <PRE> named:x:200:200:Nameserver:/chroot/named:/bin/false </PRE> </CODE></BLOCKQUOTE> And one like this to <CODE>/etc/group</CODE>: <BLOCKQUOTE><CODE> <PRE> named:x:200: </PRE> </CODE></BLOCKQUOTE> This creates a user and group called <CODE>named</CODE> for BIND. Make sure that the UID and GID (both 200 in this example) are unique on your system. The shell is set to <CODE>/bin/false</CODE> because this user will never need to log in. <P> <H2><A NAME="ss2.2">2.2 Directory Structure</A> </H2> <P>Now, we must set up the directory structure that we will use for the chroot jail in which BIND will live. This can be anywhere on your filesystem; the truly paranoid may even want to put it on a separate volume. I shall assume that you will use <CODE>/chroot/named</CODE>. Let's start by creating the following directory structure: <P> <BLOCKQUOTE><CODE> <PRE> /chroot +-- named +-- dev +-- etc | +-- namedb | +-- slave +-- var +-- run </PRE> </CODE></BLOCKQUOTE> <P>If you use GNU <CODE>mkdir</CODE> (such as on a Linux system), you can create this directory structure like this: <P> <BLOCKQUOTE><CODE> <PRE> # mkdir -p /chroot/named # cd /chroot/named # mkdir -p dev etc/namedb/slave var/run </PRE> </CODE></BLOCKQUOTE> <P> <H2><A NAME="ss2.3">2.3 Placing the BIND Data</A> </H2> <P>Assuming that you have already done a conventional installation of BIND and are using it, you will already have an existing <CODE>named.conf</CODE> and zone files. These files must now be moved (or copied, to be safe) into the chroot jail, so that BIND can get at them. <CODE>named.conf</CODE> goes in <CODE>/chroot/named/etc</CODE>, and the zone files can go in <CODE>/chroot/named/etc/namedb</CODE>. For example: <BLOCKQUOTE><CODE> <PRE> # cp -p /etc/named.conf /chroot/named/etc/ # cp -a /var/named/* /chroot/named/etc/namedb/ </PRE> </CODE></BLOCKQUOTE> <P>BIND would normally need to write to the <CODE>namedb</CODE> directory, but in the interests of tightening security, we will not allow it to do this. If your nameserver serves as a slave for any zones, it will need to update these zone files, which means we'll have to store them in a separate directory, to which BIND does have write access. <BLOCKQUOTE><CODE> <PRE> # chown -R named:named /chroot/named/etc/namedb/slave </PRE> </CODE></BLOCKQUOTE> <P>Keep in mind that'll you have to move any slave zones you have into this directory, and update your <CODE>named.conf</CODE> accordingly. <P>BIND will also need to write to the <CODE>/var/run</CODE> directory, to put its pidfile and statistical information there, so let's allow it to do so: <BLOCKQUOTE><CODE> <PRE> # chown named:named /chroot/named/var/run </PRE> </CODE></BLOCKQUOTE> <P> <H2><A NAME="ss2.4">2.4 System Support Files</A> </H2> <P>Once BIND is running in the chroot jail, it will not be able to access files outside the jail <B>at all</B>. However, it needs to access a few key files, although not nearly as many as BIND 8 did. <P>One file that BIND will need inside its jail is good ol' <CODE>/dev/null</CODE>. Note that the exact command necessary to create this device node may vary from system to system; check your <CODE>/dev/MAKEDEV</CODE> script to be sure. Some systems may also require <CODE>/dev/zero</CODE>, which can created similarly. It's reported that the BIND 9.2.0 release candidates now require <CODE>/dev/random</CODE> as well. For most Linux systems, we can use the following commands: <BLOCKQUOTE><CODE> <PRE> # mknod /chroot/named/dev/null c 1 3 # mknod /chroot/named/dev/random c 1 8 # chmod 666 /chroot/named/dev/{null,random} </PRE> </CODE></BLOCKQUOTE> <P>For FreeBSD 4.3, this is: <BLOCKQUOTE><CODE> <PRE> # mknod /chroot/named/dev/null c 2 2 # mknod /chroot/named/dev/random c 2 3 # chmod 666 /chroot/named/dev/{null,random} </PRE> </CODE></BLOCKQUOTE> <P>You also need another file in the <CODE>/etc</CODE> directory inside the jail. You must copy <CODE>/etc/localtime</CODE> (this is sometimes known as <CODE>/usr/lib/zoneinfo/localtime</CODE> on some systems) in there so that BIND logs things with the right time on them. The following command will take care of this: <BLOCKQUOTE><CODE> <PRE> # cp /etc/localtime /chroot/named/etc/ </PRE> </CODE></BLOCKQUOTE> <P> <H2><A NAME="logging"></A> <A NAME="ss2.5">2.5 Logging</A> </H2> <P>Unlike a conventional jailbird, BIND can't just scribble its log entries on the walls :-). Normally, BIND logs through <CODE>syslogd</CODE>, the system logging daemon. However, this type of logging is performed by sending the log entries to the special socket <CODE>/dev/log</CODE>. Since this is outside the jail, BIND can't use it any more. Fortuantely, there are a couple options to work around this. <P> <H3>The Ideal Solution</H3> <P>The ideal solution to this dilemma requires a reasonably recent version of <CODE>syslogd</CODE> which supports the <CODE>-a</CODE> switch introduced by OpenBSD. Check the manpage for your <CODE>syslogd(8)</CODE> to see if you have such a version. <P>If you do, all you have to do is add the switch ``<CODE>-a /chroot/named/dev/log</CODE>'' to the command line when you launch <CODE>syslogd</CODE>. On systems which use a full SysV-init (which includes most Linux distributions), this is typically done in the file <CODE>/etc/rc.d/init.d/syslog</CODE>. For example, on my Red Hat Linux system, I changed the line <BLOCKQUOTE><CODE> <PRE> daemon syslogd -m 0 </PRE> </CODE></BLOCKQUOTE> to <BLOCKQUOTE><CODE> <PRE> daemon syslogd -m 0 -a /chroot/named/dev/log </PRE> </CODE></BLOCKQUOTE> <P>Interestingly, as of Red Hat 7.2, Red Hat has apparently made this process even easier. There is now a file called <CODE>/etc/sysconfig/syslog</CODE> in which extra parameters for syslogd can be defined. <P>On Caldera OpenLinux systems, they use a daemon launcher called <CODE>ssd</CODE>, which reads configuration from <CODE>/etc/sysconfig/daemons/syslog</CODE>. You simply need to modify the options line to look like this: <BLOCKQUOTE><CODE> <PRE> OPTIONS_SYSLOGD="-m 0 -a /chroot/named/dev/log" </PRE> </CODE></BLOCKQUOTE> <P>Similarly, on SuSE systems, I'm told that the best place to add this switch is in the <CODE>/etc/rc.config</CODE> file. Changing the line <BLOCKQUOTE><CODE> <PRE> SYSLOGD_PARAMS="" </PRE> </CODE></BLOCKQUOTE> to read <BLOCKQUOTE><CODE> <PRE> SYSLOGD_PARAMS="-a /chroot/named/dev/log" </PRE> </CODE></BLOCKQUOTE> should do the trick. <P>And, last but not least, for FreeBSD 4.3 you can apparently just edit the <CODE>rc.conf</CODE> file and put in the following: <BLOCKQUOTE><CODE> <PRE> syslogd_flags="-s -l /chroot/named/dev/log" </PRE> </CODE></BLOCKQUOTE> The <CODE>-s</CODE> is for security reasons, and is part of the default settings. The <CODE>-l</CODE> is a local path on which to put another logging node. <P>Once you've figured out how to make this change for your system, simply restart <CODE>syslogd</CODE>, either by killing it and launching it again (with the extra parameters), or by using the SysV-init script to do it for you: <BLOCKQUOTE><CODE> <PRE> # /etc/rc.d/init.d/syslog stop # /etc/rc.d/init.d/syslog start </PRE> </CODE></BLOCKQUOTE> <P>Once it's been restarted, you should see a ``file'' in <CODE>/chroot/named/dev</CODE> called <CODE>log</CODE>, that looks something like this: <P> <PRE> srw-rw-rw- 1 root root 0 Mar 13 20:58 log </PRE> <P> <H3>The Other Solutions</H3> <P>If you have an older <CODE>syslogd</CODE>, then you'll have to find another way to do your logging. There are a couple programs out there, such as <CODE>holelogd</CODE>, which are designed to help by acting as a ``proxy'' and accepting log entries from the chrooted BIND and passing them out to the regular <CODE>/dev/log</CODE> socket. <P>Alteratively, you can simply configure BIND to log to files instead of going through syslog. See the BIND documentation for more details if you choose to go this route. <P> <H2><A NAME="perm"></A> <A NAME="ss2.6">2.6 Tightening Permissions</A> </H2> <P>First of all, feel free to restrict access to the whole <CODE>/chroot</CODE> directory to the <CODE>root</CODE> user. Of course, not everybody may want to do this, especially if you have other software installed in that tree that doesn't appreciate it. <P> <BLOCKQUOTE><CODE> <PRE> # chown root /chroot # chmod 700 /chroot </PRE> </CODE></BLOCKQUOTE> <P>You can also safely restrict access to <CODE>/chroot/named</CODE> to the <CODE>named</CODE> user. <P> <BLOCKQUOTE><CODE> <PRE> # chown named:named /chroot/named # chmod 700 /chroot/named </PRE> </CODE></BLOCKQUOTE> <P>For even more tightening, on Linux systems we can make a few of the files and directories immutable, using the <CODE>chattr</CODE> tool on ext2 filesystems. <P> <BLOCKQUOTE><CODE> <PRE> # cd /chroot/named # chattr +i etc etc/localtime var </PRE> </CODE></BLOCKQUOTE> <P>Equivalently, on FreeBSD 4.3, you want to look into <CODE>chflags</CODE> if you wish to make things immutable. As an example, the following should change everything in the <CODE>/chroot/named/etc</CODE> directory to immutable: <BLOCKQUOTE><CODE> <PRE> # chflags schg /chroot/named/etc/*(*). </PRE> </CODE></BLOCKQUOTE> <P>It would be nice to do this for the <CODE>dev</CODE> directory too, but unfortunately that would prevent <CODE>syslogd</CODE> from creating its <CODE>dev/log</CODE> socket. You may also choose to set the immutable bit on other files in the jail as well, such as your primary zone files, if they aren't expected to change. <P> <HR> <A HREF="Chroot-BIND-HOWTO-3.html">Next</A> <A HREF="Chroot-BIND-HOWTO-1.html">Previous</A> <A HREF="Chroot-BIND-HOWTO.html#toc2">Contents</A> </BODY> </HTML>