本节索引
  • DNS简介

  • DNS解析过程

  • DNS资源记录

  • DNS主从原理

  • 搭建完整的DNS架构

  • 调试结果

  • 错误分析

  • 本篇小结

 

DNS简介


DNS(Domain Name System,域名系统),是Internet上作为域名和IP地址相互映射的一个分布式数据库,在这个解析库中定义了某个域名和IP的对应关系。通过DNS的解析,我们不用去记住那些难记的IP地址(数串),我们只要能记住其对应的主机名即可,像www.baidu.com。这中字符串就显得好记多了。DNS协议运行在TCP和UDP的上,对应端口号为53。其运行在TCP协议上主要是为了实现DNS冗余,即主从复制或则说区域传送,这里涉及到DNS数据库的数据的创输,必须保证安全。而运行在UDP协议上主要是为了实现名称解析,名称解析要求速度快,而且安全性并没要太大要求,使用UPD协议刚好能满足这些要求。


DNS解析过程


DNS域分为多种,有最重要的根域,用“.”表示,根域的下一级是顶级域(Top Level Domain),最有名的便是com域了,在向下就是二级域、三级域等等,DNS最多支持127即域名(真达到127级还真记不住)。

我们知道,在我们的主机找中有个hosts文件,其实这也是用来做名称解析的,你可以将自己经常访问的地址写在这里面,下次访问时系统会先读取该文件,直接访问IP,这样就省掉了DNS为你解析的过程,访问也变快了不少。

wKiom1nEb0fiA4mQAAAfcB-W1y4021.png

如果在hosts文件中没有找到你要访问的地址记录,那么将会请求所在域的DNS服务器,如果DNS服务器的缓存中有你要的地址,直接返回给你结果;如果没有DNS服务器将帮你去根上询问,根帮你找相应的域,并返回给你所在域的DNS服务器下一个域的地址;你拿着这个地址在去访问根的下级域,如此递归直到找到你想要的ip地址,并将结果返回给客户端。整个解析过程如下图:

wKiom1nEmSGxPDr3AACZfIU5_oA137.png

值得一提的是,这里面有两个专业术语,“递归查询”“迭代查询”。递归查询是指:给你提供最终答案,你访问你所在域的DNS服务器就是递归查询;迭代查询是指:只给你提供线索,不给出最终答案。例如:访问www.vinsent.cn的主机,你访问你所在域的DNS服务器,它就必须给你最终答案,这个过程就是递归查询。而你所在域的DNS服务器去帮你询问的过程,就是迭代查询的过程。


DNS资源记录


        DNS服务器的数据库中记录的就是域与IP地址之间的对应关系,以及域的子域的地址,或则从服务器的地址。而这些需要众多的资源记录来实现。DNS中的资源记录类型多达10种,在这里主要给大家说说几类常见的资源记录类型。

1) SOA记录

       SOA(Start Of Authority)起始授权记录,SOA记录表明了DNS服务器之间的关系。SOA记录表明了谁是这个区域的所有者。比如vinsent.cn这个区域。一个DNS服务器安装后,需要创建一个区域,以后这个区域的查询解析,都是通过DNS服务器来完成的。而这里所说的所有者,就是谁对这个区域有修改权利。常见的DNS服务器只能创建一个标准区域,然后可以创建很多个辅助区域。标准区域是可以读写修改的。而辅助区域只能通过标准区域复制来完成,不能在辅助区域中进行修改。而创建标准区域的DNS就会有SOA记录,或者准确说SOA记录中的主机地址一定是这个标准区域的服务器IP地址。SOA记录的格式与实例展示:

$TTL 86400      #  全局定义TTL,之后记录就不用再写TTL了
@         IN         SOA     ns1.vinsent.cn. admin.vinsent.cn. (
                     2017000002 ; 序列号
                     1H         ; 刷新时间
                     5m         ; 重试时间
                     2D         ; 过期时间
                     6H )       ; 否定答案缓存时间

说明:admin.vinsent.cn.表示管理员的邮箱地址,在这里我们不能直接写admin@vinsent.cn,必须将@用"."来替换。

2)NS记录

        NS(Name Server)名称服务器,NS记录实际上也是在DNS服务器之间,表明谁对某个区域有解释权,即权威DNS。比如你先在万网申请了一个域名ABC.COM。一般情况是万网的域名服务器替你来解析如www.vinsent.cn这样的主机记录。如果你想自己架设一个DNS服务器,让这台服务器从今往后替代万网的DNS服务器解析,那么你就需要在你的DNS上设置NS记录,然后将万网域名管理系统中的NS记录改成你的DNS_IP。这样以后就是你自己的DNS服务器负责提供解析了。即使万网的DNS服务器出现故障,别人仍然可以找到你。权威DNS通过NSLOOKUP工具可以查看。NS记录格式与实例

vinsent.cn.        IN          NS         ns1.vinsent.cn.
vinsent.cn.        IN          NS         ns2.vinsent.cn.
                               NS         ns3.vinsent.cn.
                               NS         ns4

说明:NS字段之前的内容,可省略不写,从上面SOA中继承,值得注意的是,上述记录要么写完整(ns1.vinsent.cn.)要么就直接不写从上面继承(ns1)。

3)A与AAAA记录

        A记录又称IP指向,用户可以在此设置子域名并指向到自己的目标主机地址上,从而实现通过域名找到服务器。他的值即指向的目标主机地址类型只能使用IP地址;而AAAA这表示IPv6地址的IP指向;例如:

vinsent.cn.         IN          NS         ns1.vinsent.cn.     
ns1.vinsent.cn.     IN          A         192.168.25.107     # A记录必须与NS记录成对出现

4)PTR记录

        PTR是pointer 的简写,PTR记录也被称为指针记录,PTR记录是A记录的逆向记录,作用是把IP地址解析为域名。DNS的反向区域负责从IP到域名的解析,因此如果要创建PTR记录,必须在反向区域中创建。

4.3.2.1.in-addr.arpa.     IN     PTR     www.magedu.com
4                         IN     PTR     www.magedu.com     # 网络地址及后缀可省略

5)MX记录

        MX即邮件交换记录。用于将以该域名为结尾的电子邮件指向对应的邮件服务器以进行处理。如:用户所用的邮件是以域名dadmin.com为结尾的,则需要在管理界面中添加该域名的MX记录来处理所有以@admin.com结尾的邮件。

        值得一提的是,MX记录可以使用主机名或IP地址;MX记录可以通过设置优先级实现主辅服务器设置,“优先级”中的数字越小表示级别越高。也可以使用相同优先级达到负载均衡的目的;如果在“主机名”中填入子域名则此MX记录只对该子域名生效。MX记录有优先级,其范围为0-99,其值越小,优先级越高。

ns1             IN     MX    10    mailserver     # 10表示优先级
mailserver      IN     A           172.18.253.142

6)CNAME记录

        CNAME通常称别名指向。可以为一个主机设置别名。比如设置wesrv.vinsent.cn,用来指向一个主机www.vinsent.com那么以后就可以用wesrv.vinsent.cn来代替访问www.vinsent.com了。值得注意的是:CNAME的目标主机地址只能使用主机名,不能使用IP地址;·主机名前不能有任何其他前缀,如:http://等是不被允许的;A记录优先于CNAME记录。即如果一个主机地址同时存在A记录和CNAME记录,则CNAME记录不生效。例如

web        IN         A         6.6.6.6
www        IN         CNAME     web


DNS主从原理


        作为DNS服务器,我们的职责就是为大量用户提供服务,即为他们解析ip地址,我们知道在互联网中,有时数据的访问量是非常大的,大量的请求同涌入到一台DNS服务器上,那么该DNS服务的资源几乎会被消耗殆尽,直至崩溃。由此我们引入了从服务器,从DNS服务主要是为了分担主DNS服务器的一些访问请求,从而实现了负载均衡。原理如下图:

 

wKiom1nEgQKQy9l3AABMcTTRcf0965.png

        子域授权,是指通过在原有的域上划出一个小的区域,并给新DNS服务器管理。如果有客户端请求解析在这个划分区域中的域名,则只要找新的子DNS服务器。这样的做的好处可以减轻主DNS的压力,也便于管理。比如,我们去访问www.vinsent.cn.这个域,从DNS查找过程我们可以知道,DNS是一级一级的查询,上级DNS服务器只知道其直接下级,这就是子域授权的结果。我们必须在根域”.”上授权顶级域“cn”,在顶级域上授权二级域(vinsent),如此下去直到找到www.vinsent.cn这个主机的IP地址。子域授权只需要在父域的的资源记录文件中添加子域的NS记录即可;例如:在cn域上授权vinsent域。

wKioL1nEga6xTeK1AAAnoy-9cFg167.png


搭建自己的DNS架构


    要想搭建一个完整的DNS服务器群,包括根域,顶级域,以及顶级域之下的子域,那么我们必须先规划好这个网络的结构,这样才能为我们的配置创造良好的实验条件,否者会有许许多多的问题出现。这里强调一点,不管是老鸟还是新手,无论我们是在写自动户脚本还是搭建服务,全局观的思维很重要,只要能理清、理顺这些原理和本质,实验只是结果的一种展示。

wKioL1nEmyuSgqMRAACr6M8FSNA197.png

1 实验准备

        首先准备6台或者7台主机,按上图对应的关系配置好主机的IP地址,当然了你也可以选择不修改ip地址,主机本来是什么地址就用什么地址,只要互相之间能通信即可。其次为了实验能够顺利的完成,我们还是一样,关闭selinux和防火墙(每一台主机),当然了这仅仅是实验环境,如果是真实环境,建议使用防火墙策略。本次实验都是在CentOS 7系统上完成的,如你你是CentOS 6的主机,那么有些命令需要调整。

[root@vinsent ~]# systemctl stop firewalld.service     # 关闭防火墙服务
[root@vinsent ~]# iptables -F                          # 清空防火墙策略
[root@vinsent ~]# setenforce 0                         # 临时禁用selinux
[root@vinsent ~]# sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config # 永久关闭selinux 
[root@vinsent ~]#

2 安装bind并认识其配置文件

        提供DNS服务的程序时bind,我们可以通过yum list bind来查看一些包的信息,使用rmp -ql 查看包中文件列表。

[root@vinsent ~]#yum -y install bind             # 安装bind
...省略过程...
[root@vinsent ~]#yum -y install bind-utils      # 安装bind-utils包,有些工具是由该包提供的
[root@vinsent ~]#yum info bind
Installed Packages
Name        : bind
Arch        : x86_64
Epoch       : 32
Version     : 9.9.4         # 版本
Release     : 51.el7
Size        : 4.3 M
Repo        : installed
From repo   : updates
Summary     : The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) server
URL         :   # 官方网站 
License     : ISC
Description : BIND (Berkeley Internet Name Domain) is an implementation of the DNS
            : (Domain Name System) protocols. BIND includes a DNS server (named),
            : which resolves host names to IP addresses; a resolver library
            : (routines for applications to use when interfacing with DNS); and
            : tools for verifying that the DNS server is operating properly.
[root@vinsent ~]# rpm -ql bind  # bind包含很多文件,这里只说几个重要的,常用的文件
/etc/named.conf                 # 全局配置文件,定义域与各种规则
/etc/named.rfc1912.zones        # 域配置的另外一个文件,我们可以将自己定义的域写在这个文件中
/etc/named.root.key             # 和dnssec认证有关的文件
/etc/rndc.conf                  # 管理工具rndc的配置文件
/usr/lib/systemd/system/named.service         # 服务名
/usr/lib64/bind
/usr/sbin/named                 # 服务的PATH路径
/usr/sbin/rndc
/var/named                       # 主服务器域的资源记录存放位置
/var/named/slaves                # 从服务器的资源记录存放目录
[root@vinsent ~]#

3 配置

1)修改根域资源记录

        按照上图中的要求,我们创建了6台主机,分别配置了相应的ip地址,我们便可以开始配置了。由于我们要配置根DNS以及所以,我们必须修改根域记录,指向我们想要的根。

[root@vinsent ~]# vim /var/named/named.ca      # 删除其他记录,只留下面两条记录即可
.                       518400  IN      NS      a.root-servers.net.
a.root-servers.net.     3600000 IN      A       172.18.253.177         # 根服务器的地址
[root@vinsent ~]#

说明,每个主机上的/var/named/named.ca都需要修改。

2)配置vinsent.cn域主DNS服务器

思路:在/etc/named.conf中添加vinsent.cn域,然后创建并书写域记录文件

[root@vinsent named]# vim /etc/named.conf         # 添加域
options {
//      listen-on port 53 { 127.0.0.1; };     # 注释掉这行或者将值该为any
        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";
        allow-query     { any; };             # 允许查询,修改为any或者特定网段,或主机  
        recursion yes;        # 是否允许递归
...后面省略...
 
}; 
zone "vinsent.cn" IN {             # 添加vinsent.cn正向域
        type master;
        file "vinsent.cn.zone";     # 正向域资源记录文件
};
zone "253.18.172.in-addr.arpa" IN {     # 添加vinsent.cn反向域
        type master;
        file "172.18.253.zone";     # 反向域资源记录文件
};

[root@vinsent named]# vim /var/vinsent.cn.zone     # 创建域文件并添加以下记录
$TTL 86400
@         IN         SOA     ns1.vinsent.cn. admin.vinsent.cn. (
                    2017000002
                    1H
                    5m
                    2D
                    6H )

                NS    ns1
ns1                A    172.18.253.142
web        IN         A     172.18.253.21 
www        IN         CNAME     web         # 别名记录

[root@vinsent named]# named-checkconf         # 检查配置文件是否有错,要养成检查错误的好习惯
[root@vinsent named]# named-checkzone "vinsent.cn" vinsent.cn.zone  # 检查资源记录文件是否有语法错误
[root@vinsent named]# chgrp named /var/named/vinsent.cn.zone     # 修改文件属组
[root@vinsent named]# chmod 640 /var/named/vinsent.cn.zone     # 安全起见,修改权限
[root@vinsent named]# systemctl restart named    # 重启服务

 3)配置vinsent.cn域从DNS服务器

方法同上,在配置文件中添加vinsent.cn域,不过这个域要指明主DNS,

[root@vinsent ~]# vim /etc/named.conf
options{
...省略...         # options 选项的设置与vinsent.cn域的设置相同,之后都是
}
zone "vinsent.cn" IN {
    type slave;
    file "slaves/vinsent.cn.zone";     # 从服务的资源记录文件要放到slave目录下
    masters { 172.18.253.142; };
};
[root@vinsent ~]# named-checkconf  # 检查一下语法是否有错
[root@vinsent ~]# systemctl restart named    # 重启服务
[root@vinsent ~]# cd /var/named/slaves/
[root@vinsent slaves]# ls     # 重启服务之后,文件自动生成,该文件来自主DNS服务器,从服务器会自动更新
vinsent.cn.zone

4)配置cn域

cn域的是vinsent.cn域的上级域,所以需要在cn域中对子域vinsent.cn进行授权。

[root@vinsent ~]# vim /etc/named.conf
...省略...
zone "cn" IN {         # 定义cn域
    type master;
    file "cn.zone";
};
[root@vinsent ~]# vim /var/named/cn.zone       # 创建cn域资源记录文件

$TTL 86400
@               IN              SOA     ns1     admin.cn. (
                                        2017000002
                                        1H
                                        5m
                                        2D
                                        6H )

                                NS      ns1
ns1             IN              A       172.18.254.238
vinsent         IN              NS      ns3             # 对子域进行授权,由于子域有主从两台服务器
vinsent         IN              NS      ns2             # 所以有两条记录
ns3             IN              A       172.18.250.234
ns2             IN              A       172.18.253.142
[root@vinsent ~]# named-checkconf  # 检查一下语法是否有错
[root@vinsent ~]# systemctl restart named    # 重启服务

4)配置根域“.”

根域是最高等级的域,那么需要在根域中对cn域进行授权,如下

[root@vinsent ~]# vim /etc/named.conf
...省略...
zone "." IN {
        type master;
        file "root.zone";
};
[root@vinsent named]# vim root.zone 

$TTL 86400
@               IN              SOA     @       admin.vinsent.cn. ( 2017000001 1H  5M   6H  1D )
                IN              NS      @
                IN              A       172.18.253.177
cn              IN              NS      ns2     # 对cn域进行授权
ns2             IN              A       172.18.254.238
[root@vinsent ~]# named-checkconf  # 检查一下语法是否有错
[root@vinsent ~]# systemctl restart named    # 重启服务

5)配置DNS转发器

转发器作用主要是将我们客户端的请求转发给根,并进行迭代,从而返回最终结果,配置如下:

[root@vinsent ~]# vim /etc/named.conf 
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";
        allow-query     { any; };
        forward first;
        forwarders { 172.18.253.177; };
        allow-transfer {any;};    # 是否允许追踪
        recursion yes;
        dnssec-enable no;         # 关闭dnssec认证
        dnssec-validation no;     # 这一项如果不该为no,实验将不会成功
        /* Path to ISC DLV key */
        bindkeys-file "/etc/named.iscdlv.key";

        managed-keys-directory "/var/named/dynamic";

        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";
};
//zone "." IN {              # 注释掉根域或者,直接删除,
//      type hint;
//      file "named.ca";
//};

[root@vinsent ~]# vim /var/named/named.ca 
.            518400    IN    NS    a.root-servers.net.             # 留一条根指向即可
a.root-servers.net.    3600000    IN    A    172.18.253.177
[root@vinsent ~]# named-checkconf  # 检查一下语法是否有错
[root@vinsent ~]# systemctl restart named    # 重启服务

到这里DNS的配置就算完成了,接下来调试一下,看看结果。


结果测试


        要测试结果,我们需要用到一个工具dig,这个命令来自于bind-utils包,使用该工具要确保你有安装这个包。接下来先来看看dig的用法:

dig [-t type] name [@server] [query options]

-t : 查询类型 [ A | NS | PTR | SOA ] 

+[no]trace    : 跟踪解析过程 : dig +trace vinsent.cn
+[no]recurse  : 进行递归解析
dig -x IP = dig –t ptr reverse_ip.in-addr.arpa     # 反向解析

 现在用dig来测试以下看看是否成功,篇幅影响,我这里只测试了一下,你还可以逐个测试。

[root@vinsent named]#dig www.vinsent.cn @172.18.253.142

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.62.rc1.el6 <<>> www.vinsent.cn @172.18.253.142
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17807
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 1, ADDITIONAL: 1

;; QUESTION SECTION:
;www.vinsent.cn.            IN    A

;; ANSWER SECTION:
www.vinsent.cn.        86400    IN    CNAME    web.vinsent.cn.
web.vinsent.cn.        86400    IN    A    172.18.253.21             #查询到了我们的地址

;; AUTHORITY SECTION:
vinsent.cn.        86400    IN    NS    ns1.vinsent.cn.

;; ADDITIONAL SECTION:
ns1.vinsent.cn.        86400    IN    A    172.18.253.142

;; Query time: 1 msec
;; SERVER: 172.18.253.142#53(172.18.253.142)
;; WHEN: Wed Sep 20 12:41:13 2017
;; MSG SIZE  rcvd: 100
[root@vinsent named]#

如果你每次的查询都能出现你想要的结果,那么说明你在配置是无误的。


错误分析


    我们在dig查询的结果,里面有一项,status,我们可以根据这个状态来分析,问题出在哪儿。

wKiom1nE8XriC4AqAAA2wUNvKMg597.png

 一般来说,常出现的状态主要有以下几种:

  • NXDOMAIN: 可能是CNAME对应的A记录不存在导致

  • REFUSEE:可能是DNS策略导致

  • NOERROR不代表没有问题,也可以是过时的记录,可以查看是否为权威记录,flags:aa标记判断


本篇小结


  到此,有关DNS的一些基础知识以及如何构建一个自己用的DNS服务器群就给大家说讲完了,本篇主要包括,DNS主从原理、资源记录等。在最后在给大家说一下排错的方法。主要有几个要点,selinux和iptables是否关闭,options中的选项是否设置正确,资源记录的文件权限是否允许named用户读,如果是特定区域的传送,是否定义好了forward项,大概就这些问题比较常见。谢谢大家的阅读~,欢迎大家留言,指出错误。