提要:本文详尽介绍了在slackware 10.1+bind9的环境下架设DNS服务器的全过程;Recoilest兄写的极为详细,文章有序,适合所有学习Linux服务器架设的弟兄;
环境: slackware10.1/kernel 2.4.29/pIII550/64m/10g
使用slackware10.1的BIND包默认安装
公网网卡eth0 地址211.137.217.251
前提:
理解 DNS 的授权模式 ? 是怎样进行的?
理解 DNS 正解和反解 ?
理解 DNS 的查询模式 ? 查询过程是怎样的?
如果您对于以上问题还不了解,那么我建议您到这里看看
--------------------------------------------------------------------------------
下面进入正题
1 设置named.conf
首先﹐打开named.conf文件﹐路径 /etc/named.conf
我先将我自己的文档列了出来﹕
options {
directory "/var/named";
/*
* 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;
forward first;
forwarders {
202.102.224.68;
202.102.227.68;
};
};
//
// a caching only nameserver config
//
zone "." IN {
type hint;
file "caching-example/named.ca";
};
zone "localhost" IN {
type master;
file "caching-example/localhost.zone";
allow-update { none; };
};
zone "0.0.127.in-addr.arpa" IN {
type master;
file "caching-example/named.local";
allow-update { none; };
};
zone "hnzzcc.com" IN {
type master;
file "db.hnzzcc.com";
};
zone "217.137.211.in-addr.arpa" IN {
type master;
file "db.211.137.217";
};
zone "ln.hnzzcc" IN {
type forward;
forwarders { 10.87.13.87; 10.87.13.96; };
};
options 设置﹐首先用 directory 指定了 named 的资源记录( RR - Resource Record )目录所在位置為﹕“/var/named”﹔它说明了我们配置NAMED的设置文件都在这个目录下
接下來看一下注释
接下來再讓我們看下一段句子﹕ 如果您要设置的DNS服务器和DNS client之间要是有防火墙的话,要将"“// query-source address * port 53;"前面的"//"注解拿掉.这些设置对8.1之前的版本影响
我们用的是BIND9,不必担心.如果您设置的有防火墙我建议您在iptables 中添加以下语句:
iptables -A INPUT -p tcp -i eth0 --dport 53 -j ACCEPT
iptables -A INPUT -p udp -i eth0 --dport 53 -j ACCEPT
接下来的是转发(forward)设定
forward first;
forwarders {
202.102.224.68;
202.102.227.68;
};
它说明了:如果服务器查找不到相关的DNS信息,那么转发到202.102.224.68和202.102.227.68来查询
接下来是zone区域
zone "." IN {
type hint;
file "caching-example/named.ca";
};
zone "localhost" IN {
type master;
file "caching-example/localhost.zone";
allow-update { none; };
};
zone "0.0.127.in-addr.arpa" IN {
type master;
file "caching-example/named.local";
allow-update { none; };
};
"."定义了根区域,它同时又是一个INTERNET类别,详细解释需要很多篇幅,建议大家看一下相关书籍
以上zone设置是默认设置;定义了本机的DNS﹕第一个 zone 是 localhost 的正解 zone﹐其服务器属于DNS master﹐记录文件名称是 localhost.zone (在 /var/named/caching-example 目录下面)﹐但這个 zone 不允许客戶主机(或服务器)自行更新 DNS 的记录.
而第二个 zone 则是本机区域的反解 zone
现在我建议您先看一下named.conf中的directory "/var/named"
ls /var/named/caching-example我们会看到这些文件
named.ca
localhost.zone
named.local
也就是说每一个区域对应一个记录文件
2 zone区域记录文件
我们来打开这些文件看一下,首先是localhost.zone
$TTL 86400
$ORIGIN localhost.
@ 1D IN SOA @ root (
42 ; serial (d. adams)
3H ; refresh
15M ; retry
1W ; expiry
1D ) ; minimum
1D IN NS @
1D IN A 127.0.0.1
內容很简单﹐但您是否真的了解每一行的设定意思呢﹖如果不清楚或不确定﹐那就让我们一起探讨。
首先﹐第一行是一个 TTL 设定﹐目前是定义出记录文件里面的各项记录的默认 TTL 值为 86400 秒(刚好是一天)。没有这一行并不影响功能﹐但会出现一些警告.
第二行是一个 ORIGIN 设定﹐说明下面的记录出自何处.请您加倍留意最后的一个小小数点"."
然后﹐第三行﹐是一个 SOA 记录的设定﹐在这里我们看到一个特殊字符@,它就是 ORIGIN 的意思﹐也就是刚刚所定义的 $ORIGIN localhost. 內容﹐您可以写成 localhost. 也可以用@ 來代替。假如这个文件前面沒有定义 $ORIGIN 的话﹐那這个@的值就以 named.conf 里的 zone .
在@之后﹐是 TTL 的设定﹐这里是 1D﹐也就是一天的意思.
SOA ﹐也就是“Start Of Authority”的意思﹐表示目前区域的授权开始。每一个记录文件只能有一个 SOA ﹐不能重复﹐而且必须是所负责的 zone 中第一个"记录".
接着 SOA 后面,指定了这个区域的授权主机和管理者的信箱,这里分别是@和“ root ”,也就是 localhost. 主机和 root 信箱。这里要注意的是:SOA 的主机名称必须能够在 DNS 系统中找到一个 A 记录 (以后会提到);另外,我们平时使用的信箱通常是“user@host”这样的格式,但因为@在 DNS 记录中是个保留字符(刚才已经提过),所以在 SOA 中就用“.”来代替了@。目前这个信箱是 root (并没有主机地址),也就是本机,您可以写成 “root.localhost.”但不能写成“root@localhost.”。
接下来的 SOA 设置,是被括在“( )”之间的 5 组数字,主要作为和 slave 服务器同步 DNS 资料所使用的资料:
Serial:其格式通常会是“年月日+修改次序”(但也不一定如此,您自己能够记得就行)。当 slave 要进行资料同步的时候,会比较这个号码。如果发现在这里的号码比它那边的数值“大”,就进行更新,否则忽略。不过设 serial 有一个地方您要留意:不能超过 10 位数字!
Refresh:这里是是告诉 slave 要隔多久要进行资料同步(是否同步要看 Serial 的比较结果)。
Retry:如果 slave 在进行更新失败后,要隔多久再进行重试。
Expire:这是记录逾期时间:当 slave 一直未能成功与 master 取得联系,那到这里就放弃 retry,同时这里的资料也将标识为过期( expired )。
Minimum:这是最小默认 TTL 值,如果您在前面没有用“$TTL”来定义,就会以此值为准。
以上的数字都是以秒为单位,但您也可以用 H(小时)、D(天)、W(星期)来做单位,如:3H 和 259200 是一样的。
请注意:SOA 记录中这对 “ ( ) ”符号之第一个 “ (”括号一定要和 SOA 写在同一行,而不能用 Enter 断行到下一行去(有时候您在书本的范例中看到这个符号排在下一行去了,那是因为版面的关系而已),而且其左边最好有一个空格键或 tab 建。而最后一个 “ )”括号也不能写在注解符号 “ ;”的右边。
设置 DNS 的 RR 记录档,其格式要求非常严格,我们丝毫不能掉以轻心。比方说:如果句子不是以空格键、Tab 键、 或注解符号 ( ; )开头,也不在 SOA 的 “ ( ) ”之内, 则表示要定义一个“新记录项 (Entry) ”;如果句子是以空格键或 tab 键开始的话,其设置被视为上一个“记录项”的内容。所以,如果您要为“同一个记录项”定义多个记录设置,而不想重复打字,您倒可以偷懒:在接着它的后面几行用空白或 Tab 来缩排就可以了。所以,最后这两行还是关于 localhost. 的设置,因为上一个“资料项”为 “ @ ”,也就是 localhost. 。当然,您如不喜欢,这两行句子也可以这样写:
;; 修改前:
1D IN NS @
1D IN A 127.0.0.1
;; 修改后:
@1D IN NS @
@1D IN A 127.0.0.1
;; 或:
localhost.1D IN NS localhost.
localhost.1D IN A 127.0.0.1
这两行的意思是说:负责 localhost. 这个记录的 name server ( NS ) 是 localhost. 这台机器;而 localhost. 的 IP Address ( A ) 是 127.0.0.1 。DNS 里面的 A 记录应该是最常见的记录类型之一,如果在 IPv6 版本中,地址记录名称则改为 AAAA 。
Tips:关于更多的记录名称,请参阅“学习网络”中的“DNS 协议”。
最后,让我们检查剩下的 named.local 文件吧。如果您还没忘记 /etc/named.conf 的内容的话,应知道这个文件是 zone "0.0.127.in-addr.arpa" 的‘反解’记录档,它的内容也很简单:
$TTL 86400
@ IN SOA localhost. root.localhost. (
1997022700 ; Serial
28800 ; Refresh
14400 ; Retry
3600000 ; Expire
86400 ) ; Minimum
IN NS localhost.
1 IN PTR localhost.
前面的部份应该不用多解释了(如果您还不清楚,那就必须重读前面的文章)。最后一行我们看到一个“ PTR ”记录,它是“Pointer”的意思。 PTR 通常用于反记录当中,将 IP 指向主机名称(刚好和 A 记录相反)。您或许还不是很清楚这个句子为什么是这样设置的吧?或许您会这样问:您不是说 PTR 是从 IP 反查询主机名称的吗?为什么这里是 1 而不是 127.0.0.1 ?
哦,如果您有这样的问题,那证明您对 DNS 的查询模式还不是了解得很透彻,不过也不用紧张,在后面的实作例子中,您将获得更进一步的感性认识。这里,我暂时简单解释上面这行就是了:
我们知道 127.0.0.1 所映射的主机名称就是 localhost ,因为这里是反向查询,所以 IP 顺序是掉过来写的,于是这个反查询 IP 就是:“ 1.0.0.127.in-addr.arpa. ”,由于我们这里的 ORIGIN @ 是“ 0.0.127.in-addr.arpa." ”,因为在记录档中,如果名称不带小数点,则被补上 $ORIGIN 或 zone 的名称,所以这个 “ 1 ”就成了 1.0.0.127.in-addr.arpa. ”。同样道理,后面的“ localhost. ”如果漏了最后的小点的话,则会成为“ localhost.0.0.127.in-addr.arpa. ”,这显然是不对的。假如您喜欢,可以将这行句子修改成为下面的样子:
;;修改前:
1 IN PTR localhost.
;;修改后:
1.0.0.127.in-addr.arpa. IN PTR localhost.
3 设定自己的NAMED
下面设置我们自己定义的域名
设置之前首先要说的是必须已经申请过自己的DNS,拥有自己的固定IP的公网主机.
那么我的域名是 hnzzcc.com,我联系了ISP把DNS 区域hnzzcc.com 指向了我的主机:211.137.217.251
在named.conf中增加以下内容
zone "hnzzcc.com" IN {//正解区域名称
type master;//区域类型
file "db.hnzzcc.com";//记录文件名称
};
zone "217.137.211.in-addr.arpa" IN {//反解....
type master;//......
file "db.211.137.217";//.....
};
zone "ln.hnzzcc" IN { //公司内部区域名称,在此文中没有作用.
type forward; //类型是转发
forwarders { 10.87.13.87; 10.87.13.96; };//转发的地址
};
建立db.hnzzcc.com文件,文件内容:
$TTL 86400
$ORIGIN hnzzcc.com.
@ IN SOA ns.hnzzcc.com. root.ns.hnzzcc.com. (
2005072605
28800
14400
3600000
86400 )
IN NS hnzzcc.com.
IN NS ns.hnzzcc.com.
IN MX 10 ns.hnzzcc.com. //MX记录
@ IN A 211.137.217.251 //指定域主机地址
ns IN A 211.137.217.251 //A记录
IN MX 0 ns.hnzzcc.com. //MX记录
www IN A 219.154.96.5 //A记录
bbs IN A 211.137.217.251 //A记录
stone IN A 211.137.217.251 //A记录
slackware IN A 211.137.217.251 //A记录
提示:大家一定要注意别忘了域名后边那个"."
然后建立反解文件 db.211.137.217
$TTL 86400
@ IN SOA ns.hnzzcc.com. root.ns.hnzzcc.com.(
2005072605 1H 1M 1W 1D )
@ IN NS ns.hnzzcc.com.
251 IN PTR ns.hnzzcc.com.
以上设定就是完全完成了 .
建议你
sh /etc/rc.d/rc.bind restart
然后做测试
dig hnzzcc.com 或者 nslookup hnzzcc.com 都会有正确的信息显示
如果没有显示出解析的地址,那么就要查看/var/log/message和/var/log/syslog文件了,日志中有出错的行数,对应更改,问题总会解决的.经常出错的地方是少了";"或者"."如果一切正常那么查看message应有如下显示:
Jul 28 23:12:28 bbs named[5034]: loading configuration from '/etc/named.conf'
Jul 28 23:12:28 bbs named[5034]: no IPv6 interfaces found
Jul 28 23:12:28 bbs named[5034]: listening on IPv4 interface lo, 127.0.0.1#53
Jul 28 23:12:28 bbs named[5034]: listening on IPv4 interface eth0, 211.137.217.251#53
Jul 28 23:12:28 bbs named[5034]: listening on IPv4 interface eth1, 10.87.145.29#53
Jul 28 23:12:28 bbs named[5034]: listening on IPv4 interface eth2, 192.168.0.1#53
Jul 28 23:12:28 bbs named[5034]: listening on IPv4 interface eth2:1, 10.87.200.254#53
Jul 28 23:12:28 bbs named[5034]: listening on IPv4 interface ppp0, 10.87.200.1#53
Jul 28 23:12:28 bbs named[5034]: command channel listening on 127.0.0.1#953
Jul 28 23:12:28 bbs named[5034]: zone 200.87.10.in-addr.arpa/IN: loaded serial 2005072501
Jul 28 23:12:28 bbs named[5034]: zone 0.0.127.in-addr.arpa/IN: loaded serial 1997022700
Jul 28 23:12:28 bbs named[5034]: zone 217.137.211.in-addr.arpa/IN: loaded serial 2005072605
Jul 28 23:12:28 bbs named[5034]: zone hnzzcc.com/IN: loaded serial 2005072605
Jul 28 23:12:28 bbs named[5034]: zone localhost/IN: loaded serial 42
Jul 28 23:12:28 bbs named[5034]: zone hnzzcc.pn/IN: loaded serial 2005072501
Jul 28 23:12:28 bbs named[5034]: running
测试DNS服务是否启动用netstat -a也比较直接,看53是否起就可以了
也许到这里就可以结束了,但是我想还有一些不完善的地方.
4 安全设置
关于 DNS 的安全问题
DNS 系统在网络沟通上面提供了非常便利的途径,一个设置完整的 DNS 系统,无论在管理或除错方面都是非常有效的。然而,在许多网络入侵案例中,往往因为 DNS 提供的信息过多,而让入侵者省却了许多步骤和时间,这也增加了对入侵行为的侦察和预警的难度。
所以,假如您同时需要为内部和外部网络提供 DNS 服务、而又有条件的话,最好设置多台 DNS 服务器,分别对内和对外提供服务。在所有这些对外服务的机器上,我们只设置最少的必须记录就可以了,千万不要把 HINFO 等一些关于主机和网络环境的记录写进去。同时,任何不必要对外提供的 IP 和主机记录,一概删除就是了。而其它的为信任网络提供服务的主机,则无论如何也不要让过多的 DNS 信息流出 internet。您甚至可以通过火墙过滤来保护内部的 DNS 服务查询。
为了获得更好的安全效果,您可以在 /etc/named.conf 文件中设置一些限制,让 DNS 仅对那些信任的网络或主机提供服务,或者挡掉来自不信任主机的查询。下面,我提供一个安全设置的范例给大家参考一下:
logging { //把错误日志定义到slackware 默认的/var/log/syslog文件中,同时建议查看messages文件中的错误信息
category default { default_syslog; default_debug; };
};
//---首先定义各安全群组---//
acl "local" { //定义本机IP域
127.0.0.0/8;
};
acl "CNC_net" { //定义了网通的DNS主机IP域,这样普通主机只能通过网通的转发来查询以增加安全性
202.0.0.0/8;
};
acl "TRUSTED_net" { //受信任的IP域
219.156.81.0/24;
192.168.2.0/24;
};
acl "TRUSTED_host" { //受信任的主机地址
192.168.100.26/32;
10.0.1.130/32;
10.0.1.161/32;
};
acl "VPN_net" { //定义了一个VPN网络IP区域
10.87.200.0/24;
};
acl "BAD_Guys" { //定义黑名单区域
221.15.164.250;
}; //-注:以上 ip 仅作例子 :-)!-//
options {
directory "/var/named";
/*
* 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;
forward first;
forwarders {
202.102.224.68;
202.102.227.68;
};
allow-transfer { none; }; //默认禁止区域转移
allow-query { any; }; //默认允许查询
blackhole { BAD_Guys; }; //默认黑名单
};
//
// a caching only nameserver config
//
zone "." IN {
type hint;
file "caching-example/named.ca";
};
zone "localhost" IN {
type master;
file "caching-example/localhost.zone";
allow-update { none; };
};
zone "0.0.127.in-addr.arpa" IN {
type master;
file "caching-example/named.local";
allow-update { none; };
};
zone "hnzzcc.pn" IN {
type master;
file "db.hnzzcc.pn";
allow-query { VPN_net; }; //允许VPN网络查询
allow-transfer { VPN_net; }; //允许VPN网络区域转移
};
zone "200.87.10.in-addr.arpa" IN {
type master;
file "db.10.87.200";
allow-query { VPN_net; };//允许VPN网络查询
allow-transfer { VPN_net; }; //允许VPN网络区域转移
};
zone "hnzzcc.com" IN {
type master;
file "db.hnzzcc.com";
allow-query { local; CNC_net; TRUSTED_net;VPN_net; }; //允许本机,网通DNS,受信任网络,VPN查询
allow-transfer { TRUSTED_host; }; //允许受信任网络区域转移
};
zone "217.137.211.in-addr.arpa" IN {
type master;
file "db.211.137.217";
allow-query { local; CNC_net; TRUSTED_net;VPN_net; }; //允许本机,网通DNS,受信任网络,VPN查询
allow-transfer { TRUSTED_host; }; //允许受信任网络区域转移
};
zone "ln.hnzzcc" IN { //定义转发区域ln.hnzzcc
type forward;
forwarders { 10.87.13.87; 10.87.13.96; }; //转发地址
};
在设置 DNS 的安全原则的时候,有些问题您必须注意:
如果 client (包括 localhost ) 如果不在 allow-query 范围内的话,将不能查询该区域的任何信息。
当这一个区域作为 master 且有其它 slave 指向它的时候,slave 主机必须同时被包括在 allow-query 和 allow-transfer 设居中才可以完成区域转移。
那些不在 allow-query 设置当中的主机,虽然不能够直接将 server 指向这台 DNS 来查询所在区域。然而,如果对方先将 server 指向另一台 DNS 主机,且该主机是属于 allow-query 设置之中的话,也可以对该区域进行查询。
例如,如果在 zone "hnzzcc.com" 当中允许 CNC_net 的查询。虽然从外面的主机不能直接查询这个 zone ,但只要对方将 server 指向 CNC_net 其中任一台 DNS 主机,而该主机的 allow-query 可以让其通过的话,那他们也就可以查询 hnzzcc.com 了。
结束语
一个基本的公网DNS服务器建立起来了,不过难免有不足,希望研究BIND的朋友多多交流.需要深入研究的朋友可以参考DNS & BIND 第四版 ,或者登陆我新开的站点