BIND9 域名服务器更安全(一)

/ns/wz/net/data/20010524051455.htm

作者:wuming < mailto:wuming@geekbone.org >
主页:http://geekbone.org
日期:2001-5-15

---[[ 前言 ]]----------------------------------------------------------
由于作者工作中管理数个域名服务器,在最近工作当中对BIND9和BIND8进行了一些比
较。从中的到了一些心得体会,在看过backend的“BIND 8+ 域名服务器安全增强”
一文后,发觉国内的确还没有太多关于DNS服务安全配置方面的较为完整的文章,在这
里拙笔翻译和写一些我所了解如何安全配置BIND,希望能给系统管理员一些帮助。

在此文章中将介绍如何在两台LINUX(内核:2.2.x和2.4.x)机器下安装chroot过
的BIND版本9。同时还举出一些如何设置TSIG的例子等等。通过这篇文章希望能够帮
助使用BIND8的管理员向BIND9移植。



---[[ 内容简介 ]]-------------------------------------------------------

#前言
#概况,BIND8和BIND9的区别
#安装和设置BIND //(上)
#设置范例(named.conf, rndc)
#参考资料
#更多有关资料
#结束语 //(下)



---[[ 概况,BIND8和BIND9的区别 ]]----------------------------------------

按照ISC的调查报告,BIND是世界上使用最多最广泛的域名服务系统。不论你的邮件服
务器,WEB服务器或者其他的services如何的安全可靠,DNS的故障会给你带来用户根本
无法访问这些服务。

BIND,也是我们常说的named,由于多数网络应用程序使用其功能,所以在很多BIND的
弱点及时被发现。主要分为三个版本:

1:v4,1998年多数UNIX捆绑的是BIND4,已经被多数厂商抛弃了,除了OpenBSD还在使
用。OpenBSD核心人为BIND8过于复杂和不安全,所以继续使用BIND4。这样一来BIND8/9
的很多优点都不包括在v4中。

2:v8,就是如今使用最多最广的版本,其详细内容可以参阅“BIND 8+ 域名服务器安
全增强”<http://security.nsfocus.com/showQueryL.asp?libID=530>


3:v9,最新版本的BIND,全部重新写过,免费(但是由商业公司资助),也添加了许
多新的功能(但是安全上也可能有更多的问题)。BIND9在2000年十月份推出,现在稳
定版本是9.1.2。

几家大公司对BIND9的评价十分高,称BIND9十分专业和把DNS community提升到一个新
的高度。


我们是否应该注意DNS的安全问题?当然,一个管理不善的DNS可能带来以下一些值得一
提危险。

1,如果任意允许 zone transfer,一个攻击者能够轻而易举的得到有关zone的信息,
这样其中比如route,其他重要hosts/intern hosts都被泄露。

2,Denial of service,拒绝服务攻击可能带来危害:

・你的网站不能访问,也不能访问其他网站,因为没有域名解译。
・邮件不能接收(虽然一些网站有缓冲,但是不会超过几个小时或者一两天时
间。)
・攻击者可以伪装DNS服务提供假的DNS信息。这会带来什么后果?

3,彻底没有防护:如果攻击者能够伪造你的DNS数据或者欺骗其它网站相信假的DNS数
据(称DNS poisoning),后果不堪设想……

+ 假造你的网页,并且很容易的骗出用户名和密码,或者其他敏感数据。
+ 所有的邮件到达你的服务器之前可以被拷贝,修改或者删除。
+ 如果使用防火墙或者其他服务涉及DNS域名相信(auth)的服务,将彻底没有
任何防护作用。比如一个网络代理只允许 *.mydomain.com 访问。攻击者很
容易添加他自己的域名。对于防火墙比如只通过 admin.mydomain.com 进入
,那么入侵者添加其IP就可以了。

2000年底由于多个BIND远程溢出,使DNS成为黑客最喜好攻击的目标之一。


应该做些什么?BIND主要有哪些危险和弱点?

1,首先应该隔离BIND服务器,不应该在DNS服务器上跑其他服务,尤其是允许普通用户
登陆。减少其它的服务可以缩小被攻击的可能性,比如混合攻击。

2,双DNS服务器,第二个(secondary DNS)应该安装在另外一个网络连接上,(不走同
一个ISP等)。如果你的DNS服务器因为某种原因断线,至少还有一个缓冲。这样一来比
如EMAIL等都不会丢失。一般可以维持四天(应该能够修好了吧?!)。

3,使用最新版本的BIND!(比如 8.2.3 或者 9.1.2)

4,权限管理(Access Control),限制 zone transfer 的范围,不给攻击者得到你局
域网的信息。可以使用传递签名(transaction signatures)等。

5,用最低的权限执行BIND,即非root用户和严格的umask设置

6,使用chroot对执行BIND时添加更多的隔离,这样BIND对系统和其他服务带来修改和
破坏会更困难。

7,虽然有些人不相信隐蔽BIND的序列号对安全有什么特别的好处,可以有效的组织大
多数script kiddie的扫描。对于专业的骇客是另外一回事。

8,BIND的纪录应该常常分析,对于不寻常的记录可以使用内设的checker。

9,backend 说:对BIND(还有其它应用服务)进行安全增强配置的基础上,安全管理
员仍然需要密切关注最新的安全公告、安全补丁和安全技术,经常与专业的计算机安全
专家交流知识和经验。


文章将具体介绍4,5,6,应该能够达到相对的安全高度。


BIND9还是BIND8?

一些值得一提的区别是:

・如果named.conf有语法错误,BIND9会记录错误和继续执行域名服务,而
BIND8只会记录错误和segmentation fault或者core dump!
・对于事务签名(TSIG)比BIND8有更好的支持。
・新的start/stop/reload工具等等。比如rndc,附有新的Domain更新方式。
・zone文件语法检测,比如TTL行必须存在。
・named.conf中:
# BIND8中的 check-name 和 statistics-interval不在使用
# 缺省属性 auth-nxdomain 自动为"no",而BIND8是"yes"
・不需要root服务器列表,就是named.boot或者root.hint包含在server中了

・可以使用多进程域名服务(在你的机器threads支持良好条件下),如:
% ps ax |grep named
3947 ? S 0:00 /usr/local/sbin/named -u nobody
3948 ? S 0:00 \_ /usr/local/sbin/named -u nobody
3949 ? S 0:00 \_ /usr/local/sbin/named -u nobody
3950 ? S 0:00 \_ /usr/local/sbin/named -u nobody
・BIND9不支持名字认定,这样一来你就有可能设置更多的域名,比如下划线
。但还是不一定能解释带有怪字符域名。
・更多请参阅 http://sysadmin.oreilly.com/news/dnsandbind_0401.html


---[[ 安装和设置BIND ]]--------------------------------------------------

以下是我如何在LINUX机器上安装和设置BIND9的过程,首先检查你是否有gcc,ass等
BIND需要软件。

1,编译BIND

下载最新的BIND,解开压缩,编译。做这一步不需要root权限。(建议先安装GNU make
,如果你没有的话)首先在主域名服务机器上安装。

./configure --disable-threads
(对于差一点的机器不建议使用threads功能)

一般来说:
./configure

然后就可以编译了:
make

现在变成 root,暂时将BIND装在临时目录(比如/tmp/),并且生成一个tarball(塔塔球?)。

su
umask 027
#生成文件权限
make install DESTDIR=/tmp


#注意,在这里我使用了strip指令,并不一定需要,只是将所有Debug数据删
除,能将本身约60MB的BIND减肥成18MB左右。(版本9.1.2)
cd /tmp/usr/local/
strip bin/* sbin/* lib/*
rm -rf include
#删除 include 也是可选择的,我是为了减少空间。
tar -cf - * | gzip > bind9.tar.gz

现在可以把bind9.tar.gz移到一个安全的目录,并且删除在/tmp不必要的文件


BIND文献可以在 doc/arm/Bv9ARM.html 找到,有时间值得一读。

2,设置 chroot 和安装BIND

chroot() 设置是为了是BIND更加安全,使入侵者即使攻入也无法阅读任何系统文件,
比如多数允许匿名FTP使用chroot()。

1,首先指定你在哪里安装BIND,指定权限应该是022。

export jail='/usr/local/dns'
umask 022

2,建立目录和连接 chroot 运行环境。

mkdir $jail
cd $jail
mkdir -p {dev,usr,var,etc};
mkdir -p var/{run,log,named} usr/lib;
mkdir -p usr/local/etc/
mkdir -p usr/share/lib/zoneinfo

3,建立帐号
groupadd named
useradd -d /tmp -s /bin/false -g named -c "BIND daemon" -m named
#在chroot目录下生成必要passwd等文件。
grep named /etc/passwd >> $jail/etc/passwd
grep named /etc/shadow >> $jail/etc/shadow
grep named /etc/group >> $jail/etc/group

#禁止BIND帐号使用FTP
echo "named" >>/etc/ftpusers

#也许你 ftpusers 在别的目录下。

4,安装编译好的BIND,首先拷贝到 chroot() 目录下。

cp bind9.tar.gz $jail
cd $jail
tar -xvzf bind9.tar.gz

5,拷贝为chroot环境的系统文件
cp /etc/{syslog.conf,nsswitch.conf,resolv.conf,timezone} $jail/etc

6,查看named需要哪些lib文件

ldd /usr/local/dns/sbin/named
#将这些文件拷贝到lib目录下,在Linux下例如:
cp -p /lib/libnsl.so.1 \
/lib/libpthread.so.0 /lib/libc.so.6 \
/lib/ld-linux.so.2 /usr/local/dns/lib

(如果拷贝了以上文件后BIND不工作,根据“经验”以下的文件最好拷贝到lib
木录下。)
cp /lib/ld.so* /lib/libnss_files* /usr/local/dns/lib/

7,设置时区和其他系统设置。

mkdir -p /usr/local/dns/usr/share/zoneinfo;
cp -p /usr/share/zoneinfo/MET /usr/local/dns/usr/share/zoneinfo/MET

cd /usr/local/dns/dev
mknod tcp c 11 42
mknod udp c 11 41
mknod log c 21 5
mknod null c 13 2
mknod zero c 13 12
chgrp sys null zero
chmod 666 null
mknod consolg c 21 0
mknod syscon c 0 0
chmod 620 syscon
chgrp tty syscon
chgrp sys consolg
chgrp sys conslog

8,生成域名数据文件

mkdir -p /usr/local/dns/var/named;

3,设置DNS数据

cd /usr/local/dns/etc/
touch named.conf
chown root:named named.conf
chmod 640 named.conf

vi named.conf
#你完全可以使用其它编辑器

我们应该在named.conf里面写些什么?在这里做一个简单例子,比如如何设置
geekbone.org这个域名。

1:主DNS服务器,假设地址为192.168.1.3

在 /usr/local/dns/var/named 下生成 geekbone.zone, geekbone.rev,
dns.geekbone.org
以及 named.conf.primary
(以上文件分别可以在这篇文章末尾找到,以免产生疑惑。)

2:副DNS服务器,假设地址为192.168.1.4
生成以下几个文件, geekbone.zone, geekbone.rev 和
named.conf.secondary

下面我会具体介绍一些如何设置BIND,首先我们拷贝好和修改好这些文件后,用BIND
工具检查语法。
/usr/local/dns/sbin/named-checkconf /usr/local/dns/etc/named.conf
/usr/local/dns/sbin/named-checkzone
/usr/local/dns/var/named/geekbone.rev
/usr/local/dns/sbin/named-checkzone
/usr/local/dns/var/named/geekbone.zone
/usr/local/dns/sbin/named-checkconf
/usr/local/dns/var/named/dns.geekbone.org
#注意,很多中国网管没有.rev的权限,故可忽略rev和zone文件。

4,设置“监狱”模式

首先设置named必要的权限,并且禁止SUID/SGID文件等。以下是如何安全运行BIND最过
分的一种做法,我们称PARANOID模式。管理员应当根据服务器情况而设置。

cd /usr/local/dns/
chgrp -R named *
chmod -R g-w var;

#在两个DNS服务器上,只需要允许建立和修改文件权限。
chown -R root:named /usr/local/dns/var/named/
chmod 770 /usr/local/dns/var/named/

#生成空 log 和 pid 文件:
touch /usr/local/dns/var/log/all.log
/usr/local/dns/var/run/named.pid
chown named:named /usr/local/dns/var/log/all.log
/usr/local/dns/var/run/named.pid

#给 named 权限写 log 和 pid 文件
chgrp -R named /usr/local/dns/var/log/ /usr/local/dns/var/run/
chmod 770 /usr/local/dns/var/log/ /usr/local/dns/var/run/
chmod -R o-rwx /usr/local/dns/var/log/ /usr/local/dns/var/run/

#给 named 访问其他设置文件
chgrp named /usr/local/dns/etc
chown root:named /usr/local/dns/etc/named.conf
chmod 640 /usr/local/dns/etc/named.conf
chmod 755 /usr/local/dns/etc

#检查BIND目录,查看是否有SUID和SGID程序,如果除去SUID或SGID权限
find /usr/local/dns/ -type f -exec chmod ug-s {} \;

#除去普通用户阅读权限
chmod -R o-rwx * /usr/local/dns/usr/

5,启动BIND

OKEY!我们已经将BIND设置好了,下面让我们试着启动BIND!

1,以下两条指令根据 syslog.conf 设置不同,种类不一。
tail -f /var/log/messages | grep named &
tail -f /var/log/daemon.log | grep named &
#为了方便观察BIND启动时所发生的事情。

2,启动 named
/usr/local/dns/sbin/named -t /usr/local/dns/ -u named
#-t表示 chroot 的目录 -u表示用户

3, 检查错误,如果你发现一些设置错误,修改并且重新启动。
kill -1 `cat /usr/local/dns/var/run/named.pid`

4,如果一切正常,那么恭喜你的BIND安装成功了!下一步就是在系统启动
的时候自动启动BIND,这里有设置的一个BIND启动器。/etc/init.d/dns,
一般只需要连接到 /etc/rc2.d/S50dns 和 /etc/rc2.d/K50dns 就可以了。



---[[ #设置范例(named.conf, rndc) ]]------------------------------------
(待续)