Product SiteDocumentation Site

5.7. 增强 BIND 的安全性

有很多不同的方式用于完成域名服务器守护进程的安全化, 这仅与考虑方式有关:

5.7.1. 配置Bind以防误用

You should restrict some of the information that is served from the DNS server to outside clients so that it cannot be used to retrieve valuable information from your organization that you do not want to give away. This includes adding the following options: allow-transfer, allow-query, allow-recursion and version. You can either limit this on the global section (so it applies to all the zones served) or on a per-zone basis. This information is documented in the bind-doc package, read more on this on /usr/share/doc/bind/html/index.html once the package is installed.
设想一下, 您的服务器同时与互联网和您的内部(您的内部IP是192.168.1.2)网(一台基本的 multi-homed 服务器)相连, 您不想为互联网提供任何服务, 而只是为内部主机提供 DNS 查询服务. 您可以在 /etc/bind/named.conf 中加入如下内容, 以实现这种限制:
options {
            allow-query { 192.168.1/24; } ;
            allow-transfer { none; } ; 
            allow-recursion { 192.168.1/24; } ;
            listen-on { 192.168.1.2; } ;
            forward { only; } ;
            forwarders { A.B.C.D; } ;
};
listen-on 选项使 DNS 仅绑定到内部地址接口, 但即使此接口和与互联网相连的相同(例如, 您正在使用 NAT), 也只会接收源自您的内部网络的主机的查询. 如果系统有多个接口, 并且没有指定listen-on项, 以确保只有内部用户可以查询, 那么因为此端口外部攻击者也可以访问,所以他们将设法对 DNS 服务器攻击(或利用缓冲溢出攻击). 因此如果 DNS 服务器只为自身提供服务, 则应当配置其只监听 127.0.0.1.
The version.bind record in the chaos class contains the version of the currently running bind process. This information is often used by automated scanners and malicious individuals who wish to determine if one's bind is vulnerable to a specific attack. By providing false or no information in the version.bind record, one limits the probability that one's server will be attacked based on its published version. To provide your own version, use the version directive in the following manner:
 options { ... various options here ...
version "Not available."; };
改变 version.bind 的记录并不能对避免攻击提供实质性的保护. 但是可以被认为是一个有用的保障.
下边是一个 named.conf 配置文件的例子:
acl internal {
        127.0.0.1/32;           // localhost
        10.0.0.0/8;             // internal
        aa.bb.cc.dd;            // eth0 IP
};

acl friendly {
        ee.ff.gg.hh;            // slave DNS
        aa.bb.cc.dd;            // eth0 IP
        127.0.0.1/32;           // localhost
        10.0.0.0/8;             // internal
};

options {
        directory "/var/cache/bind";
        allow-query { internal; };
        allow-recursion { internal; };
        allow-transfer { none; };
};
// From here to the mysite.bogus zone 
// is basically unmodified from the debian default
logging {
        category lame-servers { null; };
        category cname { null; };   
};

zone "." {
        type hint;
        file "/etc/bind/db.root";
};

zone "localhost" {
        type master;
        file "/etc/bind/db.local";
};

zone "127.in-addr.arpa" {
        type master;
        file "/etc/bind/db.127";
};

zone "0.in-addr.arpa" {
        type master;
        file "/etc/bind/db.0";
};

zone "255.in-addr.arpa" {
        type master;
        file "/etc/bind/db.255";
};

// zones I added myself
zone "mysite.bogus" {
        type master;
        file "/etc/bind/named.mysite";
        allow-query { any; };
        allow-transfer { friendly; };
};
Please (again) check the Bug Tracking System regarding Bind, specifically http://bugs.debian.org/94760. Feel free to contribute to the bug report if you think you can add useful information.

5.7.2. 管理 BIND 用户

Regarding limiting BIND's privileges you must be aware that if a non-root user runs BIND, then BIND cannot detect new interfaces automatically, for example when you put a PCMCIA card into your laptop. Check the README.Debian file in your named documentation (/usr/share/doc/bind/README.Debian) directory for more information about this issue. There have been many recent security problems concerning BIND, so switching the user is useful when possible. We will detail here the steps needed in order to do this, however, if you want to do this in an automatic way you might try the script provided in 第 B.5 节 “修改Bind默认安装的示例脚本.”.
Notice, in any case, that this only applies to BIND version 8. In the Debian packages for BIND version 9 (since the 9.2.1-5 version, available since sarge) the bind user is created and used by setting the OPTIONS variable in /etc/default/bind9. If you are using BIND version 9 and your name server daemon is not running as the bind user verify the settings on that file.
为了可以使用其它用户来运行 BIND, 首先应为此创建一个单独的用户和组 (每个非root运行的服务都使用 nobody 或 bogroup 是一个好主意). 在下边的例子中, 将会使用named这个用户和组. 键入如下内容:
addgroup named
adduser --system --home /home/named --no-create-home --ingroup named \
      --disabled-password --disabled-login named
注意, 用户 named 将会是一个限制. 如果您需要, 或者其它的原因, 有一个较少的限制的设定:
adduser --system --ingroup named named
Now you can either edit /etc/init.d/bind with your favorite editor and change the line beginning with
start-stop-daemon --start
to[39]
start-stop-daemon --start --quiet --exec /usr/sbin/named -- -g named -u named
Or you can change (create it if it does not exit) the default configuration file (/etc/default/bind for BIND version 8) and introduce the following:
OPTIONS="-u named -g named"
修改 Bind 所使用文件的权限, 这包括 /etc/bind/rndc.key:
-rw-r-----    1 root     named          77 Jan  4 01:02 rndc.key
在 bind 创建 pidfile 的地方,使用, 例如 /var/run/named 来替代 /var/run:
$ mkdir /var/run/named
$ chown named.named /var/run/named
$ vi /etc/named.conf
[ ... update the configuration file to use this new location ...]
options { ...
        pid-file "/var/run/named/named.pid";
};
[ ... ]
Also, in order to avoid running anything as root, change the reload line in the init.d script by substituting:
reload)
       /usr/sbin/ndc reload
to:
reload)
        $0 stop
        sleep 1
        $0 start
注意: 您也许还需要修改 restart 行, 这与您的 Debian 的版本有关. 这在 Debian 的 bind 1:8.3.1-2 版中对此做了修正.
All you need to do now is to restart bind via /etc/init.d/bind restart, and then check your syslog for two entries like this:
Sep  4 15:11:08 nexus named[13439]: group = named
Sep  4 15:11:08 nexus named[13439]: user = named
Voilà! Your named now does not run as root. If you want to read more information on why BIND does not run as non-root user on Debian systems, please check the Bug Tracking System regarding Bind, specifically http://bugs.debian.org/50013 and http://bugs.debian.org/132582, http://bugs.debian.org/53550, http://bugs.debian.org/52745, and http://bugs.debian.org/128129. Feel free to contribute to the bug reports if you think you can add useful information.

5.7.3. 使名称服务器运行于 chroot 环境

To achieve maximum BIND security, now build a chroot jail (see 第 5.10 节 “常用 chroot 和 suid”) around your daemon. There is an easy way to do this: the -t option (see the named(8) manual page or page 100 of http://www.nominum.com/content/documents/bind9arm.pdf). This will make Bind chroot itself into the given directory without you needing to set up a chroot jail and worry about dynamic libraries. The only files that need to be in the chroot jail are:
dev/null
etc/bind/       - should hold named.conf and all the server zones
sbin/named-xfer - if you do name transfers
var/run/named/  - should hold the PID and the name server cache (if
                  any) this directory needs to be writable by named user
var/log/named   - if you set up logging to a file, needs to be writable
                  for the named user
dev/log         - syslogd should be listening here if named is configured to
                  log through it
Bind 守护进程必须对 named 文件有访问权限才能正常运行. 因为这些配置文件通常都在 /etc/named/ 目录下, 所以这很容易办到. 应当考虑到,对于区域文件只需要有只读权限,除非这是第二或缓存名称服务器. 如果是这样,您则需要给必要的区域以写权限(以便从主服务器进行区域转换).
Also, you can find more information regarding Bind chrooting in the http://www.tldp.org/HOWTO/Chroot-BIND-HOWTO.html (regarding Bind 9) and http://www.tldp.org/HOWTO/Chroot-BIND8-HOWTO.html (regarding Bind 8). This same documents should be available through the installation of the doc-linux-text (text version) or doc-linux-html (HTML version). Another useful document is http://web.archive.org/web/20011024064030/http://www.psionic.com/papers/dns/dns-linux.
If you are setting up a full chroot jail (i.e. not just -t) for Bind in Debian, make sure you have the following files in it[40]:
dev/log - syslogd should be listening here
dev/null
etc/bind/named.conf 
etc/localtime
etc/group - with only a single line: "named:x:GID:"
etc/ld.so.cache - generated with ldconfig 
lib/ld-2.3.6.so
lib/libc-2.3.6.so
lib/ld-linux.so.2 - symlinked to ld-2.3.6.so
lib/libc.so.6 - symlinked to libc-2.3.6.so
sbin/ldconfig - may be deleted after setting up the chroot
sbin/named-xfer - if you do name transfers
var/run/
And modify also syslogd listen on $CHROOT/dev/log so the named server can write syslog entries into the local system log.
如果您想避免动态链接库的问题, 您可以静态编译 bind. 可以使用 apt-getsource 选项下载. 这样可以下载所需正确编译的软件包. 您需要做类似如下操作:
$ apt-get source bind
# apt-get build-dep bind
$ cd bind-8.2.5-2
  (edit src/port/linux/Makefile so CFLAGS includes the '-static'
   option)
$ dpkg-buildpackage -rfakeroot -uc -us
$ cd ..
# dpkg -i bind-8.2.5-2*deb
After installation, you will need to move around the files to the chroot jail[41] you can keep the init.d scripts in /etc/init.d so that the system will automatically start the name server, but edit them to add --chroot /location_of_chroot in the calls to start-stop-daemon in those scripts or use the -t option for BIND by setting it in the OPTIONS argument at the /etc/default/bind (for version 8) or /etc/default/bind9 (for version 9) configuration file.
有关如何设定chroot的更多信息,参见 第 5.10 节 “常用 chroot 和 suid”.


[39] Note that depending on your bind version you might not have the -g option, most notably if you are using bind9 in sarge (9.2.4 version).
[40] This setup has not been tested for new release of Bind yet.
[41] Unless you use the instdir option when calling dpkg but then the chroot jail might be a little more complex.