发信人: aaa234(我只只在乎你)
整理人: zhcharles(2001-06-17 19:55:53), 站内信件
|
在FreeBSD上建立双DNS
----------------------------------------------------------------------
----------
作者:Yu-lin Cha
在一个 Firewall 系统上面,我们希望外部机器无法查寻内部机器的 IP 与
hostname 的对照表,但内部机器彼此间却需要互相认识。如果我们只能在一台机
器上建立 DNS server 而且它要能同时服务内外两个网络的使用者时,这样的要
求可以借着两种方法来达成。一是建立两个独立的 DNS 程序, 分别服务内外两个
网络的使用者,第二种方法是利用 BIND 本身的功能,来限制查寻(query)者的身
份。这边,我们选用第一种(也是比较复杂的)方法作示范。:p
此外,为了安全上的考量,我们也希望 DNS server 执行起来的时候,能使
用 root 以外的身份,并且能以 change root directory (chroot) 的动作。
本文采用的范例,外部网络为 140.109.7.* (*.wsl.sinica.edu.tw),内部
网络使用 192.168.7.* (*.ascc)。我们使用 FreeBSD 3.3-STABLE 为操作系统做
一个完整的练习,至于 Linux 的部份,已经有人写好了,请参考 Dave Lugo 的
文章,位置是 http://www.etherboy.com/dns/chrootdns.html
§前置作业§
在开始动作之前,我们需要一个安装好的 FreeBSD 3.x-STABLE 操作系统,
可以由 ftp://bsd.sinica.edu.tw/ 来安装。还需要 BIND-8.2.x 版的 DNS 程序
,可在 http://www.isc.org/ 找到,最新版的是 BIND-8.2.2-p5。这边假设操作
系统已经安装好了,并且 BIND-8.2.2-p5 也已经编译好了,放在 /usr/local/s
rc/bind8/src 下面。编译完 BIND 不须要执行 make install, 因为等一下我们
要手动把需要的程序安装到 chroot 的位置去。
§建立 chroot 区域§
假设我们 chroot 的位置是 /usr/local/BIND-ROOT/ 以下的指令可以把需要
的目录建立起来。
# mkdir /usr/local/BIND-ROOT
# cd /usr/local/BIND-ROOT
# mkdir dbfile_public
# mkdir dbfile_private
# mkdir dev
# mkdir etc
# mkdir lib
# mkdir sbin
# mkdir usr
# cd usr
# mkdir libexec
# ln -s ../lib lib
除了目录以外,还需要一些档案,使用以下的指令可以做出这些档案,有一
些动态链接库是 DNS 执行时需要的,也一并把他们复制过来。
# mknod /usr/local/BIND-ROOT/dev/null c 2 2
# chmod a+w /usr/local/BIND-ROOT/dev/null
# cp /etc/localtime /usr/local/BIND-ROOT/etc/
# cd /usr/local/BIND-ROOT/lib
# cp /lib/libc.so.3 .
# cp /lib/libutil.so.2 .
# ln -s libc.so.3 libc.so
# ln -s libutil.so.2 libutil.so
# cd /usr/local/BIND-ROOT/usr/libexec
# cp /usr/libexec/ld-elf.so.1 .
# cd /usr/local/BIND-ROOT/sbin
# cp /usr/local/src/bind8/src/bin/named/named .
# cp /usr/local/src/bind8/src/bin/named-xfer/named-xfer .
# strip *
现在回到 /usr/local/BIND-ROOT/etc 下面,准备一个最简单的 passwd 资
料,足够 DNS 执行就好了。这时候,还需要把放置 DNS 数据库的两个目录 dbf
ile_public 与 dbfile_private 的拥有者与与群组一并设定好。
# cd /usr/local/BIND-ROOT/etc
# echo "bind:*:53:" > group
# echo "bind:*:53:53:Bind Sandbox:/:/sbin/nologin" > passwd
# echo "bind:*:53:53::0:0:Bind Sandbox:/:/sbin/nologin" > master.pa
sswd
# chmod og-rwx master.passwd
# pkd_mkdb -d /usr/local/BIND-ROOT/etc master.passwd
# chown 53:53 /usr/local/BIND-ROOT/dbfile_public
# chown 53:53 /usr/local/BIND-ROOT/dbfile_private
在这里,还要做一个非常重要的动作,修改 syslogd 的设定,以便等一下
chrooted DNS 跑起来之后,能把纪录传送给 syslog daemon ,并且纪录到 sys
logd 预设的 /var/log/messages 档案里面。使用任何编辑工具( 例如 vi),编
辑 /etc/rc.conf 档案,把里面的 syslogd_flags="" 改成 syslogd_flags="-l
/usr/local/BIND-ROOT/dev/log" 如果没有 syslogd_flags 就自己增加一行进
去。
重新开机,或是用下面的指令重新跑一次 syslog daemon,这样 chroot 区
域就算是完全准备好了。
# killall syslogd; /usr/sbin/syslogd -l /usr/local/BIND-ROOT/dev/lo
g
§编辑 DNS 的设定档案§
首先编辑外部网络的 DNS 设定文件 dbfile_public/named.conf 如下,档案
中以 # 开头的都是注解。
#===================================================================
=
# named.conf for dbfile_public directory. (public network)
#-------------------------------------------------------------------
-
# NOTE: This is a *chrooted* session. Do *NOT* break the paths below
.
#===================================================================
=
options {
directory "/dbfile_public";
pid-file "/dbfile_public/public.pid";
named-xfer "/sbin/named-xfer";
# specify where the request comes from.
query-source address * port 53;
listen-on { 127.0.0.1; 140.109.7.4; };
allow-transfer { 140.109.7/24; 140.109.1/24; 192.168.7/24; };
forwarders { 140.109.1.10;};
};
# controls of name daemon
controls {
unix "/dbfile_public/ndc_public"
perm 0600
owner 0
group 0;
};
#---
# cache hint
#---
zone "." {
type hint;
file "db.cache";
};
#---
# localhost
#---
zone "0.0.127.in-addr.arpa"{
type master;
notify no;
file "db.local";
};
#---
# "*.wsl.sinica.edu.tw" (140.109.7.*)
#---
zone "wsl.sinica.edu.tw" {
type master;
file "db.wsl";
};
zone "7.109.140.in-addr.arpa" {
type master;
file "db.140.109.7";
};
#===================================================================
=
# END OF FILE "/dbfile_public/named.conf".
#===================================================================
=
编辑编辑内部网络的 DNS 设定文件 dbfile_private/named.conf 如下,档
案中以 # 开头的都是注解。
#===================================================================
=
# named.conf for dbfile_privete directory. (private network)
#-------------------------------------------------------------------
-
# NOTE: This is a *chrooted* session. Do *NOT* break the paths below
.
#===================================================================
=
options {
directory "/dbfile_private";
pid-file "/dbfile_private/private.pid";
named-xfer "/sbin/named-xfer";
# only allow the query comes from my private network.
allow-query { 192.168.7/24; };
# specify the private-side ip on this machine.
listen-on { 192.168.7.1; };
# if any things I don\'t know, I will ask my public-side name daemo
n.
forwarders { 140.109.7.4; };
# only the machines in private network can do "ZONE-TRANSFER".
allow-transfer { 192.168.7/24; };
};
# controls of name daemon
controls {
unix "/dbfile_private/ndc_private"
perm 0600
owner 0
group 0;
};
#---
# cache hint
#---
zone "." {
type hint;
file "db.cache";
};
#---
# localhost
#---
zone "0.0.127.in-addr.arpa"{
type master;
notify no;
file "db.local";
};
#---
# private network, "*.ascc" (192.168.7.*)
#---
zone "ascc" {
type master;
notify no;
file "db.ascc";
};
zone "7.168.192.in-addr.arpa" {
type master;
notify no;
file "db.192.168.7";
};
#===================================================================
=
# END OF FILE "/dbfile_private/named.conf".
#===================================================================
=
有了设定档之后,就可以根据设定文件里面的资料编辑 DNS 数据库档案,分
别是 dbfile_public 目录下的 db.wsl db.140.109.7 以及 dbfile_private 目
录下的 db.ascc db.192.168.7 这四个档案。db.local 与 db.cache 这两个档案
,可以在 BIND-8 套件里面找到或是在 www.isc.org 网站上也有,直接复制进去
就可以用了,不须要修改。
§起动 DNS 程序§
在 FreeBSD 起动 DNS 的传统方法是在 /etc/rc.conf 里面把 name daemon
的设定打开,也就是 named_enable="YES",但是这种方法只对标准的 name da
emon 有用,因此我们需要手动执行 DNS 而非用这种方法。
首先将 /etc/rc.conf 中加入一行 named_enable="NO",然后编辑一个 she
ll script 档案 /usr/local/sbin/dnsctl 以方便以后对 DNS 程序的控制。以下
是 /usr/local/sbin/dnsctl 的内容,
#!/bin/sh
#
# dnsclt Start/Stop the internal and external name daemons
#
# description: dnsctl is a script for starting DNS servers
# processname: named
#
# define command here
#
ECHO=/bin/echo
CHROOT=/usr/sbin/chroot
KILLALL=/usr/bin/killall
#
# define variables here
#
DNSHOME=/usr/local/BIND-ROOT
LOCALNAMED=/sbin/named
PUBLIC_CFG=/dbfile_public/named.conf
PRIVATE_CFG=/dbfile_private/named.conf
DAEMONNAME=named
DNSUSER=bind
DNSGROUP=bind
#
# run commands here
#
case "$1" in
start)
$ECHO -n "Starting DNS services: ...."
$CHROOT $DNSHOME $LOCALNAM
|
|