下一步 上一步 目录

2. 准备 Jail 环境

2.1 创建用户

正如引言中提到的,以 root 身份运行 BIND 不是一个好主意。因此,在开始之前,让我们为 BIND 创建一个单独的用户。请注意,您永远不应该为此目的使用像 nobody 这样的通用用户。但是,一些发行版,例如 SuSE 和 Linux Mandrake,已经开始提供特定的用户(通常称为 named);如果您愿意,您可以简单地为我们的目的调整此用户。

这需要在 /etc/passwd 中添加如下行

named:x:200:200:Nameserver:/chroot/named:/bin/false
并在 /etc/group 中添加如下行
named:x:200:
这将为 BIND 创建一个名为 named 的用户和组。确保 UID 和 GID(在本例中均为 200)在您的系统上是唯一的。shell 设置为 /bin/false,因为此用户永远不需要登录。

2.2 目录结构

现在,我们必须设置目录结构,该结构将用于 BIND 所在的 chroot jail 环境。这可以是文件系统上的任何位置;真正偏执的人甚至可能想将其放在单独的卷上。我假设您将使用 /chroot/named。让我们从创建以下目录结构开始

/chroot
  +-- named
       +-- bin
       +-- dev
       +-- etc
       |    +-- namedb
       +-- lib
       +-- var
            +-- run

2.3 放置 BIND 数据

假设您已经完成了 BIND 的常规安装并正在使用它,您将已经拥有现有的 named.conf 和区域文件。这些文件现在必须移动(或复制,为了安全起见)到 chroot jail 环境中,以便 BIND 可以访问它们。named.conf 放在 /chroot/named/etc 中,区域文件可以放在 /chroot/named/etc/namedb 中。例如

# cp -p /etc/named.conf /chroot/named/etc/

# cp -a /var/named/* /chroot/named/etc/namedb/

BIND 可能需要写入 namedb 目录,以及可能其中的一些文件。例如,如果您的 DNS 充当区域的从服务器,它将必须更新该区域文件。此外,BIND 可以转储统计信息,并且在此目录中执行此操作。因此,您应该可能使 named 用户成为此目录及其内容的所有者

# chown -R named:named /chroot/named/etc/namedb
BIND 也需要写入 /var/run 目录,以将其 pid 文件和 ndc 套接字放在那里,所以让我们允许它这样做
# chown named:named /chroot/named/var/run

2.4 系统支持文件

一旦 BIND 在 chroot jail 环境中运行,它将完全无法访问 jail 环境之外的文件。但是,它需要访问一些关键文件,例如系统的 C 库。确切需要哪些库将取决于您的 UNIX 版本。对于大多数现代 Linux 系统,以下命令足以将必要的库放置到位

# cd /chroot/named/lib
# cp -p /lib/libc-2.*.so .
# ln -s libc-2.*.so libc.so.6
# cp -p /lib/ld-2.*.so .
# ln -s ld-2.*.so ld-linux.so.2
作为替代方案,您可以简单地构建静态链接版本的 BIND 二进制文件以放入您的 chroot jail 环境中。您还应该将 ldconfig 复制到 jail 环境中,并运行它以创建 jail 环境的 etc/ld.so.cache。以下命令可以处理此问题
# cp /sbin/ldconfig /chroot/named/bin/
# chroot /chroot/named /bin/ldconfig -v

BIND 在其 jail 环境中还需要一个系统文件:好的旧的 /dev/null。同样,创建此设备节点所需的精确命令可能因系统而异;请检查您的 /dev/MAKEDEV 脚本以确保。某些系统可能还需要 /dev/zero。对于大多数 Linux 系统,我们可以使用以下命令

# mknod /chroot/named/dev/null c 1 3

最后,您需要在 jail 环境内部的 /etc 目录中添加几个额外的文件。特别是,您必须将 /etc/localtime(在某些系统上有时称为 /usr/lib/zoneinfo/localtime)复制到那里,以便 BIND 记录事件时使用正确的时间,并且您必须创建一个简单的 group 文件,其中包含 named 组。以下两个命令将处理此问题

# cp /etc/localtime /chroot/named/etc/

# echo 'named:x:200:' > /chroot/named/etc/group

请记住,GID(在本例中为 200)必须与您在上面真实的 /etc/group 中定义的 GID 匹配。

2.5 日志记录

与传统的囚犯不同,BIND 不能只是在墙上乱涂乱画日志条目 :-)。通常,BIND 通过 syslogd(系统日志守护程序)记录日志。但是,这种类型的日志记录是通过将日志条目发送到特殊套接字 /dev/log 来执行的。由于它在 jail 环境之外,BIND 无法再使用它。幸运的是,有几种解决方法。

理想的解决方案

解决此困境的理想解决方案需要一个相当新的 syslogd 版本,该版本支持 OpenBSD 引入的 -a 开关。检查您的 syslogd(8) 的手册页,看看您是否拥有这样的版本。

如果您有,您所要做的就是将开关 ``-a /chroot/named/dev/log'' 添加到您启动 syslogd 时的命令行。在使用完整 SysV-init 的系统(包括大多数 Linux 发行版)上,这通常在文件 /etc/rc.d/init.d/syslog 中完成。例如,在我的 Red Hat Linux 系统上,我更改了行

daemon syslogd -m 0
daemon syslogd -m 0 -a /chroot/named/dev/log

在 Caldera OpenLinux 系统上,他们使用名为 ssd 的守护程序启动器,它从 /etc/sysconfig/daemons/syslog 读取配置。您只需要修改选项行,使其看起来像这样

OPTIONS_SYSLOGD="-m 0 -a /chroot/named/dev/log"

同样,在 SuSE 系统上,我被告知添加此开关的最佳位置是在 /etc/rc.config 文件中。更改行

SYSLOGD_PARAMS=""
以读取
SYSLOGD_PARAMS="-a /chroot/named/dev/log"
应该可以解决问题。

一旦您弄清楚如何在您的系统上进行此更改,只需重新启动 syslogd,可以通过杀死它并再次启动它(使用额外的参数),或者使用 SysV-init 脚本为您执行此操作

# /etc/rc.d/init.d/syslog stop
# /etc/rc.d/init.d/syslog start

重新启动后,您应该在 /chroot/named/dev 中看到一个名为 log 的“文件”,它看起来像这样

srw-rw-rw-   1 root     root            0 Mar 13 20:58 log

其他解决方案

如果您有较旧的 syslogd,那么您将不得不找到另一种方法来进行日志记录。那里有一些程序,例如 holelogd,旨在通过充当“代理”并接受来自 chroot BIND 的日志条目并将它们传递到常规 /dev/log 套接字来提供帮助。

或者,您可以简单地配置 BIND 以记录到文件而不是通过 syslog。如果您选择走这条路,请参阅 BIND 文档以获取更多详细信息。


下一步 上一步 目录