Chinaunix首页 | 论坛 | 博客
  • 博客访问: 58385
  • 博文数量: 16
  • 博客积分: 930
  • 博客等级: 准尉
  • 技术积分: 215
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-16 16:57
文章分类

全部博文(16)

文章存档

2007年(13)

2006年(3)

我的朋友
最近访客

分类:

2007-06-24 15:34:39

在众多 Internet 服务器当中DNS服务是所有服务的基础,它最主要的职责之一是完成从主机域名到IP地址的映射关系的查询。DNS系统管理域名采用一个树状结构,DNS树的最上面是一个无名的root域,用“.”来表示。这个域只用来定位,并不包含任何信息,它由NIC来管理控制。Root下是分层的domain组成树状结构,一个DNS域(domain)是DNS树状结构中的一个分枝,domain中包含很多被授权管理的区域(zone),它是每个授权单位所管理的主机和IP地址的集合,我们平时说的域,实际上就是zone。比如,把这个URL地址拆解开:
.com            domain
.silly.com      zone
www             则是.silly.com区域内的一台具体的主机
 
Linux上最常用的DNS服务器软件是BIND(Berkeley Internet Name Domain),BIND在不断的更新和完善,在上可以获得它的最新源代码和文档。Red Hat Linux 7.3自带的是bind9.2。
 
§§ 安装bind软件包
 
首先来安装bind软件包
 
[root@rh73 /mnt/cdrom/RedHat/RPMS]# rpm -ivh bind-9.2.0-8.i386.rpm
Preparing...                ########################################### [100%]
   1:bind                   ########################################### [100%]
 
§§ 了解bind的配置文件/etc/named.conf
 
为了将来维护的方便,我打算把内部的某些主机做本地的名称解析,假定本地域为silly.com,我要把ns和firewall两个主机名都指向接入服务器的地址192.168.100.254:
 
ns.silly.com    192.168.100.254
firewall.silly.com  192.168.100.254
 
Linux上的DNS软件包是bind,但服务进程的名字为named,首先来看一下/etc/named.conf,该文件是bind最主要的配置文件,这里定义了域名服务器的类型,以及相应的数据库文件所在目录等内容。
 
该文件开始是options设定部分:
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;
};
其中directory设定指出了named的数据资源文件存放在/var/named目录下面。也就是说,named进程会在这个目录里查找相关文件获得DNS数据,然后在后面设置数据文件时,可以直接放在这个目录里,不需要再使用绝对路径。
 
接下来的一段文字是说如果你的DNS服务器是bind 8.1之前的版本,并且和客户端之间如果隔着防火墙的话,要将// query-source address * port 53;前面的//拿掉(去掉注释)。我们使用的是9.2版的软件,所以不需要更改这个设置。
 
//
// a caching only nameserver config
//
controls {
        inet 127.0.0.1 allow { localhost; } keys { rndckey; };
};
controls和文件最后的include "/etc/rndc.key";是bind 9.x版本的新功能,是有关DNS更新以及更新时加密处理的,暂时我们用不到,先不管它。
 
zone "." IN {
        type hint;
        file "named.ca";
};
 
这部分设置定义了DNS系统中的root区域“.”(root zone),其类型为hint。本地DNS无法解析到的非本地区域的内容,都会根据named.ca的里设定到root区域负责查询。
 
zone "localhost" IN {
        type master;
        file "localhost.zone";
        allow-update { none; };
};
 
zone "0.0.127.in-addr.arpa" IN {
        type master;
        file "named.local";
        allow-update { none; };
};
 
这两段定义了本机名称的DNS解析,第一个zone是localhost的解析,其类型为master,数据文件是/var/named/localhost.zone。第二个zone是本机区域的反向解析,即根据IP地址反查域名的数据。
 
include "/etc/rndc.key";
 
下面看看localhost.zone的内容:
[root@rh73 /var/named]# cat 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(Time To Live)设定,以秒为单位,这里定义为86400秒,也就是一天。每一个DNS服务器都有缓存非本地域名信息的功能,TTL指出了解析结果在缓存中保留的时间。平时你可能注意到了,第一次访问某个站点可能需要较长的时间才能打开,接下来再访问时就快一点,这就是DNS缓存功能的作用,它减少了第二次解析域名到IP地址的时间。
 
第二行是ORIGIN,指出下面的主机记录属于哪个域。在下面的@是它的替代符号。
 
第三行开始的@是ORIGIN的替代符,这里是指localhost。接下来的1D(1day,一天,也可以写成秒为单位的数字,如86400)是TTL值,可以不指定,如果没有指定,则参考前面设定的TTL值,如果前面也没定义,则参考后面要介绍的minium tll的值。你可以单独为每一个记录设定TTL,只要将要设定的值放在“IN”之前就可以了。
 
IN后面的SOA(Start Of Authority)是指这一行记录的类型,表示当前区域的授权记录开始。每一个数据文件只能有一个SOA,不能重复,并且必须是所负责zone中的第一个记录。
 
SOA后面指定了这个区域的授权主机和管理者信箱,这里分别是@(localhost.)和。root如果写全了应该是root.localhost,这里用“.”代替“@”。SOA的授权主机名称必须在DNS系统中有一个A记录。
 
接下来的 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 是一样的。无论用什么单位来设定,都要遵守下面的规则:
expire >= refresh + retry
expire >= 10 * retry
 
请注意:SOA 记录中这对“()”符号中的左括号“(”一定要和 SOA 写在同一行!
 
最后两行表示负责localhost.这个记录的Name Server(NS)是localhost这台主机,localhost的IP地址(Address)是127.0.0.1。
 
named.local在/etc/named.conf里定为“0.0.0.127.in-addr.arpa”zone的反向解析数据文件,其内容如下:
[root@rh73 /var/named]# cat named.local
$TTL    86400
@       IN      SOA     localhost. root.localhost.  (
                                      1997022700 ; Serial
                                      28800      ; Refresh
                                      14400      ; Retry
                                      3600000    ; Expire
                                      86400 )    ; Minimum
        IN      NS      localhost.
 
1       IN      PTR     localhost.
来看最后一行“1       IN      PTR     localhost.”,这个记录类型是PTR(Pointer),通常用在反向解析时,将IP指向主机名称(和A记录正好相反)。前面的设置中,我们知道127.0.0.1对应的主机名称是localhost,反向查询时,IP地址应该倒过来写1.0.0.127.in-addr.arpa,由于这里的ORIGIN(@)是“0.0.127-in-addr.arpa.”,所以在写PTR记录时,只需要写1,后面会自动补上0.0.127-in-addr.arpa.
 
§§ 实现本地域主机的解析
 
了解了上面的内容,我们来看看如何做本地的域名解析。我们要做的工作是:
 
在/etc/named.conf里添加两个zone设置:
 
zone "silly.com" IN {
        type master;
        file "silly.zone";
        allow-update { none; };
};
 
zone "100.168.192.in-addr.arpa" IN {
        type master;
        file "named.silly";
        allow-update { none; };
};
 
设置/var/named/下的数据文件:
[root@rh73 /var/named]# cat silly.zone
$TTL    86400
$ORIGIN silly.com.
@       IN      SOA     ns.silly.com. root.silly.com.  (
                                      1997022700 ; Serial
                                      28800      ; Refresh
                                      14400      ; Retry
                                      3600000    ; Expire
                                      86400 )    ; Minimum
                IN      NS      ns.silly.com.
 
ns              IN      A       192.168.100.254
firewall        IN      CNAME   ns
 
CNAME记录用来定义一个主机域名的别名。当多个主机名指向同一个地址的时候,这个记录类型可以方便设置。
 
设置反向解析zone:
[root@rh73 /var/named]# cat named.silly
$TTL    86400
@       IN      SOA     ns.silly.com. root.silly.com.  (
                                      1997022700 ; Serial
                                      28800      ; Refresh
                                      14400      ; Retry
                                      3600000    ; Expire
                                      86400 )    ; Minimum
        IN      NS      ns.silly.com.
 
254     IN      PTR     ns.silly.com.
 
§§ 转发解析请求
 
为了提高我们这个DNS服务器的查询效率,我们会采取这样的措施:把非本地域的解析请求转发到我们的ISP提供的DNS。
 
这个功能是由forwarder选项来完成的。所谓的 forwarder,就是当某一台 NS 主机遇到非本机负责的 zone ( slave zone 也属于本机负责的范围) 查询请求的时候,将不直接向 root zone 查询而把请求转交给指定的 forwarder (一台或多台) 主机代为查询。如果你不了解 DNS 的查询模式,那么很难理解这个 forwarder 的意义和好处。
 
我们知道,当DNS服务器接到客户端主机的查询请求时,首先会检查这个查询是否属于本机管辖,否则将转向 root zone 再逐级的查询下去,最后再把查询结果告诉客户端。在这个过程之中,DNS服务器还会将查询到的结果存放到缓存中。只要缓存中的 TTL 没过期,在下次遇到同样查询的时候,就可以直接将结果响应给客户端,而无需再重复上次的查询流程。如果DNS服务器上指定了forwarder,那这个DNS发现缓存中没有记录时,将不向 root 查询,而是向 forwarder 送出同样的请求(转发),然后等待查询结果,即把逐级往下查询这个耗费精力的动作,交给 forwarder 负责。但无论这个结果是自己直接查询得来的,还是 forwarder 送回来的,DNS服务器都会保存一份数据在缓存中。这样,以后的相同查询就快多了,这对于DNS所服务的 客户端而言查询效率会提高很多。
 
forwarder 机制的好处并非仅是上面所提到的效率提升,对于整个网络流量(尤其是对外的流量)也是有帮助的。比方说,你的内部网络需要 10 台 DNS 来提供服务,你只需在某一台能直接与外界沟通的计算机上架设 DNS 服务,然后将其它内部DNS的 forwarder 指向该服务器就行了。这样可能本来需要 10 次的 root 查询,在 forwarders 的机制下,就只需 1 次而已。连同下层的往返查询来计算的话,总体上所省下的对外查询就更多了,再加上缓存带来的好处,forwarder 所降低的 DNS 流量是非常显著的。
 
事实上,在本章开始我们就提到如何集中管理内部局域网用户域名解析问题,解决的方法就是:在本地DNS的 forwarder 设定为 ISP 的 DNS,局域网用户把DNS都设置成本地DNS地址,在进行外部域名解析时,我们的DNS把解析请求转发给ISP的DNS;又因为 ISP 上的 DNS 也有缓存的关系,所以这样设置查询还可以提高速度。
 
罗嗦了半天,现在看看如何配置。具体的设置很简单:在named.conf的options部分添加这样一行:
 
forwarders { 211.136.17.107; 202.102.152.3; };
 
如此设置完毕,那么所有非本区域的查询都会直接转发到forwarders指定的DNS服务器上去。
 
§§ 测试DNS
 
全部设置完后,把named进程重起一下,使设置生效:
 
[root@rh73 /var/named]# /etc/rc.d/init.d/named restart
 
现在测试一下刚才的设置是否正确:
 
设置Linux主机的DNS客户端
 
[root@rh73 ~]# vi /etc/resolv.conf
 
其实在系统安装设置网卡参数时我们已经设置了这个文件,其内容可能是:
 
nameserver 202.102.152.3
nameserver 202.102.134.68
 
现在把这两行内容去掉(或注释掉,在行首加“#”),然后写上:
 
nameserver 192.168.100.254
 
即使用我们刚才设定的192.168.100.254这个DNS服务器。
 
在Linux上我们可以用ping、nslookup、dig、host等命令来测试DNS是否工作正常,这些小工具都很简单,以host为例:
 
[root@rh73 ~]# host ns.silly.com
ns.silly.com has address 192.168.100.254
 
[root@rh73 ~]# host firewall.silly.com
firewall.silly.com is an alias for ns.silly.com.
ns.silly.com has address 192.168.100.254
 
[root@rh73 ~]# host china.com
china.com has address 61.151.243.8
 
可以正常解析出本地区域和Internet上域名的IP地址,符合我们的设计要求。当然配置一个完善的DNS服务器这些知识是远远不够的,如果想了解更多,请参考其它资料。

[tips]
在设置named.conf的options部分时,我们可以利用下面几个有用的options,来增强系统的安全特性:
version "Hello World";
当别人要探测我们DNS服务器的版本时,对方得到的将是Hello World :)
 
Listen-on{192.168.100.254;};
如果DNS服务运行在有多个网卡的服务器上,那么默认的它会在所有网卡接口上监听服务,这个选项告诉它只在指定的借口上进行服务监听。
 
如果不想让某些主机或网络使用我们的DNS服务,那么可以通过配置acl,并在options部分设置Blackhole完成:
acl denied {
192.168.100.50;
192.168.100.51;
192.168.1.0/24.
};
 
Blackhole {denied;};
 
这样设置之后,192.168.100.50,192.168.100.51和192.168.1.0/24的主机都不能使用这个DNS服务器了。
 
阅读(758) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~