需要的文件:
目录列表:
目录结构如下:
安装步骤:
1.添加执行bind所用的用户(为了使用chroot)
#添加named组
#添加named用户,设定home目录为我们指定的chroot目录,shell设置成nologin,不允许从控制台登陆
#锁定named帐户的密码
2.构建chroot环境
#首先删掉useradd命令自己建立的/opt/chroot目录,然后再重建/opt/chroot目录,目的是清除.bash_profile这类文件,因为named不允许登陆,因此这些文件无用
#建立etc, dev, var这三个必须的目录
#建立必要的设备文件
#复制本机的timezone文件到chroot环境
3.解压缩bind源码
4.进入源码目录进行编译
如果没有错误的话,已经编译好bind并安装到了prefix参数所指定位置(默认情况下所有的文件都在该目录,除非手工指定其他目录)。--enable-threads指定了使用多线程
5.建立BIND配置文件和zone文件
6.削减,设置目录访问权限
7.启动BIND
8.设置rndc
编辑/opt/bind/etc/rndc.conf
scott at wunsch.orgv1.5, 1 December 2001
This document describes installing the BIND 9 nameserver to run in a chroot jail and as a non-root user, to provide added security and minimise the potential effects of a security compromise. Note that this document has been updated for BIND 9; if you still run BIND 8, you want the Chroot-BIND8 HOWTO instead.
This is the Chroot-BIND HOWTO; see Where? for the master site, which contains the latest copy. It is assumed that you already know how to configure and use BIND (the Berkeley Internet Name Domain). If not, I would recommend that you read the DNS HOWTO first. It is also assumed that you have a basic familiarity with compiling and installing software on your UNIX-like system.
This document describes some extra security precautions that you can take when you install BIND. It explains how to configure BIND so that it resides in a ``chroot jail,'' meaning that it cannot see or access files outside its own little directory tree. We shall also configure it to run as a non-root user.
The idea behind chroot is fairly simple. When you run BIND (or any other process) in a chroot jail, the process is simply unable to see any part of the filesystem outside the jail. For example, in this document, we'll set BIND up to run chrooted to the directory /chroot/named. Well, to BIND, the contents of this directory will appear to be /, the root directory. Nothing outside this directory will be accessible to it. You've probably encounted a chroot jail before, if you've ever used ftp to log into a public system.
Because the chroot process is much simpler with BIND 9, I have started to expand this document slightly, to include more general tips about securing a BIND installation. Nevertheless, this document is not (and is not intended to be) a complete reference for securing BIND. If you do only what is outlined in this document, you're not finished securing your nameserver!
The idea behind running BIND in a chroot jail is to limit the amount of access any malicious individual could gain by exploiting vulnerabilities in BIND. It is for the same reason that we run BIND as a non-root user.
This should be considered as a supplement to the normal security precautions (running the latest version, using access control, etc.), certainly not as a replacement for them.
If you're interested in DNS security, you might also be interested in a few other products. Building BIND with StackGuard would probably be a good idea for even more protection. Using it is easy; it's just like using ordinary gcc. Also, DNScache is a secure replacement for BIND, written by Dan Bernstein. Dan is the author of qmail, and DNScache appears to follow a similar philosophy.
The latest version of this document is always available from the web site of the Linux/Open Source Users of Regina, Sask., at http://www.losurs.org/docs/howto/Chroot-BIND.html.
There is now a Japanese translation of this document, maintained by Nakano Takeo nakano at apm.seikei.ac.jp. This is available at http://www.linux.or.jp/JF/JFdocs/Chroot-BIND-HOWTO.html.
BIND is available from the Internet Software Consortium at http://www.isc.org/bind.html. As of this writing, the current version of BIND 9 is 9.2.0. BIND 9 has been out for some time now, and many people are using it in production. Nevertheless, some more conservative sorts still prefer to remain with BIND 8. If you are such a person, please see my Chroot-BIND8 HOWTO (available from the same location) for details on chrooting it, but be warned that BIND 8 is much messier to chroot.
Keep in mind that there are known security holes in many earlier versions of BIND, so make very sure that you're running the latest version!
I wrote this document based on my experiences in setting BIND up in a chroot environment. In my case, I already had an existing BIND installation in the form of a package that came with my Linux distribution. I'll assume that most of you are probably in the same situation, and will simply be transferring over and modifying the configuration files from your existing BIND installation, and then removing the package before installing the new one. Don't remove the package yet, though; we may want some files from it first.
If this is not the case for you, you should still be able to follow this document. The only difference is that, where I refer to copying an existing file, you first have to create it yourself. The DNS HOWTO may be helpful for this.
These steps worked for me, on my system; your mileage may vary. This is but one way to approach this; there are other ways to set the same thing up (although the general approach will be the same). It just happens that this was the first way that I tried that worked, so I wrote it down.
My BIND experience to date has been installing on Linux servers. However, most of the instructions in this document should be easily applicable to other flavours of UNIX as well, and I shall try to point out differences of which I am aware. I've also received suggestions from people using other distributions and other platforms, and I've tried to incorporate their comments where possible.
If you run Linux, you need to make sure that you're running a 2.4 kernel before attempting this. The -u switch (to run as a non-root user) requires this newer kernel.
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 nobody for this purpose. However, some distributions, such as SuSE and Linux Mandrake have started providing a specific user (generally called named); you can simply adapt this user for our purposes, if you like.
This requires adding a line something like the following to /etc/passwd:
named:x:200:200:Nameserver:/chroot/named:/bin/false
And one like this to /etc/group:
named:x:200:
This creates a user and group called named for BIND. Make sure that the UID and GID (both 200 in this example) are unique on your system. The shell is set to /bin/false because this user will never need to log in.
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 /chroot/named. Let's start by creating the following directory structure:
/chroot
+-- named
+-- dev
+-- etc
| +-- namedb
| +-- slave
+-- var
+-- run
If you use GNU mkdir (such as on a Linux system), you can create this directory structure like this:
# mkdir -p /chroot/named
# cd /chroot/named
# mkdir -p dev etc/namedb/slave var/run
Assuming that you have already done a conventional installation of BIND and are using it, you will already have an existing named.conf 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. named.conf goes in /chroot/named/etc, and the zone files can go in /chroot/named/etc/namedb. For example:
# cp -p /etc/named.conf /chroot/named/etc/
# cp -a /var/named/* /chroot/named/etc/namedb/
BIND would normally need to write to the namedb 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.
# chown -R named:named /chroot/named/etc/namedb/slave
Keep in mind that'll you have to move any slave zones you have into this directory, and update your named.conf accordingly.
BIND will also need to write to the /var/run directory, to put its pidfile and statistical information there, so let's allow it to do so:
# chown named:named /chroot/named/var/run
Once BIND is running in the chroot jail, it will not be able to access files outside the jail at all. However, it needs to access a few key files, although not nearly as many as BIND 8 did.
One file that BIND will need inside its jail is good ol' /dev/null. Note that the exact command necessary to create this device node may vary from system to system; check your /dev/MAKEDEV script to be sure. Some systems may also require /dev/zero, which can created similarly. It's reported that the BIND 9.2.0 release candidates now require /dev/random as well. For most Linux systems, we can use the following commands:
# mknod /chroot/named/dev/null c 1 3
# mknod /chroot/named/dev/random c 1 8
# chmod 666 /chroot/named/dev/{null,random}
For FreeBSD 4.3, this is:
# mknod /chroot/named/dev/null c 2 2
# mknod /chroot/named/dev/random c 2 3
# chmod 666 /chroot/named/dev/{null,random}
You also need another file in the /etc directory inside the jail. You must copy /etc/localtime (this is sometimes known as /usr/lib/zoneinfo/localtime on some systems) in there so that BIND logs things with the right time on them. The following command will take care of this:
# cp /etc/localtime /chroot/named/etc/
Unlike a conventional jailbird, BIND can't just scribble its log entries on the walls :-). Normally, BIND logs through syslogd, the system logging daemon. However, this type of logging is performed by sending the log entries to the special socket /dev/log. Since this is outside the jail, BIND can't use it any more. Fortuantely, there are a couple options to work around this.
The ideal solution to this dilemma requires a reasonably recent version of syslogd which supports the -a switch introduced by OpenBSD. Check the manpage for your syslogd(8) to see if you have such a version.
If you do, all you have to do is add the switch ``-a /chroot/named/dev/log'' to the command line when you launch syslogd. On systems which use a full SysV-init (which includes most Linux distributions), this is typically done in the file /etc/rc.d/init.d/syslog. For example, on my Red Hat Linux system, I changed the line
daemon syslogd -m 0
to
daemon syslogd -m 0 -a /chroot/named/dev/log
Interestingly, as of Red Hat 7.2, Red Hat has apparently made this process even easier. There is now a file called /etc/sysconfig/syslog in which extra parameters for syslogd can be defined.
On Caldera OpenLinux systems, they use a daemon launcher called ssd, which reads configuration from /etc/sysconfig/daemons/syslog. You simply need to modify the options line to look like this:
OPTIONS_SYSLOGD="-m 0 -a /chroot/named/dev/log"
Similarly, on SuSE systems, I'm told that the best place to add this switch is in the /etc/rc.config file. Changing the line
SYSLOGD_PARAMS=""
to read
SYSLOGD_PARAMS="-a /chroot/named/dev/log"
should do the trick.
And, last but not least, for FreeBSD 4.3 you can apparently just edit the rc.conf file and put in the following:
syslogd_flags="-s -l /chroot/named/dev/log"
The -s is for security reasons, and is part of the default settings. The -l is a local path on which to put another logging node.
Once you've figured out how to make this change for your system, simply restart syslogd, either by killing it and launching it again (with the extra parameters), or by using the SysV-init script to do it for you:
# /etc/rc.d/init.d/syslog stop
# /etc/rc.d/init.d/syslog start
Once it's been restarted, you should see a ``file'' in /chroot/named/dev called log, that looks something like this:
srw-rw-rw- 1 root root 0 Mar 13 20:58 log
If you have an older syslogd, then you'll have to find another way to do your logging. There are a couple programs out there, such as holelogd, 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 /dev/log socket.
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.
First of all, feel free to restrict access to the whole /chroot directory to the root 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.
# chown root /chroot
# chmod 700 /chroot
You can also safely restrict access to /chroot/named to the named user.
# chown named:named /chroot/named
# chmod 700 /chroot/named
For even more tightening, on Linux systems we can make a few of the files and directories immutable, using the chattr tool on ext2 filesystems.
# cd /chroot/named
# chattr +i etc etc/localtime var
Equivalently, on FreeBSD 4.3, you want to look into chflags if you wish to make things immutable. As an example, the following should change everything in the /chroot/named/etc directory to immutable:
# chflags schg /chroot/named/etc/*(*).
It would be nice to do this for the dev directory too, but unfortunately that would prevent syslogd from creating its dev/log 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.
Compiling BIND 9 for use in a chroot jail should be a much more pleasant experience than BIND 8 was. In fact, you don't have to do anything special; the standard ./configure && make should suffice.
Keep in mind that if you want to enable IPv6 support in BIND (--enable-ipv6) on Linux systems, you need matching versions of kernel and glibc. If you have kernel 2.2, you need glibc 2.1, and if you have kernel 2.4, you need glibc 2.2. BIND is quite picky about this.
I should mention that if you have an existing installation of BIND, such as from an RPM, you should probably remove it before installing the new one. On Red Hat systems, this probably means removing the packages bind and bind-utils, and possibly bind-devel and caching-nameserver, if you have them.
You may want to save a copy of the init script (e.g., /etc/rc.d/init.d/named), if any, before doing so; it'll be useful later on.
If you are upgrading from an older version of BIND, such as BIND 8, you will want to read the migration documentation in the file doc/misc/migration in the BIND source package. I don't deal with any migration issues in this document; I simply assume that you are replacing an existing, working installation of BIND 9.
This is the easy part :-). Just run make install and let it take care of it for you. Really, that's it!
If you have an existing init script from your distribution, it would probably be best simply to modify it to run the new binary, with the appropriate switches. The switches are... (drumroll please...)
-u named, which tells BIND to run as the user named, rather than root.-t /chroot/named, which tells BIND to chroot itself to the jail that we've set up.-c /etc/named.conf, which tells BIND where to find its configuration file within the jail.The following is the init script I use with my Red Hat 6.0 system. As you can see, it is almost exactly the same as the way it shipped from Red Hat. I haven't tried the rndc commands yet, but I can't see any reason why they shouldn't work.
#!/bin/sh
#
# named This shell script takes care of starting and stopping
# named (BIND DNS server).
#
# chkconfig: 345 55 45
# description: named (BIND) is a Domain Name Server (DNS) \
# that is used to resolve host names to IP addresses.
# probe: true
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
[ -f /usr/local/sbin/named ] || exit 0
[ -f /chroot/named/etc/named.conf ] || exit 0
# See how we were called.
case "$1" in
start)
# Start daemons.
echo -n "Starting named: "
daemon /usr/local/sbin/named -u named -t /chroot/named -c /etc/named.conf
echo
touch /var/lock/subsys/named
;;
stop)
# Stop daemons.
echo -n "Shutting down named: "
killproc named
rm -f /var/lock/subsys/named
echo
;;
status)
status named
exit $?
;;
restart)
$0 stop
$0 start
exit $?
;;
reload)
/usr/local/sbin/rndc reload
exit $?
;;
probe)
# named knows how to reload intelligently; we don't want linuxconf
# to offer to restart every time
/usr/local/sbin/rndc reload >/dev/null 2>&1 || echo start
exit 0
;;
*)
echo "Usage: named {start|stop|status|restart|reload}"
exit 1
esac
exit 0
As with syslogd, as of Red Hat 7.2 this process is now even easier. There is a file called /etc/sysconfig/named in which extra parameters for syslogd can be defined. The default /etc/rc.d/init.d/named on Red Hat 7.2, however, will check for the existance of /etc/named.conf before starting. You will need to correct this path.
On Caldera OpenLinux systems, you simply need to modify the variables defined at the top, and it will apparently take care of the rest for you:
NAME=named
DAEMON=/usr/local/sbin/$NAME
OPTIONS="-t /chroot/named -u named -c /etc/named.conf"
And for FreeBSD 4.3, you can edit the rc.conf file and put in the following:
named_enable="YES"
named_program="chroot/named/bin/named"
named_flags="-u named -t /chroot/named -c /etc/namedb/named.conf"
You will also have to add or change a few options in your named.conf to keep the various directories straight. In particular, you should add (or change, if you already have them) the following directives in the options section:
directory "/etc/namedb";
pid-file "/var/run/named.pid";
statistics-file "/var/run/named.stats";
Since this file is being read by the named daemon, all the paths are of course relative to the chroot jail. As of this writing, BIND 9 does not support many of the statistics and dump files that previous versions did. Presumably later versions will; if you are running such a version, you may have to add additional entries to cause BIND to write them to the /var/run directory as well.
Everything should be set up, and you should be ready to put your new, more secure BIND into action. Assuming you set up a SysV-style init script, you can simply launch it as:
# /etc/rc.d/init.d/named start
Make sure you kill any old versions of BIND still running before doing this.
You can go take a nap now ;-).
So, you had BIND 9.1.2 all nicely chrooted and tweaked to your taste... and then you hear this nasty rumour that BIND 9.1.3 is finally out, and you just have to give it a try right away. Do you have to go through this whole long process to install this new version?
Nope. In fact, you really just need to compile the new BIND and install it over top of the old one. Just don't forget to kill the old version and restart BIND, or it'll still be the old version running!
I'd like to thank the following people for their assistance in the creation of this HOWTO:
<lonny at abyss.za.org> for "testing" the first version of this HOWTO and making sure that I didn't miss any steps.<chirik at CastleFur.COM>, Dwayne Litzenberger <dlitz at dlitz.net>, Phil Bambridge <phil.b at cableinet.co.uk>, Robert Cole <rcole at metrum-datatape.com>, Colin MacDonald <colinm at telus.net>, and others for pointing out errors, omissions, and providing other useful advice to make this HOWTO even better.<erikw at sec.se> and Brian Cervenka <brian at zerobelow.org> for providing good suggestions for further tightening the jail.<support at accesswest.com> for suggesting a couple more example commands, and pointing out BIND 9.2.0's need of /dev/random.<hostmaster at cybertime.net> for the FreeBSD 4.3 information.<tzd at pobox.com> for the details about the changes in Red Hat 7.2 that make this a little easier.And last but certainly not least, I'd like to thank Nakano Takeo <nakano at apm.seikei.ac.jp> for translating the Chroot-BIND HOWTO into Japanese. You can find his translation at http://www.linux.or.jp/JF/JFdocs/Chroot-BIND-HOWTO.html.
Copyright © Scott Wunsch, 2000-2001. This document may be distributed only subject to the terms set forth in the LDP licence at http://metalab.unc.edu/LDP/COPYRIGHT.html.
This HOWTO is free documentation; you can redistribute it and/or modify it under the terms of the LDP licence. It is distributed in the hope that it will be useful, but without any warranty; without even the impled warranty of merchantability or fitness for a particular purpose. See the LDP licence for more details.
Building and configuring BIND 9 in a chroot jail
This has turned out to be a very hard document to write: we work on it bits and pieces at a time. Sorry if it's incomplete. All of our main work has been done on various flavors of Red Hat, Debian, and Fedora Core, but we've included notes on porting to other systems as well.
We're particularly fond of the outstanding O'Reilly DNS and BIND book.
But our goal is to make this a one-stop place to figure how to do do this, and we'd be really grateful if those that were stuck could send us suggestions to clarify. Kindly forward them to
.
There are plenty of people who've written about how to run BIND in a chroot jail, and we'll add our own experiences. We have done this on a handful of machines and have the routine down pretty well, and anybody else with the same problem set might find this helpful.
We've previously run BIND 8 in a jail, and it has always been a horrid nightmare to build and configure because the install paths had to be hacked up on a custom basis, and every operating system put files in different places. BIND 9 has changed this and decide that it all goes into /usr/local. This has made an enormous difference to consultants with widely varied customer bases. Thank you, ISC.
Most of our direct experience is with various flavors of Red Hat Linux, but we've set this up on Debian's "woody" release as well. These instructions are current as of BIND 9.2.2rc1.
Though the utility of a nameserver is probably clear to most people reading this tech tip, the concept of "jail" may not be: we've been asked to elaborate.
A "jail" is a software mechanism for limiting the ability of a process to access resources outside a very limited area, and it's done with security in mind. A nameserver often talks to the outside world, and time has shown that "the public internet" is a very hostile environment. Should a flaw in BIND be discovered, it could be exploited by one located anywhere on the planet: by isolating the process inside a jail, this restricts the harm that can be done to a compromised system.
A jail is created using the chroot() system call (named for "change root"), and it's given a directory name as a parameter. Once this call is made, the root - the top of the directory tree - for this process is changed from / to the directory given, and there is no way for the process to get outside this area. We typically use /chroot/named to jail our nameservers, but we'll note that the "chroot" in the directory name is just a convention: this is not required (e.g., "/usr/local/named" would make a fine jail location too).
By itself, this won't prevent some flaw in BIND from being exploited, but the worst that happens is that the nameserver is compromised: it can't be leveraged to taking over the whole system. In this way it's more of a general safety precaution providing defense in depth.
Much more information on chroot jails can be found in ourLinux Magazine article:Go Directly to Jail - Secure Untrusted Applications with Chroot
Get the source at the Internet Software Consortium, and the home page for BIND is http://www.isc.org/products/BIND/. These instructions were written for 9.1.2 on a Red Hat Linux 6.2 system, and we'll try to keep them updated as we upgrade our and customer systems. We generally try to keep running the latest stable versions - we're not generally too adventurous with beta.
Our practice is to keep our own build stuff under a /source tree, and to unpack individual sources under it.
# cd /source # gtar -xzvf bind-9.1.2.tar.gz
This unbundles everything into a subdirectory with the full name of the package, and the next step is to to configure and build it.
The BIND instructions say to simply run ./configure, but under Linux a couple of additions are required.
For many years, we have recommended disabling thread support, because in 2.2 kernels, chroot jailing did not work properly. We have never been brave enough to attempt it with more recent kernels, but we've been getting reports that threading works fine in 2.6.
In addition, BIND can support IPv6, the next generation IP addresses (current version is IPv4). BIND typically probes for IPv6 support at runtime, but since we are quite sure that we really don't need this on our networks, we disable it entirely as a safety measure.
NOTE: we prefer to remove any existing nameserver installations (especially those provided by the operating system) before installing the new one. This avoids problems with older versions of key binaries lying around and sometimes being at the wrong point in the command-search$PATH.
Under Red Hat Linux (for instance), this means removing three packages before doing installations.
# rpm -e bind bind-utils caching-nameserver
Finally, we want everything installed into the /usr/localhierarchy, so we provide the installation prefix. This said, configuration and installation is quite simple:
# cd /source/bind-9.1.2 # ./configure --prefix=/usr/local --disable-ipv6 # make # make install
This takes about 15 minutes on a dual-CPU 200 MHz Pentium Pro machine and about three minutes on a 1 GHz Pentium III, and it installs around 200 files under /usr/local. Most of them are #includefiles for C language programming, and only about a dozen are really needed for a BIND installation. See the complete file list at the end of this document.
Creating the actual jail itself is much easier than for BIND 8 because so much trash is not required - it's just tremendous. In particular, none of the shared libraries or named binary files are required to live in the jail, and this makes it easier and more secure for us. For more details on our thoughts on chroot operations, see our more detailed tech tipBest Practices for UNIX chroot() Operations
The initial steps to configure the jail are:
create initial named user and group # groupadd named # useradd -g named -d /chroot/named -s /bin/true named # passwd -l named"lock" the accountRemove all the login-related trash under the newly-created home directory # rm -rf /chroot/namedRe-create the top level jail directory # mkdir -p /chroot/named # cd /chroot/namedcreate the hierarchy # mkdir dev # mkdir etc # mkdir logs # mkdir -p var/run # mkdir -p conf/secondariescreate the devices, but confirm the major/minor device
numbers with "ls -lL /dev/zero /dev/null /dev/random" # mknod dev/null c 1 3 # mknod dev/zero c 1 5 # mknod dev/random c 1 8copy the timezone file # cp /etc/localtime etc
Noticeably absent are any ownership/permissions issues: this is deliberate. We'll get to it shortly. Note that the ls command used to verify the major/minor device numbers includes the -L parameter - this follows symbolic links and is required on some platforms such as Solaris.
The named.conf configuration is central to named operation, and we'll go through creating it step by step. Though these files can get very complex, our first efforts will be for a minimal caching-only nameserver just to get the whole end-to-end process working correctly. Then we'll retrofit to add in needed features such as local domains and access controls.
The named.conf file lives in the jail's etc directory, which makes the full path /chroot/named/etc/named.conf. We usually create a symbolic link to make this visible to the rest of the system at /etc/named.conf.
# ln -s /chroot/named/etc/named.conf /etc/named.conf
Note - we're creating a symbolic link to a file thatdoes not yet exist - this is confusing. But when we edit the file (the next step), it is created properly.
Now, using your favorite editor, create the first version of theetc/named.conf file. We suspect that some of these parameters are not strictly necessary, as the defaults will do, but we feel that being explicit will make the daemon easier to debug for the new administrator (less searching for key files).
options {
directory "/conf";
pid-file "/var/run/named.pid";
statistics-file "/var/run/named.stats";
dump-file "/var/run/named.db";
# hide our "real" version number
version "[secured]";
};
# The root nameservers
zone "." {
type hint;
file "db.rootcache";
};
# localhost - forward zone
zone "localhost" {
type master;
file "db.localhost";
notify no;
};
# localhost - inverse zone
zone "0.0.127.in-addr.arpa" {
type master;
file "db.127.0.0";
notify no;
};
Notice that the directory keyword says /conf, not/chroot/named/conf - this is intended. When running the nameserver inside the chroot jail, all the paths arerelative to the top of the jail at /chroot/named.
This configuration refers to three additional files -- db.rootcache,db.localhost and db.127.0.0 -- and they are all created in the/chroot/named/conf directory.
db.rootcache is a list of the roughly dozen "root servers" which are the starting points for virtually every name query done throughout the internet, and the latter describes the "localhost" address. Creating conf/db.rootcache file can usually be done automatically by querying the root nameservers directly.
If the current machine has working nameservers (say, via your ISP), you can just run the command:
# dig +tcp @a.root-servers.net . ns > /chroot/named/conf/db.rootcache
The +tcp option is require to get the full reply, not the truncated version due to UDP packet limits. In the absense of any working nameservice, a recent version of the file can be found here.
The two other required files serve to administrate the "localhost" address, and the files are static and need not really be understood:
;
; db.localhost
;
$TTL 86400
@ IN SOA @ root (
42 ; serial (d. adams)
3H ; refresh
15M ; retry
1W ; expiry
1D ) ; minimum
IN NS @
IN A 127.0.0.1
;
; db.127.0.0
;
$TTL 86400
@ IN SOA localhost. root.localhost. (
1 ; Serial
28800 ; Refresh
14400 ; Retry
3600000 ; Expire
86400 ) ; Minimum
IN NS localhost.
1 IN PTR localhost.
They should be created one time, and thereafter won't ever be administered again.
Now we've created the files required inside the jail, but the matter of setting the permissions and ownership remains. It's possible to do this by hand, but unreliable: it's very hard to "keep up" with making sure that everything is set correctly on an ongoing basis. So we typically create a small shell script that will run through the entire jail and affirmatively set everything.
We typically put this in /chroot/named.perms - it lives outsidethe jail itself - and we've found that the same file has been usable without change on all of our installations.
# # named.perms # # Set the ownership and permissions on the named directory #cd /chroot/named # By default, root owns everything and only root can write, but dirs # have to be executable too. Note that some platforms use a dot # instead of a colon between user/group in the chown parameters}chown -R root:named .find . -type f -print | xargs chmod u=rw,og=r# regular filesfind . -type d -print | xargs chmod u=rwx,og=rx# directories# the named.conf and rndc.conf must protect their keyschmod o= etc/*.conf# the "secondaries" directory is where we park files from # master nameservers, and named needs to be able to update # these files and create new ones.touch conf/secondaries/.empty# placeholderfind conf/secondaries/ -type f -print | xargs chown named:namedfind conf/secondaries/ -type f -print | xargs chmod ug=r,o=chown root:named conf/secondaries/chmod ug=rwx,o= conf/secondaries/# the var/run business is for the PID filechown root:root var/chmod u=rwx,og=x var/chown root:named var/run/chmod ug=rwx,o=rx var/run/# named has to be able to create logfileschown root:named logs/chmod ug=rwx,o=rx logs/
The "placeholder" file simply insures that the secondaries directory is not empty, and it prevents the script from generating (harmless) error messages.
It's absolutely necessary to run this at least once after setting things up, and periodically whenever changes are made. The command to run this is sh /chroot/named.perms, but the -x option can be added if you want to watch it run:
# sh -x /chroot/named.perms + cd /chroot/named + chown -R root:named . + find . -type f -print + xargs chmod u=rw,og=r + find . -type d -print + xargs chmod u=rwx,og=rx + chmod o= etc/named.conf etc/rndc.conf + touch conf/secondaries/.empty + find conf/secondaries/ -type f -print + xargs chown named:named + find conf/secondaries/ -type f -print + xargs chmod ug=r,o= + chown root:named conf/secondaries/ + chmod ug=rwx,o= conf/secondaries/ + chown root:root var/ + chmod u=rwx,og=x var/ + chown root:named var/run/ + chmod ug=rwx,o=rx var/run/
A few notes on the files in the jail:
The conf/secondaries/ directory holds the transferred zone files received from the master nameservers, and they are in a separate place for two reasons. One, it helps separate files that you're allowed to modify (the master files) from those that you're not (the secondary).
But more importantly, even the nameserver user itself should not modify your master files, which could be possible if a vulnerability allowed a remote bad guy to run arbitrary code. If the db.master.com filesor its directory is writable, the bad guy could hijack a domain this way (with substantial effort). By putting the secondaries in a writable area, it limits the damage that can occur this way and helps keep things organized well.
options {
pid-file "/var/run/named.pid";
...
};
We're just about ready to try starting the nameserver, but since the daemon requires several key parameters - that we cannot omit - we prefer to put the full command in a script file. This small script is placed in /chroot/named.start:
#
# named.start
#
# Note: the path given to the "-c" parameter is relative
# to the jail's root, not the system root.
#
# Add "-n2" if you have multiple CPUs
#
# usage: named [-c conffile] [-d debuglevel] [-f|-g] [-n number_of_cpus]
# [-p port] [-s] [-t chrootdir] [-u username]cd /chroot/named# make sure the debugging-output file is writable by namedtouch named.run
chown named:named named.run
chmod ug=rw,o=r named.run
PATH=/usr/local/sbin:$PATH named \
-t /chroot/named \
-u named \
-c /etc/named.confand made executable with chmod a+x /chroot/named.start. We willnever start the nameserver with just a "named" command - we must use the script. So let's do so:
# sh /chroot/named.start
If all is well, the nameserver will start running quietly, and the ps -fCnamedcommand may show it running in the background. It should now be ready to accept nameserver requests, and we can test it with the dig command. Though we'll need to modify the file /etc/resolv.conf to contain the local machine's address.
Very old BIND nameservers relied on UNIX signals to control their behavior, and this has always been a lousy mechanism. BIND 8 introduced a ndc command that communicated over a control channel (a UNIX domain socket), but BIND 9 is now doing this via a TCP socket. This allows for remote operation (say, reloading it) of the nameserver. The old ndc command is gone, replaced with rndc, though not all of the commands are implmented yet.
Configuring rndc is a little tricky: BIND supports substantial functionality that involves the use of keys, and rndc uses just a small part of it. This is aggravated by the fact that getting even a little bit of this wrong will cause the mechanism to fail without meaningful diagnostics. It's been very frustrating.
The rndc command reads the file /usr/local/etc/rndc.conf for its configuration data, but we prefer to locate this file under our chroot area to keep an eye on the permissions and ownership. We'll create a link between the two shortly, but we prefer to build the file first.
#
# /chroot/named/etc/rndc.conf
#
options {
default-server 127.0.0.1;
default-key "rndckey";
};
server 127.0.0.1 {
key "rndckey";
};
key "rndckey" {
algorithm "hmac-md5";
secret "secret key here";
};
As with named.conf, the format is very peculiar and requires that all the semicolons go in the right places. In this file, the token "rndckey" is just the name of this key (as opposed to those keys required for other purposes), and any word could be used as long as they all agree in this file.
The variable part is the "secret", which is a long string of base-64-encoded data, and the BIND distribution provides a mechanism for creating one of these keys. The dnssec-keygen is used for generating multiple kinds of keys, and in our case we just care about generating one of them. We'll create the key into a file, then copy that key to our config file:
# cd /chroot/named/etc # /usr/local/sbin/dnssec-keygen -a HMAC-MD5 -b 256 -n HOST rndc Krndc.+157+13856 # cat Krndc.+157+13856.private Private-key-format: v1.2 Algorithm: 157 (HMAC_MD5) Key: hU9utBAdP6/dVKKfxOlv0bPOTnAd4A1qosMbs/dwVJI= ... # rm Krndc.+157+13856.*after key has been saved
Odd note: we've seen the dnssec-keygen program simply hang for long periods of time even on very fast machines, and upon investigation found that there was no available random numbers from the /dev/random device (!). The system collects entropy (aka "randomness") into a pool, and when it's depleted for whatever reason, it waits for more to show up. To get around this, add the@BTT{-r /dev/urandom} option to the command line just before the -aoption: this pulls from a different device that won't block on depleted entropy.
The Krndc.+157+13856 is the name of the key, and we don't believe that any part of this name is interesting to us. The key itself is created into output filenames based on the key name: kname.keyand kname.private. We see above the contents of the private key file, and the key itself ishU9utBAdP6/dVKKfxOlv0bPOTnAd4A1qosMbs/dwVJI=. This data must be inserted into the rndc.conf file:
...
key "rndckey" {
algorithm "hmac-md5";
secret "hU9utBAdP6/dVKKfxOlv0bPOTnAd4A1qosMbs/dwVJI=";
};
Now the rndc.conf file is created, the "key" files created by
# ln -s /chroot/named/etc/rndc.conf /usr/local/etc/rndc.conf # ln -s /chroot/named/etc/rndc.conf /etc/rndc.conf
Note that we also have /etc/rndc.conf point to the real file: this is simply as a convenience for the administrator who has to edit this file often - it's easier to type.
Now, the nameserver itself must be configured to listen on a control channel and use this particular key. In the same /chroot/named/etcdirectory, we reconsider the named.conf file: We must add two sections to the beginning of this file. We add a controlssection that describes the network addresses that named will listen on, and a key section describes the key it will use. Copy the secret key from above into the file in the obvious place:
controls {
inet 127.0.0.1 allow { 127.0.0.1; } keys { rndckey; };
};
key "rndckey" {
algorithm "hmac-md5";
secret "hU9utBAdP6/dVKKfxOlv0bPOTnAd4A1qosMbs/dwVJI=";
};
...
Note - previous versions of this document have suggested that the actual key name doesn't matter, but this has proven to be false. Once a key has a name, everybody has to agree on what that name is or things will fail outright.
The controlsand key sections must be first in the file: we're not surewhy it's a rule, but we're sure it is a rule.
This configuration tells named to listen only on the localhost interface, and as such won't accept any connections from the rest of the network. This is a useful security precaution, though it's possible to "open" the nameserver to accept connections from trusted others. Both of these config files contain these important private keys, so they must not be readable to nonprivileged users.
Now that the keys and controls have been set up properly, it's necessary to kick the nameserver to force it to reread the file. Simply send a SIGHUP (a -1) to the nameserver
# ps -fCnamed
UID PID PPID C STIME TTY TIME CMD
named 12527 1 0 12:42 ? 00:00:00 named -t /chroot/named {...}
# kill -1 1252712527 is process IDNow the nameserver should have reread the configuration files and started listening on the control interface. Now let's try rndc:
# /usr/local/sbin/rndc status number of zones: 2 debug level: 0 xfers running: 0 xfers deferred: 0 soa queries in progress: 0 query logging is OFF server is up and running
This indicates that all is well: the keys are correct. But a common error seen from a bad configuration is:
rndc: send remote authenticator: permission denied
This is often the only diagnostics seen, and it means you have to doublecheck your configuration files. We're sorry that we can't offer much more useful guidance on this front. We'll add notes as we find them.
Now that named is running correctly after being started "by hand", we usually wish for it to start automatically at boot time. The mechanism for this depends somewhat on the particular operating system, but we can give some overall guidelines. Automatic starting at boot time requires a base "init" file plus a couple of symbolic links.
The "base" startup file a small shell script that can start or stop the nameserver, and our version looks like:
#!/bin/sh## named#
export PATH=/usr/local/sbin:$PATH # needed for rndc
case "$1" in
start)
# Start daemons.
echo -n "Starting named: "
sh /chroot/named.start
echo
;;
stop)
# Stop daemons.
echo -n "Shutting down named: "
rndc stop
echo "done"
;;
esac
exit 0
We only support start and stop commands, and this has been more than good enough for us: those wanting a more "full featured" control file are welcome to be adventurous. Be sure to make the file executable:
Once the startup script is in place, we have to make some symbolic links to make it start in the appropriate runlevels. The filenames are modified from the "base" name to account for the order in which things are started: we want the nameserver to start just after the IP subsystem has started because so many of the other daemons depend on nameservice.
Locating this init file depends on the operating system, and we'll make notes in this table as we learn about them.
| Operating System | startup script | runlevel 2 file | runlevel 3 file |
|---|---|---|---|
| Red Hat Linux 6.X / 7.X | /etc/rc.d/init.d/named | /etc/rc.d/rc2.d/S11named | /etc/rc.d/rc3.d/S11named |
| Debian "Woody" | /etc/init.d/named | /etc/rc2.d/S18named | /etc/rc3.d/S18named |
To create the "rc" files, we use symbolic links. This sample is for the Red Hat Linux organization, and it can be altered for your operating system. We also believe that other runlevels are used for things like X11 windowing, but we don't ever use them. Your mileage may vary.
# cd /etc/rc.d # ln -s ../init.d/named rc2.d/S11named # ln -s ../init.d/named rc3.d/S11named
We recommend rebooting the system once to be sure that the nameserver starts properly on an automatic basis: it's very frustrating to have a power outage (say) three months from now and find out that DNS is not available: better to test this while your mind is thinking about nameservice.
(to be determined)
(to be determined)
The nameserver as installed only accepts rndc requests from the local system, but it's possible to do so over the network with a few changes in the config file.
The change is made in the named.conf file, and we add an entry to the controls section. The addition is made here in bold:
`
controls {
inet 127.0.0.1 allow { 127.0.0.1; } keys { rndckey; };
inet 192.168.1.31 allow { 127.0.0.1; # localhost
192.168.1.0/24; # local Ethernet
10.1.2.0/24; # network at home
172.27.217.6; # our consultant
} keys { rndckey; };
};
...
The first inet line requests that named listed on the localhost interface only, but the second requests that it listen on the computer's public Ethernet address (here, 192.168.1.31). The access control lines limit the connections to addresses in the given list, and we can include as many as desired in either single IP address notation or /nbits netbits notation. Be careful to put semicolons in all places that matter - it's easy to get wrong.
Now the config files must be reread: but if we're adding a new interface to listen on, we have to fully stop and restart the daemon. Since we've configured it to run as a non-root user, it's simply not able to bind to the privileged port (953/tcp) on the additional interface. So we must stop and restart.
Now to the remote machine.
On some other machine that's in the access list of the nameserver to be controlled, we must modify rndc.conf to add the keys. We presume here that the rndc.conf file will be controlling the local machine as well as the remote ones, so we'll be adding to the file, not modifying it.
#
# /chroot/named/etc/rndc.conf
#
options {
default-server 127.0.0.1;
default-key "rndckey";
};
server 127.0.0.1 {
key "rndckey";
};
key "rndckey" {
algorithm "hmac-md5";
secret "hU9utBAdP6/dVKKfxOlv0bPOTnAd4A1qosMbs/dwVJI=";
};
server remote.example.com {
key "remotekey";
};
key "remotekey" {
algorithm "hmac-md5";
secret "4TT2RNenA3JyHJAVHvWQTzgOo8GzqHowHUdB2i95peM=";
};NOTE: we use 127.0.0.1 instead of localhost above because the latter requires name resolution and the former doesn't. We've seen cases where we messed up the "localhost" resource record and causedrndc to stop working. This obviates that problem.
Here, the entry for the remote computer includes a definition of the key used by that remote, and it's clearly different than the key used for the local one.
To control the remote nameserver, we use rndc with the
# rndc -s remote.example.com status number of zones: 13 debug level: 0 xfers running: 0 xfers deferred: 0 soa queries in progress: 0 query logging is OFF server is up and running
We're able to stop and reload the remote server, but there is no wayto restart it via this mechanism. Be careful that you don't get surprised.
It's possible to run BIND 9 in a "split DNS" configuration, where the nameserver will give different answers to the same question depending on who's doing the asking. This is mainly useful for sites that run private networks inside with a limited public footprint on the outside.
We've only barely touched the whole "view" thing and can't offer any real advice in configuration, but we did run into one maddening problem regarding rndc that we'll touch on here.
When configuration changes have been made to the zone or config files, one normally can do
But when views are used, it fails in a very unhelpful way:
# rndc reload unixwiz.net rndc: 'reload' failed: not found
After fooling around with it for a while we realized that the command requires additional parameters: the class and view names. So we figured out that it's done this way:
# rndc reload unixwiz.net IN external
This requests the "internet" ( IN ) class and the external view: apparently these are not the defaults. We suspect that there are ways around this (say, by naming the view something else), but we very much think that the message from rndc was not very helpful. We might look into some patches to the 9.2.0 source to expand on this to provide a bit more feedback. It was very frustrating.
One of the really ugly problems with previous versions of BIND is that the various important files got scattered all over the filesystem, and the locations varied by platform as determined by the operating system vendor. It was just a nightmare to configure a chroot nameserver for a new platform.
BIND 9 makes this dramatically easier because they have decided to put everything under one place (usually /usr/local/), but there are enough files installed that it can be a bit overwhelming to know just what you need.
This is a list of files that were installed by our own configuration of BIND 9, and it might help you decide what you need to take for a binary-only distribution. Note that this was as of an early BIND 9 installation: we've not updated this since we have upgraded our own installation.
We've had all kinds of trouble building BIND 9.2.1 on SCO Open Server wtih gcc 2.7.2.2, though we think we've gotten around it. We have had zero luck with the stock C compiler (no "long long" support). Note for this platform can be found here.
Solaris and *BSD use a colon instead of a dot between the user name and the group name in the chown command. *BSD uses wheel as the main root group, and Solaris uses other.
... named_enable="YES" named_program="/usr/local/sbin/named" named_flags="-t /chroot/named -u named -c /etc/named.conf" ...
Rob Thomas has a greatSecure BIND Template document, with more coverage of the named.conf file than I provide.
Andrew St. Jean has a good document on setting up DNS and DHCPhere.
本日志由 flyinweb 于 2011-07-29 09:38:12 发表,目前已经被浏览 1183 次,评论 0 次;
作者添加了以下标签: bind9-chroot,bind,chroot;
引用通告:http://www.517sou.net/Article/641/Trackback.ashx
而且直接配置文件是效率最高的,通过其它驱动效率都相对较低,BDB
这个测试不太准确,看官方的测试结果:http://bind-dlz.sourceforg
为什么使用BDB时QPS这么低? 我在bind版本基本相似的环境中测试的
It is quite useful and interesting too.
VIRT 的上限是64G,也就是36位, cat /proc/cpuinfo的结果是:addre
昨天要准备用线程重写webbench,试验了下Fedora Linux 2.6.35.14
不明白您的具体的意思是什么?
已经发送到你QQ邮箱