BindDNS安装调试及FAQ
2010-08-28 16:48:20 阿炯

一.、Bind 简介
Bind是一款开放源码的DNS服务器软件,Bind由美国加州大学Berkeley分校开发和维护的,全名为Berkeley Internet Name Domain它是目前世界上使用最为广泛的DNS服务器软件,支持各种unix平台和windows平台。本文将介绍它在Red hat Linux中最基本的安装和配置。

二.、软件的相关资源
官方网站:http://www.bind.com/
源码软件包:Bind 是开源的软件,可以去其官方网站下载。http://www.isc.org/index.pl/sw/bind/ ,目前最新版本为bind-9.6.x。
帮助文档:http://www.isc.org/index.pl/sw/bind/ 有该软件比较全面的帮助文档。
FAQ:http://www.isc.org/index.pl/sw/bind/ 回答了该软件的常见问题。

三.、软件的安装
1.安装
由其官方网站中下载其源码软件包bind-9.6.x. tar.gz。接下来我将对安装过程的一些重要步骤,给出其解释:
[root@localhost root]#tar xzvf bind-9.6.x. tar.gz
[root@localhost root]#cd bind-9.6.x
[root@localhost bind-9.6.x]#./configure
[root@localhost bind-9.6.x]#make
[root@localhost bind-9.6.x]#make install
tar xzvf bind-9.6.x.tar.gz 解压缩软件包。
./configure 针对机器作安装的检查和设置,大部分的工作是由机器自动完成的,但是用户可以通过一些参数来完成一定的设置,其常用选项有:
./configure --help 察看参数设置帮助。
--prefix= 指定软件安装目录(默认/usr/local/)。
--enable-ipv6 支持ipv6。
可以设置的参数很多,可以通过 -help察看需要的,一般情况下,默认设置就可以了。默认情况下,安装过程是不会建立配置文件和一些默认的域名解析的,不过并不妨碍,可以从下载一些标准的配置文件(http://www.bind.com/bind.html),也可以使用本文所提供的样例文件。
默认情况下,安装的deamon为/usr/local/sbin/named
默认的主配置文件,/etc/named.conf(须手动建立)。
2.启动:
[root@localhost root]# /usr/local/sbin/named -g
/usr/local/sbin/named默认情况是一个后台deamon ,-g选项表示前台运行,并将调试信息打印到标准输出,这在我们安装调试阶段是非常有帮助的。
如果建立了配置文件和域名解析文件(关于怎样建立将在下面的部分讲到),ps aux 应该可以查到named 的进程,或netstat -an 也可以看到53端口的服务已经起来了。(DNS默认端口为53),如果要设置开机自启动DNS server,只需在/etc/rc.d/rc.local中加入一行:
/usr/local/sbin/named

#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.
touch /var/lock/subsys/local
/usr/local/sbin/named

四.软件的配置
1.主配置文件
默认安装主配置文件的位置为:/etc/named.conf
下面逐步分析一个比较基础的配置文件:(注:named配置文件采用和c语言相同的注释符号)。
(1) log options
/*
* log option
*/
logging {
channel default_syslog { syslog local2; severity error; };
channel audit_log { file "/var/log/named.log"; severity error; print-time yes; };
category default { default_syslog; };
category general { default_syslog; };
category security { audit_log; default_syslog; };
category config { default_syslog; };
category resolver { audit_log; };
category xfer-in { audit_log; };
category xfer-out { audit_log; };
category notify { audit_log; };
category client { audit_log; };
category network { audit_log; };
category update { audit_log; };
category queries { audit_log; };
category lame-servers { audit_log; };
};
这一部分是日志的设置,其中最主要的是file "/var/log/named.log" 这一句指定了日志文件的位置,要正常启动named,必须要保证这一文件是存在的,并且named 进程对它有读写权限。
(2) options
options {
directory "/etc/namedb";
listen-on-v6 { any; };
// If you've got a DNS server around at your upstream provider, enter
// its IP address here, and enable the line below.  This will make you
// benefit from its cache, thus reduce overall DNS traffic in the Internet.
forwarders {
your.upper.DNS.address;
};
/*
* If there is a firewall between you and nameservers you want
* to talk to, you might need to uncomment the query-source
* directive below.  Previous versions of BIND always asked
* questions using port 53, but BIND 8.1 uses an unprivileged
* port by default.
*/
// query-source address * port 53;
/*
* If running in a sandbox, you may have to specify a different
* location for the dumpfile.
*/
dump-file "/etc/named_dump.db";
};
这一部分是一些基本的配置项:
directory "/etc/namedb"; 指定域名解析等文件的存放目录(须手动建立);
listen-on-v6 { any; }; 支持ipv6的请求;
forwarders {
your.upper.DNS.address;
}; 指定前向DNS,当本机无法解析的域名,就会被转发至前向DNS进行解析。
dump-file "/etc/named_dump.db"; 指定named_dump.db文件的位置。
(3) 线索域和回环域
// Setting up secondaries is way easier and the rough picture for this
// is explained below.
// If you enable a local name server, don't forget to enter 127.0.0.1
// into your /etc/resolv.conf so this server will be queried first.
// Also, make sure to enable it in /etc/rc.conf.
zone "." {
type hint;
file "named.root";
};
zone "0.0.127.IN-ADDR.ARPA" {
type master;
file "localhost.rev";
};
指定线索域和本地回环域,这一部分使用一些标准的例子就可以。file "named.root"; 指定该域的解析文件,其目录为options中directory "/etc/namedb";指定的。在本例中为/etc/namdb。
(4)自定义域
zone "test.com" {
type    master;
file    "zone.test ";
};
zone "0.168.192.in-addr.arpa" {
type    master;
file    "zone. test.rev";
};
zone "4.0.0.f.0.5.2.0.1.0.0.2.IP6.ARPA" {   
type master;
allow-transfer { any;};
allow-query { any; };       
file "ipv6.rev";
};
zone "lowerlevelzone.test.com" {
type    slave;
masters {
192.168.0.1;
};
};
这一部分是配置文件中我们需要重点关心的部分:
zone "test.com" {
type master;
file "zone.test ";
}; 设定test.com域;

type master 指明该域主要由本机解析;
file "zone.test "指定其解析文件为zong.test,目录为options中设定的目录本例中为/etc/named。
zone "0.168.192.in-addr.arpa" {
type master;
file "zone. test.rev";
}; 指定ipv4地址逆向解析

type master 指明该域主要由本机解析;
file "zone.test.rev "指定其解析文件为zone.test.rev,目录为options中设定的目录本例中为/etc/named。

zone "4.0.0.f.0.5.2.0.1.0.0.2.IP6.ARPA" {
type master;
allow-transfer { any;};
allow-query { any; };
file "ipv6.rev";
};指定ipv4地址逆向解析

type master 指明该域主要由本机解析;
file " ipv6.rev "指定其解析文件为ipv6.rev,目录为options中设定的目录本例中为/etc/named。
zone "lowerlevelzone.test.com" {
type slave;
masters {
192.168.0.1;
};
}; 设定lowerlevelzone.test.com域;

type slave 指明该域主要由低一级的域名服务器解析;
masters {
192.168.0.1;
}; 指定低一级的域名服务器ip地址。
到此我们就初步建立了一个标准的named 的主配置文件,接下来建立对应的域名解析或逆向解析文件。

2.域名解析和IP地址逆向解析文件:
(1) 域名解析:
/etc/namedb/zone.test

; From: @(#)localhost.rev    5.1 (Berkeley) 6/30/90
; $FreeBSD: src/etc/namedb/PROTO.localhost.rev,v 1.6 2000/01/10 15:31:40 peter Exp $
;
; This file is automatically edited by the `make-localhost' script in
; the /etc/namedb directory.
;
@    IN    SOA    ns.test.com. root.test.com.(
2005030116; Serial
3600    ; Refresh
900    ; Retry
3600000    ; Expire
3600 )    ; Minimum
IN    NS    ns.test.com
;
ns        IN    A    192.168.0.1
www6    IN    AAAA    2001:250:f004::10
www    IN    A    192.168.0.2

本文件前半部分是一些默认的参数设置,只需把域名改成对应得你要设置的域就行,其余的不用过分深究,如果读者有兴趣可以查阅相关的手册文档。(注意,IN NS ns.test.com;这一条必须有,来指定本域的域名服务器;域名必须以"."尾。)本文件的第二部分(倒数三行),指定了该域上的主机:
ns IN A 192.168.0.1
ns 为主机名,A代表地址类型为IPV4地址,192.168.0.1 是实际ip地址,这一条记录的含义是ns.test.com 的ip地址为 192.168.0.1
www6 IN AAAA 2001:250:f004::10
www6为主机名,AAAA代表地址类型为IPV6地址,2001:250:f004::10 是其IPV6地址,这条记录的含义是www6.test.com 的ip地址是2001:250:f004::10。

(2)IP地址逆向解析:
ipv4 逆向解析:
/etc/namedb/zone.test.rev
;    From: @(#)localhost.rev    5.1 (Berkeley) 6/30/90
; $FreeBSD: src/etc/namedb/PROTO.localhost.rev,v 1.6 2000/01/10 15:31:40 peter Exp $
;
; This file is automatically edited by the `make-localhost' script in
; the /etc/namedb directory.
;
@    IN    SOA    ns.test.com. root.test.com.(
2005030116; Serial
3600    ; Refresh
900    ; Retry
3600000    ; Expire
3600 )    ; Minimum
IN    NS    ns.test.com
;
1    IN    PTR        ns.test.com.
2    IN    PTR        www.test.com.
ipv6 逆向解析:
/etc/namedb/zone.test.rev
; From: @(#)localhost.rev    5.1 (Berkeley) 6/30/90
; $FreeBSD: src/etc/namedb/PROTO.localhost.rev,v 1.6 2000/01/10 15:31:40 peter Exp $
;
; This file is automatically edited by the `make-localhost' script in
; the /etc/namedb directory.
;
@    IN    SOA    ns.test.com. root.test.com.(
2005030116; Serial
3600    ; Refresh
900    ; Retry
3600000    ; Expire
3600 )    ; Minimum
IN    NS    ns.test.com
;
10.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0        IN    www6.test.com.
这里
10.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN www6.test.com.
与主配置文件/etc/named.conf中的
zone "4.0.0.f.0.5.2.0.1.0.0.2.IP6.ARPA"
"10.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0" + "4.0.0.f.0.5.2.0.1.0.0.2" 刚好组成点分的32位16进制逆序ipv6地址。实际上,ip地址逆向解析由于缺乏统一的管理和相关的标准,这项服务的使用比较混乱,可以考虑不启动该服务。所以在这里只给出两个例子,就不过多解释了。

五.安装使用的一些经验:
1.带调试信息的启动
named -g
/usr/local/sbin/named默认情况是一个后台deamon ,-g选项表示前台运行,并将调试信息打印到标准输出,这在我们安装调试阶段是非常有帮助的。

2.客户端命令nslookup简介
windows ,linux 平台均支持此调试命令。
键入nslookup即进入与服务器交互状态,这时键入域名或ip地址就可以向服务器正向或逆向查询。
>www.test.com 正向域名解析
>192.168.0.1 逆向IP解析
>set type=AAAA 设置查询地址类型为IPv6地址类型。
>set type=A 设置查询地址类型为IPv4地址类型。
>exit 退出。
参考资料:
[1]:http://www.bind.com/
[2]:http://www.isc.org/index.pl?/sw/bind/
[3]:ipv6.bupt.edu.cn 

BIND 9的FAQ
本文译自BIND主网站上的一篇文章:http://www.isc.org/products/BIND/FAQ.html。应该说,这些问题都非常典型,对BIND 9用户的日常维护和管理可以提供不小的帮助。

1. 当我在Linux 2.2.x上使用以--enable-threads选项编译的bind程序时,为什么-u参数不起作用?
答:Linux线程并没有完全实现Posix线程(pthreads)标准。特别是setuid()只能对当前线程起作用,而不适用于整个进程。正是由于此项限制,Linux上的BIND 9就无法像在其他支持的系统平台上一样使用setuid()。在创建线程之前不能调用setuid(),因为服务器只有在线程启动之后才能开始监听预留端口。
对于2.2.18或2.3.99-pre3以及更新的内核而言,则能在调用setuid()之后仍然保持可用性。这使得BIND 9可以更早些调用setuid(),而同时又保持了绑定预留端口的能力。这是针对Linux所作的特别处理。
在2.2内核上,BIND 9的确放弃了许多root权限,所以相对于那些没有放弃权限的root进程而言,这会更加安全一些。
如果Linux线程已经正常工作,那么这项限制也就不复存在。用户可以使用--disable-threads选项(这是默认选项)来编译BIND9,这样会生成一个非线程的版本,用户能够使用-u选项。

2、为什么named的日志中会给出警告信息"no TTL specified - using SOA MINTTL instead"?
答:你的zone文件不符合RFC1035标准。你可以使用两种方法来解决此问题:
1)在zone文件的开头加入一行对TTL的定义,例如:$TTL 86400
2)在zone文件的第一条记录中包含TTL字段,例如:example.com. 86400 IN SOA ns hostmaster

3、为什么我在Linux上会看到5个(或者更多)的named副本?
答:在ps下每个Linux线程也会像进程一样显示出来。一般运行的线程个数为n+4,这里n表示CPU的数目。注意在内存量的使用上并不遵从累加的原则;如果每个进程使用10M内存,那么所有线程总共也只使用10M内存。

4、为什么即便我在Linux系统上用root身份运行BIND 9,在访问配置文件或zone文件时,仍然会得到关于"permission denied"错误的日志?
答:在Linux上,BIND 9在启动时就放弃了绝大部分root权限,这其中就包括打开其他用户所属文件的权限。因此,如果服务器是以root身份运行的,那么配置文件和zone文件也应该由root所有。

5、为什么我得到类似于"dns_zone_load: zone foo/IN: loading master file bar: ran out of space"的错误提示?
答:这通常是由于TXT记录中少了一个引号所致。检查所有TXT记录是否都包含了完整的引号。

6、我怎样能够在Linux上从多线程named生成一个可用的core文件?
答:如果Linux内核是2.4.7或更新的版本,多线程core导出(dump)是可用的(也就是说,将导出正确的线程)。否则,如果使用的是2.2内核,那么需要应用在contrib/linux/coredump-patch中的内核补丁并重新编译内核。该补丁可以使多线程程序导出正确的线程。

7、我怎样限制别人查询我的服务器版本?
答:在named.conf的"options"段中放置"version"选项,并将其值设成与你实际使用版本不同的其他版本。注意:这样做不能避免攻击,反而可能会妨碍别人对你服务器问题的诊断尝试,而且这同样可能成为别人鉴别你服务器的标志。

8、我怎样限制只有远程用户才能查询服务器版本?
答:当存有版本信息的内部视图被最后匹配时,下面的视图语句将拦截查询。上面一问回答中的警告在这里同样适用。
view "chaos" chaos {
match-clients { ; };
allow-query { none; };
zone "." {
type hint;
file "/dev/null"; // or any empty file
};
};

9、"no source of entropy found"或"could not open entropy source foo"是什么意思?
答:服务器需要信息熵(entropy)源来执行特定的操作,通常这与DNSSEC相关。这些信息提示没有信息熵源。在有/dev/random或类似设备的系统上,默认会使用它们。信息源也可以通过named.conf中的random-device选项来定义。

10、我安装了BIND 9并且重新启动了named,但是它仍然是BIND 8,这是为什么?
答:BIND 9默认安装在/usr/local下。而BIND 8通常安装在/usr下。检查是否正确的named在运行。

11、我尝试使用TSIG来验证动态更新或者zone传输。我确信密钥设置是正确的,但是服务器仍然拒绝TSIG,为什么?
答:这可能是时钟不准的问题。检查客户端的时钟和服务器上的是否同步(例如使用ntp)。

12、我尝试编译BIND 9,但"make"却因为某些文件无法找到而失败了。为什么?
答:使用并行或分布式的"make"来编译BIND 9是不支持的,而且也无法工作。如果你确实使用的是它们中一种,建议你使用一般的make或gmake来替代。

13、我有一台BIND 9的主服务器和一台BIND 8.2.3的从服务器,而主服务器记录到类似于"notify to 10.0.0.1#53 failed: unexpected end of input"的错误信息。哪有问题?
答:该错误信息是由BIND 8.2.3中一个已知的bug所致,这在BIND 8.2.4中得到了修复。你可以完全不必理会它 - 不管错误信息如何,notify都在正常工作着。

14、我不断地得到如下的日志信息,为什么?
Dec 4 23:47:59 client 10.0.0.1#1355: updating zone 'example.com/IN': update failed: 'RRset exists (value dependent)' prerequisite not satisfied (NXRRSET)
答:DNS更新程序允许更新请求在进行更新之前进行测试以确认特定的条件是否满足。以上信息说明条件不满足,无法继续进行更新。参看doc/rfc/rfc2136.txt以获知关于前提条件的更多信息。

15、我不断地得到如下的日志信息,为什么?
Jun 21 12:00:00.000 client 10.0.0.1#1234: update denied
答:有人在尝试使用RFC2136动态更新协议来更新你的DNS数据。Windows 2000的机器有这样的习惯:无需事先配置就发送动态更新请求给DNS服务器。如果更新请求来自于Windows 2000机器,请参看 以了解如何关闭它。

16、我看到如下的日志信息,为什么?
couldn't open pid file '/var/run/named.pid': Permission denied
答:很可能你是以非root用户在运行named,而该用户又对/var/run没有写权限。通常的修复方法是创建由named用户所有的/var/run/name目录并设置pid文件为"/var/run/named/named.pid",或者设置pid文件为"named.pid",这将把该文件放到由directory选项指定的目录(在此情况下,该目录必须对named用户可写)下去。

17、当我在执行“dig . ns"时,许多关于root服务器的A记录都丢失了。为什么?
答:这是正常的情况,并无大碍。在BIND 9实现RFC 2181的信任级别(trust ranking)的方法和BIND 9对避免相关数据(glue)进入回答所作的努力上,有些令人迷惑的副面效果。
当BIND 9第一次启动并初始化其缓冲时,它接收根服务器地址作为根服务器权威响应的附加数据,并且这些记录符合包含在响应中作为附加数据的条件。随后,它接收根服务器地址的子集作为根服务器的非权威(推荐)响应的附加数据。这导致这些地址现在被视为非权威的(相关的)数据,它们不适合包含在响应中。
服务器的确总是有一组完整的根服务器地址作为缓冲,只是有可能没有包括全部的地址作为附加数据,这取决于它们最后接收的是响应还是相关数据。你通常可以使用显式查询如“dig a.root-servers.net A"来查找这些地址。

18、从BIND 9主服务器传输zone到Windows 2000从服务器失败了。为什么?
答:这可能是由于Windows 2000 DNS服务器的一个bug所致,在Windows机器上,大于16K的DNS消息就无法正确处理。这可以通过设置选项"transfer-format one-answer;"来解决。也可以检查你的zone是否包含了内嵌的空格或其他的特殊字符,例如"John\032Doe\213s\032Computer",因为根据已知信息,这些名字也会导致Windows 2000从服务器不正确地拒绝zone。

19、为什么当我在执行"rndc reload"或SIGHUP时,我的zone文件并不重新载入?
答:既可以通过编辑zone文件并重新引导服务器来更新zone文件,也可以通过动态更新来实现,但不能同时使用两种方法。如果你已经针对zone使用了"allow-update"选项来激活动态更新,那你就不能再手工编辑zone文件,此时服务器将不再尝试重新载入zone文件。

20、我可以在域名服务器上查询域名服务器,但不能从其他机器上查到。为什么?
答:这通常是由防火墙配置阻止了查询和/或响应所导致的结果。

21、我怎样可以让服务器同时作为内部和外部视图的从服务器?当我试着这样做时,从服务器上的两个视图传输了主服务器上的同一视图。
答:你应该为主服务器和从服务器设定多IP地址。例如:
主服务器: 10.0.1.1 (internal), 10.0.1.2 (external, IP alias)
internal:
match-clients { !10.0.1.2; !10.0.1.4; 10.0.1/24; };
notify-source 10.0.1.1;
transfer-source 10.0.1.1;
query-source address 10.0.1.1;
external:
match-clients { any; };
recursion no; // don't offer recursion to the world
notify-source 10.0.1.2;
transfer-source 10.0.1.2;
query-source address 10.0.1.2;
从服务器:10.0.1.3 (internal), 10.0.1.4 (external, IP alias)
internal:
match-clients { !10.0.1.2; !10.0.1.4; 10.0.1/24; };
notify-source 10.0.1.3;
transfer-source 10.0.1.3;
query-source address 10.0.1.3;
external:
match-clients { any; };
recursion no; // don't offer recursion to the world
notify-source 10.0.1.4;
transfer-source 10.0.1.4;
query-source address 10.0.1.4;
将external地址设为别名,这样所有在这台机器上的dns客户端默认看到的是internal视图。

22、当我尝试使用rndc时,我得到错误信息"network unreachable"或"connection refused",尽管我知道named正在运行。
答:你可能在/etc/rndc.conf中有"default-server localhost",你的/etc/hosts或DNS将"localhost"同时解析成IPv4回退地址127.0.0.1和IPv6回退地址::1,而此时你的IPv6根本无法工作。将"default-server localhost"改作"default-server 127.0.0.1"以确保rndc不会尝试使用IPv6连接域名服务器。

23、我用的是Freebsd 4.4,运行"rndc-confgen -a"就停在那儿不动?
答:没有配置/dev/random。使用rundcontrol(8)告知内核使用特定中断作为随机事件的源。你可以通过在/etc/rc.conf中设置rand_irqs来使之永久生效。
/etc/rc.conf
rand_irqs="3 14 15"

24、为什么named监听的UDP端口不是53?
答:named使用系统选定的端口连接到其他域名服务器进行查询。这可以通过使用query-source进行覆盖以锁定端口和/或地址。
25、当传输zone文件时,我得到错误信息如"multiple RRs of singleton type"以及"CNAME and other data"。这是什么意思?
答:这提示了主zone文件不正确。你可以通过使用dig来找到zone传输所包含的记录,然后在其上运行named-checkzone。
dig axfr example.com @master-server > tmp
named-checkzone example.com tmp

26、我得到错误信息如"named.conf: 99 : unexpected end of input",这里99是named.conf的最后一行。
答:有些文本编辑器(记事本和写字板)无法在文本文件的最后一行放置行终止标识(例如CR/LF)。这可以通过在文件的最后“加入”一空行来修复。named期望在EOL后紧跟的是一个EOF,如果不符合此条件,它就当作被删除了。

27、我得到警告信息如"zone example.com/IN: refresh: failure trying master 1.2.3.4#53: timed out".
答:1)检查你是否可以由从服务器到主服务器进行UDP查询:
dig +norec example.com soa @1.2.3.4
2)你可能生成的查询超过了从服务器所能处理的能力。降低串行查询率。
serial-query-rate 5; // default 20