发信人: 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 
 
 
 
  | 
 
 
 |