全解DNS

一,dns工作原理

对于DNS 服务器,它始终应指定为 Internet 类别。例如,指定的名称可以是计算机的完全合格的域名,如hosta.hello.myblog.com,并且指定的查询类型用于通过该名称搜索地址资源记录。系统将把DNS 查询当作客户机向服务器提出的两部分问题,如“对于名为 hostname.hello.myblog.com 的计算机,你有没有地址资源记录?”当客户机从服务器接收应答时,它读取并解释应答的地址资源记录,以了解它通过名称提问的计算机的 IP 地址。

  DNS 查询以各种不同的方式进行解析。客户机有时也可通过使用从以前查询获得的缓存信息就地应答查询。DNS 服务器可使用其自身的资源记录信息缓存来应答查询,也可代表请求客户机来查询或联系其他 DNS 服务器,以完全解析该名称,并随后将应答返回至客户机。这个过程称为递归。

  另外,客户机自己也可尝试联系其他的 DNS 服务器来解析名称。如果客户机这么做,它会使用基于服务器应答的独立和附加的查询,该过程称作迭代。

  总之,DNS 的查询过程按两部分进行:首选,名称查询从客户机开始并传送至解析程序(DNS客户服务)进行解析;其次,不能就地解析查询时,可根据需要查询DNS服务器来解析名称。

164150948.jpg

如查询过程的初始步骤所示,DNS 域名由本机的程序使用。该请求随后传送至 DNS 客户服务,以通过使用就地缓存的信息进行解析。如果可以解析查询的名称,则查询将被应答,并且此过程完成。

其中,本地解析程序的缓存可从以下2个可能的来源获取名称信息:

  ● 如果主机文件就地配置,则来自该文件的任何主机名称到地址的映射都将在DNS 客户服务启动时预先加载到缓存中。

  ● 从以前DNS查询应答的响应中获取的资源记录将被添加至缓存并保留一段时间。

  如果此查询不匹配缓存中的项目,则解析过程继续进行,客户机查询 DNS 服务器来解析名称。

  接下来查询 DNS 服务器,当本地的DNS不能就地解析查询时,可根据需要查询 DNS 服务器来解析名称。如图4-1所示,客户机将查询首选 DNS 服务器。在此过程中使用的实际服务器是从全局列表中选择的。当 DNS 服务器接收到查询时,首先检查它能否根据在服务器的就地配置区域中获取的资源记录信息作出权威性的应答。如果查询的名称与本地区域信息中的相应资源记录匹配,则服务器作出权威性的应答,并且使用该信息来解析查询的名称。

  如果查询的名称没有区域信息,则服务器检查它能否通过本地缓存的先前查询信息来解析名称。如果从中发现匹配的信息,则服务器使用它应答查询。接着,如果首选服务器可使用来自其缓存的肯定匹配响应来应答发出请求的客户机,则此次查询完成。

  如果查询名称在首选服务器中未发现来自缓存或区域信息的匹配应答,则查询过程可继续进行,使用递归来完全解析名称,包括来自其他 DNS 服务器的支持,以帮助解析名称。在默认情况下,DNS 客户服务要求服务器在返回应答前使用递归过程来代表客户机完全解析名称。在大多数情况下,DNS 服务器的默认配置支持递归过程,如图

164442541.jpg

为了使 DNS 服务器正确执行,首先需要在DNS 域名空间内存放其他DNS服务器的一些有用的联系信息。该信息以根线索的形式提供,它是记录初步资源的一个列表,可用来定位一些 DNS 服务器,这些服务器对 DNS 域名空间树的根具有绝对控制权。根服务器对 DNS 域名空间树中的根域和顶级域具有绝对控制权。DNS 服务器可通过使用根线索搜索根服务器来完成递归过程。

  例如,当客户机查询单个DNS服务器时,考虑使用递归过程来定位名称 host.example.microsoft.com。此过程在 DNS 服务器和客户机首次启动,并且没有可帮助解析名称查询的当地缓存信息时进行。

  首先,首选服务器分析全名并确定对于顶级域com具有绝对控制权的服务器的位置。随后,对com DNS 服务器使用迭代查询,以获取microsoft.com服务器的参考信息。然后参考性应答从microsoft.com服务器传送到example.microsoft.com的 DNS 服务器。最后,与服务器 example.microsoft.com 联系上。因为该服务器包括作为其配置区域一部分的查询名称,所以,它向启动递归的源服务器作出权威性的应答。当源服务器接收到表明已获得对请求查询的权威性应答的响应时,它将此应答转发给发出请求的客户机,这样,递归查询过程就完成了。

二,服务器搭建

2.1 yum安装dns的软件包

[root@test2 ~]# yum install bind bind-utils bind-chroot caching-nameserver
bind就是dns的主要包
bind-utils提供了dns测试的工具
bind-chroot是让dns工作在chroot模式下,这样更加安全了
caching-nameserver是缓存dns的功能,提供dns配置模板
yum安装之后就会在/ var /named/chroot/下生成named 的很多相关文件
[root@test2 etc]# ll
localtime
named.caching-nameserver.conf 模板
named.rfc1912.zones 提供zone的配置
rndc.key 加密通道的配置文件
将caching-nameserver提供的模板拷贝成named.conf
[root@test2 etc]# cp named.caching-nameserver.conf named.conf
[root@test2 etc]# pwd
/ var /named/chroot/etc

2.2 编译安装dns

#tar -zxvf bind- 9.9 . 3 .tar.gz
# cd bind- 9.9 . 3 (进入解压出来的目录)
# ./configure –prefix=/usr/local/named –enable-threads
#make && make install (编译完后进行安装,这个过程比较长,耐心等待下!)
# ls /usr/local/named/ ( 查看安装完后的目录)
bin etc include lib man sbin var 首先生成一个控制key,用于主从同步数据加密的key。
#/usr/local/named/sbin/rndc-confgen -a -c zhirs.key -k zhirs
并也把生成的/ zhirs.key传到主从服务器。
进入/usr/local/named/etc,将rndc.conf及named.conf生成
#/usr/local/named/sbin/rndc-confgen >/usr/local/named/etc/rndc.conf
(使用rndc-confgen命令生成rndc.conf文件,rndc主要用来通过网络控制bind9服务器,在能够控制一台bind服务器前,必须要建立双方的认证机制。)


三,dns配置文件详解

3.1在dns安装之后的配置文件

由于dns工作在chroot模式下,所以他的根是/var/named/chroot/,那么一下所有的配置都是在此目录下的文件
options {
        listen-on port 53 { 127.0.0.1; };
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        // query-source    port 53;
        allow-query     { localhost; };
        allow-query-cache { localhost; };
};
logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};
view  dns1 {
        match-clients      { localhost; };
        match-destinations { localhost; };
        recursion yes;
        include "/etc/named.rfc1912.zones";
};


3.2参数意义

acl用来对bind的访问进行限制,是一个全局的设置,前面配置的acl在整个bind中都适用,和路由器里面的access-list有同工之处,语法是
acl acl-name {
address_match_list
};
其中的address match list是一个地址列表,如”192.168.0.0/24;”,记住最后一定得有分号,有多个的话中间用分号格开,如192.168.0.0/32;192.168.1.0/24;
bind内置了4个acl分别是:
any(不是all) 对应所有的,也就是0.0.0.0/0.
none 对应为空.
localhost 对应本地机器.
localnets 对应本地网络.
—————-

Controls主要用于对bind进行控制,如:
key “rndc-key” {
algorithm hmac-md5;
secret “VkMaNHXfOiPQqcMVYJRyjQ==”;
};
controls {
inet 127.0.0.1 port 953
allow { 127.0.0.1; } keys { “rndc-key”; };
};
设置rndc控制的端口以及端口,keys用来设置控制的密钥.
—————-

include是一个非常有用的选项,作用是包含一个文件进来,如果需要写程序来读写bind的配置文件,这个将会用到,因为bind的配置文件很不规则,但是用了include后,就可以变的很规则,就和数据库一样了J,功用和c语言里面的include一样.

directory 设置bind的数据文件的存放位置:如 directory “/var/named”,实际上是在/var/named/chroot/目录

dump-file 设置当执行rndc dumpdb命令后的导出文件存放绝对路径,如果没有指定的话,缺省文件为named_dump.db,放在directory指定的目录下面.

pid-file 设置bind的进程号pid文件.

memstatistics-file: 默认为named.memestats,当退出的服务的时候将服务器的统计信息写到文件中.

interface-interval 设置bind检查网卡变化的周期.

forward 值有first和only两项, first则首先转发到”forwarders”中的服务器,然后自己查询,only则仅转发到 “转发服务器列表”中的服务器,不再自己查询

forwarders设置转发服务器地址列表,语法同acl中的语法.

listen-on 设置bind的绑定ip和端口,如listen-on 53 {192.168.0.1;};

version 设置客户查询DNS版本好的返回信息,如果不想让客户探测到当前的版本好,就用这个好了,如version mydns1.0;

notify 在主服务器更新时是否通知辅助服务器(notify)
如果设置为”yes”,则在主服务器区域数据发生变化时,就会向在域的”域名服务器“中列出的服务器和“亦通知”中列出的服务器发送更新通知。这些服务器接受到更新通知后,就会向主服务器发送请求传输的消息,然后区域文件得以更新。

recursion 是否允许递规查询(recursion)
如果设置为”yes”,则允许服务器采用递归的方式进行查询,也就是当要查询的地址不在服务器的数据库列表中时,服务器将一级一级的查询,直到查到为止。(一般对局域网都打开)
设置为”no”,并不意味着服务器对于请求的递归查询不给予回答,而是对于请求的递归查询,不再向上级服务器请求,也不缓存,如果不对请求的递归查询回答,可以清空缓存,然后设置为“NO”.

allow-query 允许普通查询的地址列表(allow-query):
设置允许进行普通查询的ip地址列表,在域中的设置将覆盖全局设置,默认情况下是允许所有的地址进行普通查询.

allow-recursion允许递归查询的地址列表(allow-recursion):
设置允许进行递归查询的ip地址列表,缺省值是允许所有地址进行查询,需要注意的是当设置了不允许递归查询后,如果仍然能够查询部分外部的域名,那是因为dns的缓存在起作用,将缓存清除以后就可以了.

allow-transfer允许服务器进行区域传输的地址列表(Allow-transfer):
(注意的是视区和域中的设置将覆盖全局设置).

allow-notify 允许更新通知的地址列表(allow-notify)
当服务器作为辅助服务器的时候,设置这个可以对收到的更新通知进行判断,只是接收该列表的更新通知.默认情况下,只是接收来自主服务器的更新通知。对于其他服务器的更新通知,会忽略掉.

also-notify 更新时亦通知下列地址(also-notify):
设置发送更新通知的时候,不仅是域名服务器中列出的地址,亦通知此地址列表中的地址。

match-clients,指的是view对应的源地址,match-destinations指的是view对应的目的地址, match-recursive-only指的是view对应是否仅仅是递归请求.
BIND 在收到DNS的解析请求后,会首先判断该请求包的源地址和目标地址,然后根据视区里面的“match-clients”和”match- destinations”和” match-recursive-only”,判断是否属于第一个视区,符合的话就用第一个视区来进行解析,否则就判断下一个视区.然后再进行解析.如果所有的视区都不能对应,则DNS将返回Query refused的消息
这样在防火墙的情况下,就有一个很好的解决办法了,比如一个典型的网络结构下,DMZ区全部在防火墙外网口上做的地址映射(DNAT),当DMZ区要访问本地网络的时候,单纯用传统的域名解析的话,是无法达到要求的,因为防火墙无法同时又做SNAT和DNAT,比如DMZ地址192.168.0.14映射到外部地址202.196.160.14,而域名服务器解析 WWW.YOURDOMAIN.COM到202.196.160.14,则192.168.0.0/24的网络将无法访问 www.yourdomain.com,但是当用了VIEW后,你可以对来自该网络的解析请求将WWW.YOURDOMAIN.COM直接解析到 192.168.0.14,这样就可以访问了.
View里面可以包含zone,优先级是zone>;view>;options,zone里面的选项好多和options里面一样,不过它只是对本zone一样,同样view里面的选项也只是对本view有效.


3.3 域名和zone的配置解释

一般的,zone必须在view中,应为我们在named.conf配置文件中有指定

include"/etc/named.rfc1912.zones";

所以我们配置zone的时候都是在这个文件中进行的

zone "wolf.org" IN { 正向解析wolf.org这个域
type master; 设置dns服务器的类型
file "wolf.org.zone"; 解析文件名,他的路径在named.conf文件中direcory指定
allow-update { none; }; 是否 dhcp更新
};

zone "126.168.192.in-addr.arpa" IN { 反向解析
126.168.192.0/24

type master;
file "126.168.192.local";
allow-update { none; };
}
;
我们来看看test.com.这个域的zone

$TTL    86400
@               IN SOA  ns.test.com.       root@test.com. (
              42              ; serial (d. adams)
              3H              ; refresh
              15M             ; retry
              1W              ; expiry
              1D )            ; minimum
test.com.       IN NS           ns.test.com.
test1           IN A            192.168.126.128
test2           IN A            192.168.126.12

注意,上述的A记录解析中test1后面没有"." 这表示的是当我们要解析test1.test.com时他会自动加上test.com,但是当我们写成test.或者test.test.com的时候,这个时候named会把解析成test.或者test.test.com.test.com

$TTL 86400 //时间一天也可以写成1D D代表一天

 @ 默认域

SOA (Start Of Authority ) 授权开始区域,标识是服务器管理的起始开始位置,其中的信息说明如何控制该域。配置文件的首记录必须是SOA记录。 实际应用中SOA号的作用比较重要。负责判断主辅更新。named就这里的例子来说呢! test.com.域的授权开始区域(也就是老大)是ns.test.com.这台主机

  A(Address) 主机名转换成ip地址。任何一个主机只能 有一个A记录

  CNAME(Canonic NAME)  命名主机别名。主机规范名在A中定义

  MX  (Mail exchange)  定义邮件服务器,和邮件处理优先级别 (数字小优先级高)

  NS (Name Server)授权的域名服务器

  PTR domain name Pointer) ip地址转换成主机名

  SOA Hostname mail-address

  Serial 表示信息文件版本号,配置文件每次修改一次要求加1

  Refresh 表示辅助域名服务器更新的时间间隔

  Retry  辅助域名服务器更新数据失败,再次测试的时间间隔

  Expire 辅助域名服务器无法从主服务器更新数据时,原有数据的有效时间

  Minimum 若未指定ttl, 高速缓存的数据以此值为生存期


四,搭建基于View,key加密传输的dns主从服务器

众所周知的是中国有南电信和北网通,之间有很大的延时,为了在客户之间获得很好的客户体验,我们在南方搭建一台服务器,然后再北方搭建一台服务器,所以当我们由用户访问www.test.com的时候,我们需要北方的用户去访问北方的服务器,南方的用户去访问南方的服务器,这个时候我们就需要将dns的解析到合适的服务器上了

我们来假设如下图的企业需要

要求:北方的1.1.1.1的IP访问www.test.com的时候解析到north的服务器66.66.66.66,北方的3.3.3.3的IP访问www.test.com的时候解析到north的服务器88.88.88.88,而且我们需要两台dns服务器。

201147440.png


4.1建立主辅dns同步的加密

生成加密通道的密钥,这个时候会生成一把公钥和一把私钥,dd是可以随便起的名字

[root@test2 chroot]# dnssec-keygen -a HMAC-MD5 -b 128 -n HOST dd
Kdd.+157+28146
[root@test2 chroot]# ll
-rw------- 1 root root 46 Oct 9 20:16 Kdd.+157+28146.key
-rw------- 1 root root 81 Oct 9 20:16 Kdd.+157+28146.private
我们来看看在这个密钥的内容

[root@test2 chroot]# cat ./Kdd.+157+28146.key
dd. IN KEY 512 3 157
MXxup0rtmjdpYD188CtMBA==
我们将密码写到一个文件中

[root@test2 chroot]# vim /var/named/chroot/etc/transfer.key

key "dd" {
algorithm hmac-md5;
secret "
MXxup0rtmjdpYD188CtMBA==";
};

修改权限

[root@test2 chroot]# chmod 644 /var/named/chroot/etc/transfer.key
[root@test2 chroot]# chown root.named /var/named/chroot/etc/transfer.key

在named.conf中view包含这个文件,然后将密码文件拷贝到辅助dns中


4.2配置主dns服务器test2.test.com,IP 192.168.126.129

为了方便我让192.168.126.129192.168.126.130也作为客户端

acl north { 192.168.126.129;1.1.1.0/24; };
acl south { 192.168.126.130;3.3.3.0/24; };
options {
      ......
};
logging {
........
};
view  dns1 {
        match-clients      { north; };
        recursion yes;
        include  "/etc/transfer.key";
        zone "test.com" IN {
        type master;
        file "north.test.com.zone";
        allow-update { none; };
        also-notify { 192.168.126.130; };
        allow-transfer { 192.168.126.130; };
        };
        include "/etc/named.rfc1912.zones";
};
view  dns2 {
        match-clients      { south; };
        recursion yes;
        include  "/etc/transfer.key";
        zone "test.com" IN {
        type master;
        file "north.test.com.zone";
        allow-update { none; };
        also-notify { 192.168.126.130; };
        allow-transfer { 192.168.126.130; };
        };
        include "/etc/named.rfc1912.zones";
};


4.3辅助dns的配置test3.test.com,IP 192.168.126.130

acl north { 192.168.126.129;1.1.1.0/24; };
acl south { 192.168.126.130;3.3.3.0/24; };
options {
        ....
};
logging {
.......
};
server 192.168.126.129 {
   keys  { dd; };
};
view  dns1 {
        match-clients      { north; };
        recursion yes;
        include  "/etc/transfer.key";
        zone "test.com" IN {
        type slave;
        file "north.test.com.zone";
        masters { 192.168.126.129; };
        };
        include "/etc/named.rfc1912.zones";
};
view  dns2 {
        match-clients      { south; };
        recursion yes;
        include  "/etc/transfer.key";
        zone "test.com" IN {
        type slave;
        file "south.test.com.zone";
        masters { 192.168.126.129; };
        };
        include "/etc/named.rfc1912.zones";
};


4.4主辅同步的zone

[root@test3 named]# cat ./south.test.com.zone
$TTL    86400
test.com.   IN SOA  test2.test.com.       root@test.com. (
                    42      ; serial (d. adams)
                    3H      ; refresh
                    15M     ; retry
                    1W      ; expiry
                    1D )        ; minimum
@               IN NS       test2.test.com.
test1       IN A        192.168.126.128
test2       IN A        192.168.126.129
www             IN A            88.88.88.88
[root@test3 named]#


4.5查看主辅dns同步日志

Oct  9 22:02:20 test2 named[18749]: zone test.com/IN/dns2: loaded serial 66
Oct  9 22:02:20 test2 named[18749]: zone localdomain/IN/dns2: loaded serial 42
Oct  9 22:02:20 test2 named[18749]: zone localhost/IN/dns2: loaded serial 42
Oct  9 22:02:20 test2 named[18749]: running
Oct  9 22:02:20 test2 named[18749]: zone test.com/IN/dns1: sending notifies (serial 42)
Oct  9 22:02:33 test2 named[18749]: client 192.168.126.130#60736: view dns2: transfer of 'test.com/IN': AXFR-style IXFR started: TSIG dd
Oct  9 22:02:33 test2 named[18749]: client 192.168.126.130#60736: view dns2: transfer of 'test.com/IN': AXFR-style IXFR ended