服务器架设篇 - RockyLinux 9

第八章、领域名称服务器 DNS 服务

无论是 WAN 还是 LAN,主机名称与 IP 地址的对应都是非常重要的!所以才需要 DNS 服务!

最近更新时间: 2023/11/30

以前提到 DNS 系统,大家都觉得似乎是在互联网服务上面才需要这东西!不过,大家想一想,我们在企业内部, 每部主机应该也都需要提供主机名称吧?如果通过自己的 /etc/hosts 文件来处理,每次增加/修改服务器 IP 地址与主机名称时, 你不是会变得很麻烦~所以啊!即使是 LAN 内部,事实上,我们还是需要一部 DNS 系统的。简单的处理方式有 dnsmasq 等软件, 不过,我们这边还是使用功能完整的 bind 软件来的查!这一章比较难~大家要多花点脑袋喔!

8.1、Domain Name Service (DNS) 系统

虽然对于互联网世界来说,我们主要是通过 TCP/IP 协定来连网,连网就得要有 IP 地址,IP 地址目前有 IPv4 与 IPv6 两种版本, 无论如何,有 public IP 地址或通过 NAT 的 private IP 地址之后,就可以连网。问题是,对于人类来说,这种数值方式的主机位置记忆, 还是无法跟文本相比的,文本类型的主机名称还是比较好记忆!为此,早期人们使用的是 /etc/hosts 来作为主机名称与 IP 地址的对应! 让我们来看一看 /etc/hosts 的内容:

[root@master ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
....
192.168.10.254     masterap.vbird    masterap
192.168.20.254     masterlan.vbird   masterlan

[root@master ~]# ping -c 2 masterap.vbird
PING masterap.vbird (192.168.10.254) 56(84) bytes of data.
64 bytes from masterap.vbird (192.168.10.254): icmp_seq=1 ttl=64 time=0.030 ms
....

如上,我们在 master 骨干系统上面设置过 192.168.10.254 对应到 masterab.vbird 的主机名称!这样会比较好记忆!但是,这种方式也只能在 master 骨干系统上生效!并无法对局域网路内的其他主机有效果~所以,在架设其他服务时,我们偶而会来拷贝 master:/etc/hosts 这个文件!只是...这样效率实在很糟糕!所以,后来才用 DNS 系统统一管理主机名称与 IP 地址的对应!

要记得,连接到 localhost 时,我们的软件可能会误判是 IPv6 (::1) 还是 IPv4 (127.0.0.1) 的地址,因为这两个 IP 地址对应, 都有写到 localhost 上!如果单纯要测试 127.0.0.1 的话,应该使用 localhost4 单独对应会比较好!
  • DNS 系统的目的

DNS 原始最主要的目的是『通过主机名称来找到该服务器的 IP 地址』,如此一来,人们就可以不用记忆 IP 地址而只须记忆主机名称即可。假设主机名称是人名,IP 地址是身份证好了,想想看,你是记忆朋友的名字比较厉害, 还是记忆朋友的身份证比较厉害?户政事务所要找的是身份证号码,但是我们要找的是人名,两者间的对应,对于服务器来说,就是 DNS 系统了。所以说, DNS 系统就是互联网的户政事务所啰。相关的 DNS 目标为:

  • 每一部连上网络的电脑 (无论 server/client),应该都要有一个网络主机名称 (公开或私有)
  • 上述主机名称应该要『登录在某一个 DNS 服务器底下』
  • 上述服务器若要让全世界查找的到,就需要『注册在 DNS 系统的架构底下』
  • 最终,任何软件只要通过询问 DNS 系统,就会知道某网络电脑的主机名称对应到的 IP 地址
  • 找到 IP 地址是最重要的目的 (正解)
  • DNS 架构下的主机名称命名方式 - 了解 FQDN

主机名称也不是随便就能命名的!各个国家的名字命名方式都不一样啊!在台湾,就像您的大名一样,也不是可以随便更改的! 至少,你的姓氏基本上就是不能变更对吧!一般来说,人名与地址相关的命名方式有点像这样:

  • 先分区域,包括台北的、高雄的、台南的
  • 再分姓氏,姓蔡的、姓邱的、姓林的等等
  • 最后才是名字
  • 一般 DNS 的写法与西方姓名编排比较像,重要的姓氏在后面,名字在前面,所以就会变成:
    • 鸟哥.蔡.台南 (住台南的蔡鸟哥)
    • 鸟哥.邱.台北 (住台北的邱鸟哥)
    • 名字都叫鸟哥,但是因为姓氏与住址不同,而可以找到正确的人名~我们姑且称之为『完整的人名系统』

网络主机名称跟上述的系统架构就很像了!你必须要去注册一个领域名 (姓氏),你的主机名 (名字) 才能够让人家找到正确的地方。 就跟树状结构一样,我们总是要找到『根 (root)』之后,才能够往树干、树枝、叶子等去搜索到最终的数据!那么那个『根』是什么? 我们以台湾教育部的 www 服务器来说明好了:

  • 所有主机名称都是从一个『顶层』所延伸出来的,这个顶层也称为 root,设计上是一个小数点 (.)
  • 台湾有跟顶层注册一个姓氏,就是 .tw. 这个顶层姓氏
  • 然后通过 .tw. 自己分配台湾自己的下层领域,例如 .gov.tw., .edu.tw. 等等
  • 每个下层姓氏再自己成立所需要的主机名称,例如 www.edu.tw. 这个教育部的 WWW 服务器主机名!
  • 从主机名称到最顶层 (www.edu.tw.) 这个完整的主机名称,就被称为 FQDN (Fully Qualified Domain Name)

以上面的例子来说,www.edu.tw. 这个 FQDN 可以拆成两个部份,一个是主机名称 (hostname),一个是领域名称 (domain name)。 这个例子的主机名称为 www 而领域名称为 edu.tw.!这一个大架构其实可以视为分布式『数据库』系统!因为所有的名字都在个别的 DNS 服务器当中设置,再通过加入 DNS 系统,让大家都能查找的到!基本的 DNS 大架构是这样的:

  • 最顶层 (类似根目录) 基本上有 13 部系统在管理下层的数据链接
  • 每一个节点只负责自己所管理注册的网域,其他网域则会去顶层 (类似根目录) 寻找关联点再去往下找。

所以最重要的就是『注册』啰!就像你生出小孩,得要去户政事务所报户口一样啦!只是有所谓的『授权』功能,让你也能开小型户政事务所而已。

用过 Linux 的应该都知道『目录树 (directory tree)』系统吧!你可以说,每一个目录就是一个 DNS 服务器管理的领域,每个文件名就代表一个主机名称。 要查到某个独一无二的文件名,要从根目录 (/) 开始查找 (绝对路径文件名)。同理,要查到某个主机名称,要从最顶层 (.) 开始查找! 所以,对于 DNS 系统最简单的认知,就是把它当成目录树结构的目录(领域名称)与文件名(主机名称)!而绝对路径文件名,就是 FQDN 啦!

8.1.1、DNS 的阶层架构与 TLD

基本上,DNS 系统与目录树结构真的非常类似~DNS 纪录的主机名称是从 . 开始查找领域与主机名称,而目录树的文件名则是从根目录 / 开始查找到完整的绝对路径主机名称。根据维基百科 domain name space 的图标重新绘制成为如下图标,我们来了解一下整体 DNS 的阶层架构:

图 8.1.1、DNS 阶层架构的 domain name space 示意图
图 8.1.1、DNS 阶层架构的 domain name space 示意图

每个虚线环都是一个区域 (zone),而且这个 zone 必须要跟上层注册取得委任授权,才是合法的 zone,这个 zone 主要是由名称服务器 (name server) 所维护管理。所以,当我们昆山科大的计算机中心想要有自己的名称服务器时,就得要跟教育部 edu.tw. 这个 zone 注册取得委任授权~ 如此,未来 edu.tw. 就不再纪录 *.ksu.edu.tw. 的主机名称,而是『导向委任的子区域 (subzone)』去向下查找! 因为每个 zone 只能纪录与自己有关的领域名称,所以,昆山科大必要的 domain 一定含有上层领域名称,所以就只能是申请 ksu.edu.tw.。

申请合法授权的意义是,当昆山科大自己的服务器创建一个例如 www.ksu.edu.tw. 这样的 FQDN 时,在左下角的 zone 由计算机中心自己设置好,无须通知任何人,任何在互联网上面的电脑,通过从顶层 (.) 开始查找,就可以找到 ksu.edu.tw. 所纪录的 www 服务器的 IP 地址了!

就跟 Linux 的根目录底下所创建的第一层目录 (例如 /etc, /home, /usr 等) 是有特殊意义的一样,最古早的时候,由最源头的根 (.) 记载的最顶层领域名称 (Top Level Domain, TLD) 仅有 .com, .org, .edu, .gov, .net, .mil 等, 后来又加入国码,后来又加入其他洲码,后来又加入其他名称等~不过,总的来说,原始定义为:

  • 一般最上层领域名称 (Generic TLDs, gTLD):例如 .com, .org, .gov 等等
  • 国码最上层领域名称 (Country code TLDs, ccTLD):例如 .tw, .uk, .jp, .cn 等

至于最早 root 仅管理六大领域名称,分别如下:

早期的 6 种 TLD 名称与内容
领域名称代表意义
com公司、行号、企业
org组织、机构
edu教育单位
gov 政府单位
net 网络、通信
mil 军事单位

台湾 (.tw) 管理的下一层领域名称,大概也都维持相同的 gTLD 的分类~不过后来 TWNIC 有开放台湾底下的顶层领域名称申请喔! 因此,鸟哥才有办法申请到 vbird.tw. 这样的领域名称哩!从这个案例我们也可以知道:

  • 主机名称或新申请的授权领域名称,必定包含上层领域名称 (所以 ksu 只能是 ksu.edu.tw.)
  • 申请到合法授权的领域之后,该领域下的主机名称,一经设置,即可被整个 DNS 系统查找到 (无须回报上层)

更多详细的 TLD 领域名称可以参考底下的网址,台湾除了有『.tw』之外,还有『.台湾』哩!台湾的 TLD 则是由 TWNIC (Taiwan Network Information Center) 所维护。

8.1.2、主机名称解析流程与递归查找方式(dns resolver, recursive query)

当你的电脑有连上某部主机的需求时,你的软件 (例如浏览器) 会向 DNS 服务器 (DNS resolver) 要求取得该主机名称的 IP 地址, 例如我们需要知道 www.vbird.tw 这个主机名称所代表的 IP 地址时,我们的 resolver 会去跟 DNS 服务器要求这个主机名称, 然后 DNS 服务器会去查找最顶层 root 的位置,而 root 只会告知下一层,也就是 tw. 的位置,然后再去找 vbird.tw.,如此层层查找,就可以知道 www.vbird.tw. 是纪录在 vbird.tw. 的领域下,通过该名称服务器纪录的信息,我们就可以查找到 www.vbird.tw. 地址,接下来我们的软件就可以连上该 IP 地址了!整体流程有点像底下这样:

图 8.1.2-1、通过 DNS 系统查找主机名称(FQDN)的整体流程示意图
图 8.1.2-1、通过 DNS 系统查找主机名称(FQDN)的整体流程示意图

上面的图标意思是:

  1. 我们的软件有连网需求,需要连接到 www.vbird.tw,于是向 DNS 服务器询问该主机的 IP 地址。
  2. 我们的 DNS 没有该笔纪录,但是有 . 的纪录,所以前去 . 查找 www.vbird.tw.
  3. root (.) 仅有纪录 tw. 的服务器地址纪录,所以叫 DNS 解析器去 tw. 询问
  4. tw. 仅有 vbird.tw. 的服务器地址纪录,所以叫 DNS 解析器去 vbird.tw. 询问
  5. vbird.tw. 确实有 www 的数据 (www.vbird.tw.),所以回答 DNS 解析器实际的 IP 地址。
  6. 最后,DNS 解析器会将 www.vbird.tw. 的 IP 地址数据记忆在内存中,并且该笔纪录会有 TTL (time to live) 的存活时间,然后回报我们操作的软件,软件就可以开始连到 www.vbird.tw. 了!
  • TTL (time to live) 的意思

上面的流程应该不是很难理解~比较特别的只有 ttl 而已!ttl 主要是由 vbird.tw. 这部 DNS 服务器所针对 www.vbird.tw. 所设置! 意思是『这笔纪录建议放置到 DNS 解析器的内存存活的时间』,根据这个建议,DNS 解析器 (上图左侧的方块) 会将这笔纪录放置到内存当中一段时间, 在这段 ttl 存活时间内,如果有其他软件也需要 www.vbird.tw. 的 IP 地址时,DNS 解析器将会直接把内存内的 IP 地址提供出去, 不会重新跑一次 root(.) 开始的流程!这样可以降低很多的 DNS 查找流量!

也就是说,当 www.vbird.tw. 这笔纪录存活在内存当中时,查找流程只需要『 0 --> 1 --> 5 』就可以取得正确的 IP 地址! 不需要 2, 3, 4 的步骤喔!但是对于较为频繁变动的主机名称对应的 IP 地址来说,ttl 不要设置太久...否则,刚改过 IP 地址时, 某些电脑会有一段时间无法连到正确的 IP 地址,这是因为他们使用的 DNS 解析器可能还在 ttl 的缓存记忆中!所以提供的是旧的 IP 地址喔!

  • 用 whois 简单检查合法授权的领域名称

我们这个章节的目的,主要就是想要架设如上图的 vbird.tw. 这个领域名称服务器 (name server) 的角色!这部主机需要取得合法授权! 怎么知道一个领域有没有经过合法的授权呢?我们在指令列模式底下,可以通过 whois 来直接查得注册的消息:

[root@master ~]# yum install whois

[root@master ~]# whois [领域名称]
[root@master ~]# whois vbird.tw
Domain Name: vbird.tw
   Domain Status: ok
   Registrant:
....
   Domain servers in listed order:
      dns.vbird.tw      140.116.44.179
      dns2.vbird.tw     140.116.44.180

Registration Service Provider: HINET
Registration Service URL: http://domain.hinet.net

[root@master ~]# whois www.vbird.tw
网域名称不合规定

[root@master ~]# whois my.vbird
No whois server is known for this kind of object.

从上面我们可以清楚的知道,whois 指令后面要接的是领域名称,而不是 FQDN!如果有显示领域名称的状态,那就代表有相关注册的数据! 那就是一个合法的授权领域名称。上表后面两个错误的示范,就代表不是领域名称,或根本没有该领域名称的意思!所以,我们就可以在 vbird.tw. 这个领域底下随便创建属于鸟哥自己的主机名称了!

  • 使用 dig 做 +trace 追踪流程

上头的示意图,如果将要 2, 3, 4 当中的每个步骤都抓出来检测看看,该如何处理?我们可以使用 dig 这个指令加上 +trace 参数来查找即可! 我们来检查一下全部的流程看看:

[root@master ~]# dig +trace www.vbird.tw
; <<>> DiG 9.16.23-RH <<>> +trace www.vbird.tw
;; global options: +cmd
.                       16299   IN      NS      f.root-servers.net.
.                       16299   IN      NS      l.root-servers.net.
.                       16299   IN      NS      e.root-servers.net.
......
;; Received 715 bytes from 120.114.100.1#53(120.114.100.1) in 0 ms
# 由 120.114.100.1 查找到 . 共有多台 NS 的纪录数据存在!随机取一个来使用

tw.                     172800  IN      NS      a.dns.tw.
tw.                     172800  IN      NS      g.dns.tw.
......
;; Received 945 bytes from 192.203.230.10#53(e.root-servers.net) in 6 ms
# 由 e.root-servers.net 查找到 tw. 共有多台 NS 的纪录,随机取一个来使用

vbird.tw.               3600    IN      NS      dns.vbird.tw.
vbird.tw.               3600    IN      NS      dns2.vbird.tw.
......
;; Received 623 bytes from 203.73.24.25#53(a.dns.tw) in 6 ms
# 由 a.dns.tw 查找到 vbird.tw. 有两部 NS 的纪录,随机取一台来使用

www.vbird.tw.           600     IN      CNAME   linux.vbird.tw.
linux.vbird.tw.         600     IN      A       140.116.44.180
vbird.tw.               600     IN      NS      dns2.vbird.tw.
vbird.tw.               600     IN      NS      dns.vbird.tw.
;; Received 174 bytes from 140.116.44.180#53(dns.vbird.tw) in 1 ms
# 由 dns.vbird.tw 找到正确的 IP 地址了!

上面的数据,若搭配我们图标的步骤,那就可以清楚的看出来:

  1. 从 global 开始到第一个 Received 数据当中,那个 . 的 IP 地址对应是由 120.114.100.1 所提供的。 该 120.114.100.1 就是我们自己设置的 DNS 解析器!
  2. 由前一步骤所得知的 e.root-servers.net 服务器当当中取得 tw. 的数据
  3. 由前一步骤所得知的 a.dns.tw 服务器当中取得 vbird.tw. 的数据
  4. 由前一步骤所得知的 dns.vbird.tw 查找到 www.vbird.tw 为别名,实际名称为 linux.vbird.tw,并查得 IP 地址定位为 140.116.44.180
  • 查找方式 query 与 recursive

一般来说,每部 DNS 服务器,都会回报它自己纪录的领域数据,亦即 zone 里面的信息如果是该 DNS 服务器自己管的, 那就可以直接提供给用户端软件,这就是所谓的查找 (query)。下图在右边的三部 DNS 服务器提供的查找方式, 就是 query 的查找方式,每部服务器仅提供自己拥有的纪录值而已,这也是正常 DNS 服务器应该要提供放行的功能。

而下图中左侧的 DNS 解析器,可以帮我们用户端软件去向外查找,尤其是从 root (.) 开始查起~这个递归查找的动作,就称为 recursive 查找。通常 DNS 服务器不会开放 recursive 查找!因为容易被乱用,导致 DNS 服务器所在的带宽被 DDoS 打到爆炸... 一般来说,DNS 服务器只会开放内部用户或者是特定用户作为递归查找的信任用户!

图 8.1.2-2、recursive 与 query 查找示意图
图 8.1.2-2、recursive 与 query 查找示意图
  • DNS 服务器的角色位置

还记得我们在网络参数设置的章节中,都会跟大家说,你的 DNS 服务器 IP 地址可能需要填写两台嘛!为什么要填写两台呢? 现在你知道,我们人类大概都用主机名称来记忆,而互联网主要是 TCP/IP,所以能够将两者在背景自动转换的 DNS 系统, 就显得相当重要!如果没有 DNS 系统,我们大概所有的网络服务通通不能使用了吧!所以说,如下图所示,所有的网络电脑都需要设置好名称解析器的 DNS IP 地址才行!我们使用的是 Network Manager 管理机制,但其实 Linux 记忆名称解析器的设置档是在 /etc/resolv.conf 这个文件内!

图 8.1.2-3、DNS 角色示意图
图 8.1.2-3、DNS 角色示意图
# 查找系统内的 DNS 服务器设置
[root@master ~]# cat /etc/resolv.conf
# Generated by NetworkManager
search vbird
nameserver 120.114.100.1   <==第 1 台,主要的 DNS 递归服务器
nameserver 168.95.1.1      <==第 2 台,次要的 DNS 递归服务器

因为我们底下会设置 DNS 服务器,所以这里应该要正名为本机的名称解析设置!从设置上面就可以看到,事实上我们目前设置两部名称解析器, 分别是 120.114.100.1 以及 168.95.1.1。为什么要设置两部呢?如图 8.1.2-3 所示,如果主要的解析器挂掉 (本例当中是 120.114.100.1 那部), 那么我们的电脑会主动找第二台次要的那部做查找!所以在图 8.1.2-3 当中才会有灰色字体的部份~在一切正常的情况下, 次要的 DNS server 是不会被使用的!那是预防第一部 DNS 出问题时的保险动作。要注意的是, 120.114.100.1 以及 168.95.1.1 虽然都是互联网的 DNS 服务器,其中 120.114.100.1 是昆山科大内部的 DNS 递归服务器,校外不能使用喔!168.95.1.1 则是中华电信放行的递归服务器。

一般来说,企业内部的 DNS 递归服务器应该是不容易出问题~外部的 DNS 系统也通常防护的很好,所以, 在 /etc/resolv.conf 内的 nameserver 解析器不必设置超过 3 部以上!通常有备援想法所以设置 2 部即可! nameserver 设置太多也没有意义~

8.1.3、DNS 数据库类型 (hint/master/slave)

在图 8.1.1 当中,我们知道每个虚线都是一个区域 (zone),每个 zone 都会代表一个领域 (domain),而这个 zone 的内容, 就是被 DNS 服务器所维护!那这些纪录的数据,在 Linux 的 DNS 惯用软件中,都是使用文本档作为主机名称与 IP 地址对应的纪录格式, 但无论如何,我们还是习惯以 DNS 数据库来解释这个 zone 的数据就是了。

  • Zone 的正解与反解

如上所述,DNS 数据库内的纪录,其实就是主机名称与 IP 地址的对应表,但是到底是主机名称对应到 IP 地址?还是 IP 地址对应到主机名称呢? 在 DNS 系统当中,原本正常的情况当然是从主机名称找到 IP 的对应,因此这个方向称为正解。反过来说,如果数据库纪录的信息是从 IP 地址去对应主机名称的话,那就称为这是一个反解的 zone 设置。

  • 在 DNS 服务器的数据库设置中,不管是正解还是反解,每个领域的记录就是一个区域 (zone)
  • 从主机名称查找到 IP 的流程称为:正解
  • 从 IP 反解析到主机名称的流程称为:反解

刚刚上面讲到的是 zone 的纪录领域是主机名称或 IP 地址,如果 zone 要解析的 domain 是主机名称,那么得到的答案就是 IP 地址, 因此就是正解。如果 zone 要解析的 domain 是 IP 地址,那么就会得到主机名称,因此这时就会是反解。我们等等讲反解的 zone 时, 再来详细说明。

  • 数据库 Zone 的类型

从图 8.1.1 当中,我们知道 DNS 服务器管理的都是一个个的 zone,每个 zone 可能都是一个正解或反解~不过, 当中有个比较特别的存在!我们知道每个 zone 应该都是需要向上层 zone 申请授权,但是...那个 root (.) 要不要申请授权? 此外,我们从前一个小节也知道 DNS 最好有备援,也就是说,同一个 zone 最好有两部以上的 DNS 服务器维护较佳! 因为同一个 zone 放在两个不同的 DNS 上,那么如果 DNS 内容设置错误 (例如手滑写错数字),不就非常糟糕! 所以,这时就有所谓的 hint, master, slave 的 zone 的格式。

  • hint: 记录最顶层 (.) 的领域记录方式,每部 DNS server 都应该要有这个记录才对
  • master: 让管理员手动或通过管理界面『主动』修改主机名称与 IP 对应的数据库内容,该数据库类型就称为 master。
  • slave: 与 master 同样可以管理同一个 domain 的数据库,但其数据库的来源为直接从 master 的记录中同步而取得的

基本上,从图 8.1.2-2 的主机名称查找流程来说,你会发现到 DNS 服务器缺省应该都要知道最顶天的 root (.) 这个 zone, root (.) 的 zone 纪录的数据库类型,就被称为 hint,这是每部 DNS 服务器都应该要设置的才对!而 hint 数据库类型可以从 internic 网站下载~这个 zone 的数据库内容,基本上是不会随意改变的!

除了 root zone 是使用 hint 类型之外,其他的 zone 无论正反解,基本上缺省应该都是放置成为 master 的类型! 也就是数据库文件内容要创建/删除/变更,我们管理员得要手动去更改数据才行!但是如前所述,那如果手滑了,导致数据输入错误, 或者是像 root zone 一样,共有 13 部主机要维护,那得要分别连进 13 部主机去维护数据才行,这怎么合理?因此就有 slave 数据库的类型了。

slave 数据库类型,管理员并不需要手动去修改!只是必须要指定这个 slave 类型的 zone 要跟哪个 master 进行数据库内容同步即可! 所以,master 维护好新的数据库纪录,slave 就会自动跑来更新啦!两者就同步了!一般来说,当 master 维护过纪录的数据, 重新启动服务时,就会主动告知 slave 来更新。而 slave 在缺省的设置中,也会定期来跟 master 要求数据库的同步就是了!

  • Master/Slave 数据库类型的查找权重

master/slave 在 DNS 的数据库类型中,只是定义出纪录的信息更新的方式,并不会影响到图 8.1.2-2 的查找流程! 在 DNS 的查找中,获得的数据总是先抢先赢。例如,root zone 共有 13 部,那你的 DNS 是使用 13 部当中的哪一个? 这当然是通过轮询机制来的!也就是这 13 部 server 在 DNS 查找的角度上,其重要性是一模一样的!这是 DNS 的大架构! 至于 master/slave 则仅是定义出,你的数据维护该如何进行而已!并不是 master 的数据库类型就比较伟大喔!不要跟图 8.1.2-3 搞混了!

鸟哥初次接触 DNS 系统时,就是以为 master DNS 查不到时,才会去查 slave 数据库类型~所以先跟 ISP 注册两部 DNS server 的 IP 地址对应, 然后仅架设一部 DNS 服务器而已。没想到要连接到自己的网站时,有时候会卡住,有时候又很顺!非常奇怪!使用 IP 地址输入在网址列, 那就肯定非常顺。后来才发现,原来 master / slave 数据库类型的权重是一模一样的!这就导致互联网的电脑,有时候查去不存在的那部 DNS 系统, 就导致找不到 IP 地址纪录 (因为鸟哥根本没有架设另一部 DNS 服务器)!所以这里才加强说明喔!

8.1.4、数据库记载的内容 (resource recode, RR)

当我们从 DNS 查找到数据时,该笔纪录其实提供非常多的信息喔!包括该笔 FQDN 的维护者 DNS 服务器、 实际回应的数据、回应的旗标信息 (flags) 等等,接下来,我们就来谈一谈这些回应的消息~

  • 旗标信息 (flags)

DNS 回应消息的旗标信息,可以在使用 dig 查找时,从前面几行表头数据查到。我们通过目前的环境来检测一下 www.vibrd.tw 的查找信息好了:

# 以目前的 DNS server 查找 www.vbird.tw 的信息
[root@master ~]# dig www.vbird.tw
; <<>> DiG 9.16.23-RH <<>> www.vbird.tw
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37144
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 10, ADDITIONAL: 14
....

通过上面的信息,我们可以知道这笔纪录的旗标有 qr, rd, ra 三个项目,而底下的信息分别有一个查找 (QUERY)、 2 个答案 (ANSWER)、10 个授权 (AUTHORITY)以及 14 个额外信息 (ADDITIONAL)。好了,那 flags 是什么意思? 从 wiki 的数据查找得到相关的旗标意义为:

DNS 查找数据的 flags 旗标信息
旗标代码信息内容
qr 此回应信息为查找 (query) 或回应 (reply)
rd Recursion Desired,用户端需要进行递归查找的功能
ra Recursion Available,此 DNS 解析器具有递归查找的功能
aa Authoritative Answer,此纪录为有经授权的回应信息

大致上比较常看到且需要了解的就是这几个!我们在上面 dig 查找中,也可以查找到 qr, rd, ra 等旗标信息,问题不大! 但是,那个 aa 旗标怎么来?最简单的想法,就是通过检查具有自己主机名称纪录的 DNS 服务器即可!简单的说, 你可以找 www.ksu.edu.tw 主机名称在 120.114.100.1 这部 DNS 服务器!处理方案如下:

# 120.114.100.1 具有 ksu.edu.tw. 这个 zone 的维护权,所以这样做:
[root@master ~]# dig www.ksu.edu.tw @120.114.100.1
; <<>> DiG 9.16.23-RH <<>> www.ksu.edu.tw @120.114.100.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52431
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 3
....

因为鸟哥的测试环境是在昆山科大网络环境当中,所以上面的 flags 会出现 ra 的旗标,否则,一般只会出现 qr, aa 与 rd 而已。 因为这笔纪录是 120.114.100.1 这部 DNS 服务器本身在维护,所以就显示出这是授权回应的信息!

  • 纪录资源 (Resource Record, RR)

现在,让我们来看一下 dig 指令回复的问题 (Question) 与回答 (anwser) 区段的展示消息:

[root@master ~]# dig www.vbird.tw
...
;; QUESTION SECTION:
;www.vbird.tw.                  IN      A

;; ANSWER SECTION:
www.vbird.tw.           303     IN      CNAME   linux.vbird.tw.
linux.vbird.tw.         303     IN      A       140.116.44.180
...

基本上,纪录的信息字段有点像这样:

[domain]    [ttl]           IN  [[RR type]  [RR data]]
[待查数据]  [暂存时间(秒)]  IN  [[资源类型] [资源内容]]

以查找 www.vbird.tw 的结果来说,最终回应的是『linux.vbird.tw. 的存活时间为 303 秒,我们需要的是 A (Address) 的信息, 其信息为 140.116.44.180』这样的意思!所以重点其实是『 A 140.116.44.180 』这一段回应信息!至于 CNAME 则是别名的意思! 那么常见的 RR 有哪些呢?大致上有这些:

# 常见 DNS server 管理需要的纪录资源,假设 zone 为 domain.
[domain]   IN  [[RR type]  [RR data]]
domain.    IN  SOA         管理这个 domain 的七个重要参数 (容后说明) 
domain.    IN  NS          管理 domain. 这个 zone 的 DNS 服务器主机名称

# 在 DNS 管理的 zone 规范的主机名称内,主要的正解纪录类型
[domain]   IN  [[RR type]  [RR data]]
hostname.  IN  A           hostname. 的 IPv4 的 IP 地址
hostname.  IN  AAAA        hostname. 的 IPv6 的 IP 地址
domain.    IN  MX 权重数   接收 domain. 邮件的服务器主机名字
hostname.  IN  CNAME       hostname. 为别名,实际名称为此主机名称
hostname.  IN  TXT         一串代表 hostname. 的解释数据,当前环境很常用于 mail server

# 在 DNS 管理的 zone 规范的主机名称内,主要的反解纪录类型
[domain]   IN  [[RR type]  [RR data]]
hostname.  IN  PTR         代表 hostname. 这个领域的指向主机名称,通常 hostname. 是 IP 的领域!
  • SOA: 针对整体 zone 的纪录需求 (master/slave)

正反解都需要的 RR 项目,主要有 SOA 与 NS 两者~比较需要注意的是 SOA (start of authority) 的项目! 这个项目内的信息比较多~而且主要是针对 master/slave 的 DNS 数据库结构所必须要的设置!如果只有单台 DNS 的设计, 那么这个项目就比较不要紧~但是...我们都建议要架设两部以上的 DNS 啦!所以当然两部 DNS 的同步就很重要!所以, SOA 就一定得要了解才行。我们先来看看 google.com 这个 domain 的设置值好了!

[root@master ~]# dig -t soa google.com
....
;; QUESTION SECTION:
;google.com.            IN  SOA

;; ANSWER SECTION:
google.com.         60  IN  SOA   ns1.google.com. dns-admin.google.com. 584847865 900 900 1800 60
....
# 上面这行后面的特殊字体意义说明,共有 7 大项
# 1. 主要的 (master) DNS 服务器主机名称:  ns1.google.com.
# 2. google 的 DNS 管理员 email:          dns-admin@gogle.com.
# 3. 目前数据库的序号:                    584847865
# 4. slave 数据库间隔多久会主动去更新:    900 秒
# 5. 若前一个更新失败,多久重新更新:      900 秒
# 6. 如果持续更新失败,多久之后就不再更新:1800 秒
# 7. 错误查找纪录的 TTL 时间:             60 秒

上面的数据我们可以用英文这样呈现:

domain. ttl IN SOA servername. adm_email. serial refresh retry expire minimum

至于详细相关数据,可以这样看:

  • domain.
    SOA 主要是针对整体的 zone,所以待查项目就是这个 zone 的名称!除了完整撰写成为 FQDN 之外,也可以使用 @ 代表!你没看错, @ 这个符号在 zone file 里面是有特殊意义的!所以不要随便使用 @ 喔!
  • servername.
    这个 Domain 的主要 DNS 服务器 (master server) 之主机名称
  • adm_email.
    是 DNS 管理员的 email,一般 email 写法为『 user@host.domain.name. 』这样,但是因为 @ 代表了 zone 的名称, 所以 @ 需要用小数点取代~所以整体写成:『 user.host.domain.name. 』这样!
  • serial (序号)
    这个 zone file 的版本,数字越大代表越新的版本!一般建议使用『YYYYMMDDXX』(年/月/日/两位数字) 来取代! 除了好记忆之外,也不会超出最大序号值。这个数字很重要喔!slave 的 zone file 版本若比较旧,那在更新时间到的时候, 就会同步数据~如果 slave 数据库比较新,那反而就不会同步了!
  • refresh (更新频率)
    slave 主动向 master 数据库检查 zone file 版本的间隔时间。
  • retry (失败重新尝试)
    当 slave 更新失败时,才会触发 retry 时间!
  • expire (失效时间)
    如果一直持续失败到这个 expire 的间隔时间,那就不再主动更新,直到 DNS 服务器重新启动为止。
  • minimum (错误纪录时间)
    这个数值已经被调整了!目前的定义是,错误查找的数据 (NXDOMAIN) 所缓存 (TTL) 在 DNS resolver 上面的时间~你没看错~错误查找的数据也会被缓存!这真是相当有趣的设置!

在 Linux 的 bind 软件上面,都有提供默认值给大家参考,可以直接引用默认值即可。不过,最后一个设置值已经修订成为错误纪录的 TTL 时间, 以前都习惯这个项目设置为 86400 啦!现在可以将这个 TTL 改成跟正常查找数据的 TTL 即可!否则,错误数据 cache 在人家的 DNS 服务器上太久, 我们自己的更新反而没被查找到,这也挺奇怪的!

  • @ 与小数点 (.) 及完整主机名称 (FQDN) 的关系

首先你要注意的是,在 DNS 设置上,我们通常说的 FQDN 其实是『 hostname.domain. 』这样的格式!最后那个小数点代表最顶层的 root zone! 然后,所谓的 domain name 通常就是 zone 的名称!而我们说的数据库,其实就是个别的 zone file (zone 设置档)!

在所有 dig 的输出中,你应该发现了,跟 domain 还是 hostname 有关的名称,结尾几乎都会加上小数点 (.), 那个小数点代表的是 root zone 的意思!如果主机名称没有加上小数点,那么 DNS 数据库就会以为该笔数据为 hostname 而已, 而不是 FQDN,因此会主动加上 domain name!例如,你设置写上『 www.vbird.tw 』没有加上小数点,而 zone 假设为 vbird.tw, 那么该笔设置的 FQDN 会变成『 www.vbird.tw.vbird.tw. 』!所以小数点非常非常重要!

  • NS: 针对整体 zone 的纪录需求,设置 DNS server

先来看看 google 公司纪录自己 DNS 的 server 有几台?

[root@master ~]# dig -t ns google.com
....
;; QUESTION SECTION:
;google.com.                    IN      NS

;; ANSWER SECTION:
google.com.             21600   IN      NS      ns3.google.com.
google.com.             21600   IN      NS      ns1.google.com.
google.com.             21600   IN      NS      ns2.google.com.
google.com.             21600   IN      NS      ns4.google.com.

;; ADDITIONAL SECTION:
ns4.google.com.         7220    IN      A       216.239.38.10
ns4.google.com.         7407    IN      AAAA    2001:4860:4802:38::a

我们跟 DNS 解析器说,需要 google.com 这个 domain 的 DNS 名称服务器是谁?答案回答 4 台,亦即有 4 部 google DNS 服务器! 而其中 ns4.google.com. 的 IPv4 地址为 216.239.38.10 这样的意思。要注意的是, NS 也是针对整体 zone 的设置! 所以你不能使用『 dig -t ns www.google.com 』这样的方式去查!因为 www.google.com 只是一个 google.com 这个 zone 底下的一台主机名称而已。

  • A, AAAA: 仅针对某主机名称的 IP 地址对应

缺省的正解数据就是使用 A 或 AAAA,分别代表 IPv4 与 IPv6 的 IP 地址。因为这是 DNS 最原本的设计需求, 所以不用『 dig -t a www.google.com 』,直接『 dig www.google.com 』即可!太简单了!就查找即可!不做说明了!

[root@master ~]# dig www.google.com
;; QUESTION SECTION:
;www.google.com.                        IN      A

;; ANSWER SECTION:
www.google.com.         205     IN      A       142.251.42.228

A 与 AAAA 都是针对单一主机名称做 IP 地址的对照!但是,你也可以给整个网域的名称一个 IP 地址喔! 所以,如果你『 dig google.com 』也可以取得一个 IP 地址喔!

  • MX: 针对收信主机名称的设置 (Mail eXchanger)

MX 是 Mail eXchanger (邮件交换) 的意思,由于邮件主机所发送的数据就有点像信件,然后你也知道广告信可以塞在你家的信箱! 因此,有阵子在不受管制的情况下,很多邮件主机就被拿来架设广告信发信站,造成很多的网络带宽与垃圾信件的问题。 所以,后来『合法』的邮件主机,『该主机名称一定会对应一个以上的 MX 纪录』,否则,该邮件主机名称所发出的信件, 就会被当成垃圾信件或被直接丢弃。当然 MX 不止这个功能,它还可以让你的信件不容易遗失~设置多个 MX 并架设多台 mail server, 可以让你的邮件比较不容易遗失!先来看看 google 的 gmail 设置:

[root@master ~]# dig -t mx gmail.com
;; QUESTION SECTION:
;gmail.com.              IN   MX

;; ANSWER SECTION:
gmail.com.         3284  IN   MX   40 alt4.gmail-smtp-in.l.google.com.
gmail.com.         3284  IN   MX   5 gmail-smtp-in.l.google.com.
gmail.com.         3284  IN   MX   10 alt1.gmail-smtp-in.l.google.com.
gmail.com.         3284  IN   MX   20 alt2.gmail-smtp-in.l.google.com.
gmail.com.         3284  IN   MX   30 alt3.gmail-smtp-in.l.google.com.

MX 后面会加上权重数字,数字越小代表越重要!所以,当有个邮件名称为 user@gmail.com 寄出之后,这封邮件就会被送到 gmail-smtp-in.l.google.com. 这部邮件主机上~并由此邮件服务器收下,因为这部主机的 MX 权重数字最小 (5)。 如果该部主机因为某些原因导致你的邮件无法送达,那这封邮件就会送到 alt1.gmail-smtp-in.l.google.com. 上!因为它是后续次小的权重值! 在 gmail 的例子中,我们就知道 gmail 至少架设 5 部邮件服务器的意思,邮件就不容易不见!

如果你要收信的主机名称不只是网域,而是有多个主机名称时,所有要能收信的邮件主机都需要有 MX 喔!举例来说, 以昆山科大为例,我们通常使用的 email 是: user@mail.ksu.edu.tw~那如果你想让 user@ksu.edu.tw 也能收信, 这两个主机名称 (mail.ksu.edu.tw, ksu.edu.tw) 就都需要有 MX 的设置!当然你可以设置在同一部邮件主机来接收!

[root@master ~]# dig -t mx ksu.edu.tw
;; ANSWER SECTION:
ksu.edu.tw.             3600    IN      MX      8 mx01.ksu.edu.tw.

[root@master ~]# dig -t mx mail.ksu.edu.tw
;; ANSWER SECTION:
mail.ksu.edu.tw.        3600    IN      MX      8 mx01.ksu.edu.tw.

你会发现两者都寄到同一台邮件主机上喔!不过需要注意的是,MX 后面接的主机名称,需要有对应的 A 或 AAAA 的 IP 地址纪录才行! 不可以是 CNAME 喔!另外,为了加强邮件服务器的合法性,目前还多了很多的纪录信息喔!未来谈到 mail server 时, 我们再来继续聊聊~

  • CNAME: 作为别名指向正确的主机名称

有时候你不想要针对某个主机名称设置 A 的标志,而是想通过另外一部主机名称的 A 来规范这个新主机名称时,可以使用别名 (CNAME) 的设置喔!举例来说,在台湾,查看新闻的时候,还是很可能会前往 tw.yahoo.com 查看的!这部主机的 IP 地址为何呢?

[root@master ~]# dig tw.yahoo.com
;; QUESTION SECTION:
;tw.yahoo.com.                  IN      A

;; ANSWER SECTION:
tw.yahoo.com.           26      IN      CNAME   fp-ycpi.g03.yahoodns.net.
fp-ycpi.g03.yahoodns.net. 47    IN      A       180.222.106.12
fp-ycpi.g03.yahoodns.net. 47    IN      A       180.222.109.251
fp-ycpi.g03.yahoodns.net. 47    IN      A       180.222.109.252
fp-ycpi.g03.yahoodns.net. 47    IN      A       180.222.106.11

我们可以看到,查找是 tw.yahoo.com. 的 A,但是回应则是显示 CNAME 到 fp-ycpi.g03.yahoodns.net. 上头, 然后该主机有 4 个 IP 地址~CNAME 有点像 Linux 的符号链接啦!未来只要改了 fp-ycpi.g03.yahoodns.net. 的设置即可, 不用理会 tw.yahoo.com.!因为实际上用的是 fp-ycpi.g03.yahoodns.net. 的 A 纪录就是了。

  • PTR: 由 IP 地址找出主机名称的反解指向 (Pointer)

由 IP 地址反向找出主机名称,使用的就是 PTR 这个纪录~但是要查反解时,我们使用的参数是 dig -x 喔! 让我们来瞧一瞧,找到的第一个 google.com 的 IP 地址反向追踪会变怎样?

# 先由短输出信息来查找 google.com 的 IP 地址
[root@master ~]# dig +short google.com
142.251.42.238

# 再来查一下上面的 IP 地址对应的主机名称又是什么?
[root@master ~]# dig -x 142.251.42.238
;; QUESTION SECTION:
;238.42.251.142.in-addr.arpa.   IN      PTR

;; ANSWER SECTION:
238.42.251.142.in-addr.arpa. 45321 IN   PTR     tsa01s11-in-f14.1e100.net.

我们可以发现,询问的信息从 142.251.42.238 变成了『 238.42.251.142.in-addr.arpa. 』,里面有两个重点, 第一个是 IP 地址反过来写了 (238.42.251.142),第二个是最终的名称会加上『 in-addr.arpa. 』 。我们知道 IP 地址的记载,是从左侧到右侧,所以 class A/B/C 是从左侧第一组 10 进位去开始查找的!但是 DNS 主机名称则是西式名字的写法,也就是右侧才是代表家族名称~所以 DNS 是从右侧开始查找。为了让 IP 地址的查找符合 DNS 右侧开始查找的方式,所以 IP 地址需要反过来写~而且为了让 DNS 知道这其实是 IP 地址的领域 (反解),所以需要加上特殊的『 in-addr.arpa. 』这样的领域结尾!

8.2、DNS 系统规划设置与安装测试 bind 软件

要开始来架设 DNS 服务器之前,得要想想我们内部的系统该如何规划!另外,这部 DNS 服务器的硬件/操作系统/网络环境/软件等等, 也应该要来好好的处理一下才行!在互联网上,bind (Berkeley Internet Name Domain, BIND) 这套达成 DNS 功能的软件是挺常使用的, 这也是我们缺省的 DNS 软件!所以,让我们开始来学习学习。

8.2.1、DNS 系统规划与设置

假设我们已经向上层领域注册了两台 DNS 服务器,然后未来这两部 DNS 服务器还需要对外提供服务!所以,这两部系统应该要放置到 DMZ 的网域中。基本上 DNS 服务器不应该放置在同一个 IP 地址网域当中的,不过我们这边只是做个仿真练习的环境, 所以暂时将这两部系统放置在一起喔!这点要多多留意才好!

  • 处理硬件设置档 (XML)、硬盘档 (.img) 等信息

由于拷贝硬盘数据时,来源文件应该要在干净 (clean) 的状态下较佳!因此,我们先将 server_raw 的虚拟机先关闭起来再说。 关闭完成之后,再来处理 XML 的拷贝以及 .img 的拷贝即可。现在,先登录我们的母机器 (cloud.vbird) 系统, 然后进行整体流程大概如下所示:

# 1. 确认在 KVM 母机器上面,然后确认一下,如果 server_raw 虚拟机存在,就关闭它
[root@cloud ~]# hostname
cloud.vbird
# 请确定是在 KVM 母机器上头!否则会找不到相关的映像档与 XML 档!

[root@cloud ~]# virsh list
 Id   Name         State
----------------------------
 1    master       running
 2    client_raw   running
 3    server_raw   running
# 看起来 server_raw 是存在的,所以,先来关闭它!

[root@cloud ~]# virsh shutdown server_raw
Domain 'server_raw' is being shutdown
# 需要静待几秒钟,等待 server_raw 的关闭!

# 2. 拷贝两个硬盘文件,分别给 DNS master/slave 使用
[root@cloud ~]# cd /kvm/img
[root@cloud img]# cp server_raw.img server_dns_master.img
[root@cloud img]# cp server_raw.img server_dns_slave.img

# 3. 处理 XML 硬件设置档
[root@cloud img]# cd /kvm/xml
[root@cloud xml]# cp server_raw.xml server_dns_master.xml
[root@cloud xml]# cp server_raw.xml server_dns_slave.xml

[root@cloud xml]# vim server_dns_master.xml
  <name>server_dns_master</name>
    <loader readonly="yes" type="pflash" secure="no">/usr/share/edk2/ovmf/OVMF_CODE.fd</loader>
    <nvram>/kvm/xml/server_dns_master.uefi.fd</nvram>
      <source file="/kvm/img/server_dns_master.img"/>
      <mac address="52:54:00:00:30:c1"/>
    <graphics type="vnc" port="5931" listen="0.0.0.0" passwd="rocky9">

[root@cloud xml]# vim server_dns_slave.xml
  <name>server_dns_slave</name>
    <loader readonly="yes" type="pflash" secure="no">/usr/share/edk2/ovmf/OVMF_CODE.fd</loader>
    <nvram>/kvm/xml/server_dns_slave.uefi.fd</nvram>
      <source file="/kvm/img/server_dns_slave.img"/>
      <mac address="52:54:00:00:30:c2"/>
    <graphics type="vnc" port="5932" listen="0.0.0.0" passwd="rocky9">

# 4. 之后就启动它吧!
[root@cloud xml]# virsh create server_dns_master.xml
[root@cloud xml]# virsh create server_dns_slave.xml
[root@cloud xml]# virsh list
 Id   Name                State
-----------------------------------
 1    master              running
 2    client_raw          running
 13   server_dns_master   running
 15   server_dns_slave    running

[root@cloud xml]# netstat -tlunp | egrep '^Pro|qemu'
Proto Recv-Q Send-Q Local Address   Foreign Address  State   PID/Program name
tcp        0      0 0.0.0.0:5909    0.0.0.0:*        LISTEN  786802/qemu-kvm
tcp        0      0 0.0.0.0:5920    0.0.0.0:*        LISTEN  786920/qemu-kvm
tcp        0      0 0.0.0.0:5932    0.0.0.0:*        LISTEN  985321/qemu-kvm
tcp        0      0 0.0.0.0:5931    0.0.0.0:*        LISTEN  984148/qemu-kvm
  • 网络布建规划

如前所述,我们的两部 DNS 系统未来可能会提供给 internet 使用,所以理论上应该要放置到可以被外部网络访问的 DMZ 环境中。 另外,为了区分网络来源是 AP、内部网络还是外部的 DMZ 网络,因此我们预计给予三个 zone,分别是 ap.vbird, lan.vbird 及 server.vbird 共三个。当然啦,每个正解的 zone 我们预计都给予一个反解的 zone!相关的图标如下所示。

图 8.2.1、DNS 系统的网络布建示意图
图 8.2.1、DNS 系统的网络布建示意图

我们已经创建了 master DNS 与 slave DNS 的系统,现在,请使用 VNC 连接到这两部系统上,分别使用如下的设置来处理各自的网络环境。 为什么要使用 VNC 呢?我们同时启动两部拷贝来自 server_raw 的硬件系统,所以这两部硬件缺省的主机名称都是 server001,而且网络也都设置为手动, 所以目前就会 IP 地址冲突啦~建议就是使用 VNC 连接到主系统来处理,比较可以忽略网络 IP 地址变化造成的问题!所以,底下的行为, 请通通在 VNC 的本机终端机环境下处理喔!

# 1. 在 Master DNS 上面处理底下的行为:
[root@server001 ~]# hostnamectl hostname dns1.server.vbird
[root@dns1 ~]# nmcli connection modify enp1s0 ipv4.method manual ipv4.addresses 192.168.30.211/24 \
> ipv4.gateway 192.168.30.254 ipv4.dns 120.114.100.1,168.95.1.1
[root@dns1 ~]# nmcli connection up enp1s0
[root@dns1 ~]# dig +short www.google.com
172.217.163.36
# 最终有回应信息,应该就是达到网络正常了!

# 2. 在 Slave DNS 上面处理底下的行为:
[root@server001 ~]# hostnamectl hostname dns2.server.vbird
[root@dns2 ~]# nmcli connection modify enp1s0 ipv4.method manual ipv4.addresses 192.168.30.212/24 \
> ipv4.gateway 192.168.30.254 ipv4.dns 120.114.100.1,168.95.1.1
[root@dns2 ~]# nmcli connection up enp1s0
[root@dns2 ~]# dig +short www.vbird.tw
linux.vbird.tw.
140.116.44.180
# 这次我们来测试另一部主机~可以看到 www.vbird.tw 也有相关的 IP 地址!

将两部 DNS 的网络搞定之后,再来就准备架设 DNS 服务器了!

8.2.2、bind 软件安装

bind 是达成 DNS 服务的一个软件,主要是由柏克莱大学所开发的套件 (Berkeley Internet Name Domain, BIND)。 这个软件虽然功能相当完整,不过,过去有许多资安方面的问题,因此,运作时,建议将此软件的功能锁住于 /var/named/chroot/ 目录下! 为了方便设置,bind 同时提供了 bind-chroot 的软件,可以让管理员快速的设置 chroot 的功能。

bind 提供了名为 named 的软件,同时提供了 named.service 的服务。而 bind-chroot 则提供了 named-chroot.service 的服务。 基本上, named.service 及 named-chroot.service 并没有什么太大的差异,只是 named-chroot 主动将服务关在 /var/named/chroot 而已。 而由于 bind-chroot 软件已经帮我们做好了目录的对照,所以我们可以依据正常的 named 设置来处理设置档,只要启动的服务是 named-chroot 就好了!相当方便!

  • 在 dns1 及 dns2 安装 bind, bind-chroot, bind-utils 软件

直接安装好我们需要的软件,底下的动作请分别在两部主机上面进行!

# 1. 先进行全系统的更新
[root@dns1 ~]# yum -y update

# 2. 开始安装 DNS 所需要的软件
[root@dns1 ~]# yum -y install bind bind-chroot bind-utils

# 3. 查看主要设置档:
[root@dns1 ~]# ll -d /etc/named.conf /var/named/*
-rw-r-----. 1 root  named 1722 Nov 11 10:55 /etc/named.conf              <==主设置档
drwxr-x---. 8 root  named   73 Nov 27 20:37 /var/named/chroot
drwxrwx---. 2 named named    6 Nov 11 10:55 /var/named/data
drwxrwx---. 2 named named    6 Nov 11 10:55 /var/named/dynamic
-rw-r-----. 1 root  named 2253 Nov 11 10:55 /var/named/named.ca          <==root zone file
-rw-r-----. 1 root  named  152 Nov 11 10:55 /var/named/named.empty
-rw-r-----. 1 root  named  152 Nov 11 10:55 /var/named/named.localhost   <==正解范例档
-rw-r-----. 1 root  named  168 Nov 11 10:55 /var/named/named.loopback    <==反解范例档
drwxrwx---. 2 named named    6 Nov 11 10:55 /var/named/slaves
# 上面的动作,请在 dns2 上面一样做一次!

这样就安装妥当了!但是缺省的 named-chroot 这个 DNS 服务,仅提供如下的功能:

  • 仅监听 DNS 要求在 127.0.0.1 这个界面
  • 仅允许本机 (127.0.0.1) 的数据查找要求 (query)
  • 针对整个 Internet 放行 DNS 代理查找 (recursion) 的功能
  • 加载了 . 的 root zone file
  • 加载了文档上要求加载的 zone

所以,准备来修改修改主设置档~

8.2.3、caching only DNS 服务器建置/测试

因为 named 这个服务缺省只给本机自己使用,亦即无法当成外部的递归 DNS 服务器!同时也不给外部查找 (query)! 只开放自己查找而已。这样根本无法作为内部 DNS Server 使用,因此我们需要来修改一下!虽然图 8.2.1 已经规划好了所有的 zone, 不过,我们这边先想要了解的是,DNS 作为缓存功能的情况下,只有 root zone file 时,该如何设计?预计这个内部 DNS server 需要达成的目的是:

  • 设置 mynet 的 ACL,加入 192.168.10.0/24, 192.168.20.0/24, 192.168.30.0/24 这三段 IP 地址
  • DNS 监听在本机的所有网络界面
  • 允许全部 (any) 来源的查找 (query)
  • 仅允许本机与 mynet 的来源帮忙做递归 (allow-recursion)
  • (option):使用上层 DNS 服务器作为转递 (forwarders) 服务器来源
  • 设置 /etc/named.conf 主设置档,并启动 named-chroot

要达成上述的功能,需要将主设置档做个修订~我们来测试看看:

[root@dns1 ~]# vim /etc/named.conf
// 这个是注解
/* 这个也是注解!但是需要前后包夹 */

acl mynet { 192.168.10.0/24; 192.168.20.0/24; 192.168.30.0/24; 127.0.0.0/8; }
// 列出一个别名 (acl) 为 mynet,代表的是上述的四个网段 ( 连同 localhost )
options {
        listen-on port 53 { any; };     // 监听在所有网络界面
        listen-on-v6 port 53 { any; };  // 监听在所有 IPv6 界面
        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";
        secroots-file   "/var/named/data/named.secroots";
        recursing-file  "/var/named/data/named.recursing";
        allow-query     { any; };       // 允许所有来源的查找

        // recursion yes;
        allow-recursion { mynet; };     // 删除全部递归,只让本地端主机递归

        dnssec-validation yes;
        managed-keys-directory "/var/named/dynamic";
        geoip-directory "/usr/share/GeoIP";
        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";
        include "/etc/crypto-policies/back-ends/bind.config";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

// zone 的设置值!非常重要!需要搭配 8.1.3 的说明查阅
zone "." IN {               // 这个 zone 针对的是 root file (.)
        type hint;          // 类型是 hint 数据库
        file "named.ca";    // zone file 文件名为 /var/named/named.ca
};

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

acl 是一个 access control list 的设计,可以将复杂的/重复出现的数据用简单的文本代替!所以上述的数据中, 我们用 acl 取名一个 mynet 作为 4 段网域的代表名称!any 代表的是所有的网域!allow-query 指的是可以查找的来源, allow-recursion 则是能够递归查找的来源!相关的 query/recursion 查找,请查阅 8.1.2 的说明。 基本上不用做什么奇怪的设置,大部分沿用设置档内容即可。接下来检查一下设置档,如果没有问题,就直接启动 named-chroot 服务!

# 使用 named-checkconf 检查 /etc/named.conf 设置档是否有问题
[root@dns1 ~]# named-checkconf
/etc/named.conf:10: missing ';' before 'options'
# 如上所示,设置档第 10 行在 options 设置之前,似乎少了分号!鸟哥故意留了个错误在上面!
# 请自行修改成正确的数据喔!修改完成之后再次 named-checkconf,一直到没出现问题为止!

# 启动 named-chroot 服务,并且查阅一下服务状态
[root@dns1 ~]# systemctl --now enable named-chroot.service
[root@dns1 ~]# systemctl status named-chroot
● named-chroot.service - Berkeley Internet Name Domain (DNS)
     Loaded: loaded (/usr/lib/systemd/system/named-chroot.service; enabled; preset: disabled)
     Active: active (running) since Mon 2023-11-27 21:25:08 CST; 41s ago
     ....

Nov 27 21:25:08 dns1.server.vbird named[4534]: all zones loaded
Nov 27 21:25:08 dns1.server.vbird named[4534]: running
Nov 27 21:25:08 dns1.server.vbird systemd[1]: Started Berkeley Internet Name Domain (DNS).
Nov 27 21:25:09 dns1.server.vbird named[4534]: resolver priming query complete
Nov 27 21:25:09 dns1.server.vbird named[4534]: managed-keys-zone: Initializing automatic ..

[root@dns1 ~]# tail /var/log/messages

基本上,这样就设置好 caching only 的 DNS 服务器!要注意的是,在缺省的情况下,named 的注册表信息是纪录到 /var/log/messages 这个文件内,所以,如果重新启动了 named-chroot 后,请使用 tail 或 less 等指令去观察一下 /var/log/messages 喔! 非常重要!不要忘记!上述的动作完成后,请在 dns2.server.vbird 系统上实做!

  • 放行防火墙的 dns 访问功能

这部系统仅能提供 ssh 以及 dns 而已,其他的服务先关掉~

[root@dns1 ~]# firewall-cmd --list-services
cockpit dhcpv6-client ftp http https ssh

[root@dns1 ~]# firewall-cmd --remove-service={cockpit,dhcpv6-client,ftp,http,https}
[root@dns1 ~]# firewall-cmd --add-service=dns
[root@dns1 ~]# firewall-cmd --list-services
dns ssh

[root@dns1 ~]# firewall-cmd --runtime-to-permanent

很快的使用 firewalld 将防火墙搞定~设计完毕,也请针对 dns2.server.vbird 进行完整的设置!

  • 开始测试 DNS

现在,请开始测试这部 DNS 是否正常运作了!要注意的是,因为我们还是往外查找,所以,查找时可能会比较慢! 而且查找的数据实际上是会缓存的!测试看看先:

# 1. 在骨干系统上面测试一下:
[root@master ~]# dig www.vbird.tw @192.168.30.211
....
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; QUESTION SECTION:
;www.vbird.tw.                  IN      A

;; ANSWER SECTION:
www.vbird.tw.           600     IN      CNAME   linux.vbird.tw.
linux.vbird.tw.         600     IN      A       140.116.44.180

;; Query time: 1516 msec
;; SERVER: 192.168.30.211#53(192.168.30.211)
# 确定有回应数据!我们的 DNS 系统实际活起来了!

# 2. 自己的 dns1 系统,使用自己的服务来测试看看:
[root@dns1 ~]# nmcli connection modify enp1s0 ipv4.dns 127.0.0.1
[root@dns1 ~]# nmcli connection up enp1s0
[root@dns1 ~]# dig www.vbird.tw
...
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; QUESTION SECTION:
;www.vbird.tw.                  IN      A

;; ANSWER SECTION:
www.vbird.tw.           384     IN      CNAME   linux.vbird.tw.
linux.vbird.tw.         384     IN      A       140.116.44.180

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)

如果对于自己的 DNS server 有信心的话,那么所有内部的系统通通用这部服务器来作为 DNS 查找! 此时可以直接修改网络设置值,这样就能使用共同的 DNS 服务了!也请将 dns2 的 DNS 查找改为 127.0.0.1 喔!

  • 使用 forwarders 设置

你可能会发现,怎么我们的 DNS 服务器查找的速度有点慢?这是因为内部系统电脑数量不够多,所以我们的 DNS 每次都要从 root (.) 去查找! 连去国外查找速度确实很慢啊!那,我们能不能借用上层 DNS 服务器?因为 DNS 服务器越多人用,使用到相同的主机名称查找越可能重复, 所有主机名称就越可能缓存在 DNS 系统上!所以,使用上层 DNS 作为代查手段,应该是比较合理的啦!在鸟哥的场域,我们上层 DNS 是 120.114.100.1 这一台,所以我可以这样做:

# 1. 修改主设置档
[root@dns1 ~]# vim /etc/named.conf
        // recursion yes;
        allow-recursion { mynet; };
        forwarders {
                120.114.100.1;
                120.114.150.1;
        };

[root@dns1 ~]# named-checkconf
[root@dns1 ~]# systemctl restart named-chroot

再次 dig 查找相关数据之后,你会发现,我们的查找速度会变快喔!请在 dns2 机器上面也这么处理!

8.3、zone file 的设置

我们从上面的测试,可以知道 zone 的定义是在 /etc/named.conf 主设置档内,同时主设置档也会宣布该 zone 的 zone file 完整文件名! 所以,整体来说,主要还是需要 /etc/named.conf 啦!而我们从前几个小节也知道,zone 的类型有 hint (.)、master 与 slave。 hint 就是单纯的 root zone 设置,数据可以使用套件提供的,也可以自行从 internic 网站取得~手动自己改数据的 zone file 称为 master 格式! 自动更新的则是在 slave DNS server 上的设置!底下我们就分别来谈一谈!

8.3.1、正解档的主设置与 zone file 设置方式 (type master)

我们从图 8.2.1 了解正解档共有 3 个 zone,底下鸟哥只进行 client*.lan.vbird 这个 zone 的实做, 其他三个 zone 的实做是相同的处理方式~所以我们就不浪费篇幅~只是大家真的要实际实做出来才行喔!

  • zone 的设置与 zone file 文件名设计

我们先做一个名为 lan.vbird 的 zone,假设 zone file 的名称就设置为 /var/named/named.lan.vbird,一般来说, zone file 常以 named 做开头,后续则接 zone 的名字即可!那么这个 dns1 的设置中,要能允许 dns2 的整体 zone 传输需求, 因此, named.conf 的设置可以写成这样:

[root@dns1 ~]# vim /etc/named.conf
zone "." IN {
        type hint;
        file "named.ca";
};
zone "lan.vbird" IN {
        type master;
        file "named.lan.vbird";
        allow-transfer { 192.168.30.212; };
};

[root@dns1 ~]# named-checkconf
  • zone file 内容设置

确定没问题之后,再来则是前往 /var/named 去创建一个 named.lan.vbird 的文件,zone file 的内容格式需要注意的有:

zone file 内容格式
字符意义
一定从行首开始 所有设置数据一定要从行首开始,前面不可有空白字符。若有空白字符,代表延续前一个 domain 的意思~非常重要~
@ 如前所述,这个符号代表 zone 的意思!zone 的名称则是设置于 named.conf 当中!若为反解领域, 则可能成为类似 20.168.192.in-addr.arpa. 这样的名称!
. 这个点 (.) 很重要!因为他代表一个完整主机名称 (FQDN) 而不是仅有 hostname 而已。
; 代表注解符号~似乎 # 也是注解~两个符号都能使用

接下来,就让我们实际来设计一下相关的设置值:

# 1. 创建 named.lan.vbird 的方式,包括权限与内容
[root@dns1 ~]# cd /var/named
[root@dns1 named]# cp -a named.localhost named.lan.vbird
[root@dns1 named]# chown root.named named.lan.vbird
[root@dns1 named]# chmod 640 named.lan.vbird
[root@dns1 named]# vim named.lan.vbird
; 这个 zone file 的 zone 缺省为 lan.vbird.  @ 就是 lan.vbird.
$TTL 600                                ; 统一创建全部纪录的 TTL 时间
@       IN SOA  dns1.lan.vbird. adm.mail.server.vbird. (
                        2023112801      ; serial
                        3H              ; refresh
                        15M             ; retry
                        1D              ; expire
                        600 )           ; minimum
; 这个 zone 的 DNS server 指定
@       IN NS   dns1.lan.vbird.
@       IN NS   dns2.lan.vbird.
dns1    IN A    192.168.30.211
dns2    IN A    192.168.30.212
; 其他用户端的设置!主要是分给内网用的,共计 100 台!可用 gogozone.sh 创建
masterlan       IN A    192.168.30.254
client001       IN A    192.168.20.1
client002       IN A    192.168.20.2
...

# 2. 可用底下的脚本,修改之后,即可大量的处理相似数据的输出
[root@dns1 named]# vim gogozone.sh
#!/bin/bash
for i in $( seq -w 1 100)
do
        ip=$( echo $i | sed 's/^0*//g' )
        echo -e "client${i}\tIN A\t192.168.20.${ip}"
done

[root@dns1 named]# sh gogozone.sh >> named.lan.vbird

# 3. 记得要检查看看这个 zone 的设置是否正确!
[root@dns1 named]# named-checkzone {zone} {zone filename}
[root@dns1 named]# named-checkzone lan.vbird named.lan.vbird
zone lan.vbird/IN: loaded serial 2023112801
OK
  • 重新启动服务与测试

如果上面两个测试指令 named-checkconf 与 named-checkzone 都运行过无误,那么你的 named-chroot 应该就能重新加载设置了!

[root@dns1 named]# systemctl restart named-chroot

如果一切顺利,那么我们就可以开始检查设置是否正确!请注意,所有你加入 zone file 的设置,全部都要测试!因为数据量太多, 所以鸟哥底下使用 +short 的方法来检测,注意输出的信息是否正确喔!我们设置的项目有 SOA, NS, A 等三个主项目!

[root@dns1 named]# dig +short -t soa lan.vbird
dns1.lan.vbird. adm.mail.server.vbird. 2023112801 10800 900 86400 600

[root@dns1 named]# dig +short -t ns lan.vbird
dns2.lan.vbird.
dns1.lan.vbird.

[root@dns1 named]# dig +short dns1.lan.vbird
192.168.30.211
[root@dns1 named]# dig +short dns2.lan.vbird
192.168.30.212
[root@dns1 named]# dig +short masterlan.lan.vbird
192.168.20.254
[root@dns1 named]# dig +short client001.lan.vbird
192.168.20.1
[root@dns1 named]# dig +short client100.lan.vbird
192.168.20.100

这样看起来大致上都有出现正确的数据!也就完成一个正解的 zone 处理了!

  • 设置与测试 ap.vbird 正解

请依据前面的设置流程,完成 ap.vbird 这个 zone 的设置 (查阅图标 8.2.1),假设 zone file 文件名为 /var/named/named.ap.vbird, 这边我们不浪费篇幅,请大家由刚刚的 named.lan.vbird 以及 gogozone.sh 的运作,同样创建 100 个主机的 A 对应。 最终检测结果会是这样:

[root@dns1 ~]# dig +short -t soa ap.vbird
dns1.ap.vbird. adm.mail.server.vbird. 2023112801 10800 900 86400 600

[root@dns1 ~]# dig +short -t ns ap.vbird
dns2.ap.vbird.
dns1.ap.vbird.

[root@dns1 ~]# dig +short dns1.ap.vbird
192.168.30.211
[root@dns1 ~]# dig +short dns2.ap.vbird
192.168.30.212
[root@dns1 ~]# dig +short masterap.ap.vbird
192.168.10.254
[root@dns1 ~]# dig +short ap001.ap.vbird
192.168.10.1
[root@dns1 ~]# dig +short ap100.ap.vbird
192.168.10.100

注意,一定要查找正确喔!不可以有失败或错误的情况发生!

  • 设置与测试 server.vbird 正解

请依据前面的设置流程,完成 server.vbird 这个 zone 的设置 (查阅图标 8.2.1),假设 zone file 文件名为 /var/named/named.server.vbird, 因为这个地方的设置主要都是固定 IP 地址的方式,所以不需要有太多的缺省主机名称,所以只创建 10 个主机的 A 对应即可! 最终检测结果会是这样:

[root@dns1 ~]# dig +short -t soa server.vbird
dns1.server.vbird. adm.mail.server.vbird. 2023112801 10800 900 86400 600

[root@dns1 ~]# dig +short -t ns server.vbird
dns2.server.vbird.
dns1.server.vbird.

[root@dns1 ~]# dig +short dns1.server.vbird
192.168.30.211
[root@dns1 ~]# dig +short dns2.server.vbird
192.168.30.212
[root@dns1 ~]# dig +short masterdmz.server.vbird
192.168.30.254
[root@dns1 ~]# dig +short server01.server.vbird
192.168.30.1
[root@dns1 ~]# dig +short server10.server.vbird
192.168.30.10

注意,一定要查找正确喔!不可以有失败或错误的情况发生!

8.3.2、slave 向 master 要求数据库同步的设置方式 (type slave)

Slave 的同步更新挺简单的!比较需要注意的是,通常我们的 slave 向 master 要数据之后,会将数据自动复写到 /var/named/slaves/ 目录下! 所以我们不需要重新撰写 zone file~只要将 /etc/named.conf 设置好即可!现在,请在 dns2 上面如此设置:

# 1. 在 slave DNS (dns2) 设置好 /etc/named.conf
[root@dns2 ~]# vim /etc/named.conf
zone "." IN {
        type hint;
        file "named.ca";
};
zone "lan.vbird" IN {
        type slave;
        file "slaves/named.lan.vbird";
        masters { 192.168.30.211; };
};
zone "ap.vbird" IN {
        type slave;
        file "slaves/named.ap.vbird";
        masters { 192.168.30.211; };
};
zone "server.vbird" IN {
        type slave;
        file "slaves/named.server.vbird";
        masters { 192.168.30.211; };
};

# 2. 重新启动 named-chroot,并查看输出消息
[root@dns2 ~]# systemctl restart named-chroot
[root@dns2 ~]# tail -n 100 /var/log/messages| grep 'lan.vbird'
Nov 28 17:01:30 dns2 named[5842]: zone lan.vbird/IN: Transfer started.
Nov 28 17:01:30 dns2 named[5842]: transfer of 'lan.vbird/IN' from 192.168.30.211#53: 
                                  connected using 192.168.30.212#40163
Nov 28 17:01:30 dns2 named[5842]: zone lan.vbird/IN: transferred serial 2023112801
Nov 28 17:01:30 dns2 named[5842]: transfer of 'lan.vbird/IN' from 192.168.30.211#53: 
                                  Transfer status: success
Nov 28 17:01:30 dns2 named[5842]: transfer of 'lan.vbird/IN' from 192.168.30.211#53: 
                                  Transfer completed: 1 messages, 107 records, 2816 bytes, 
                                  0.001 secs (2816000 bytes/sec) (serial 2023112801)
Nov 28 17:01:30 dns2 named[5842]: zone lan.vbird/IN: sending notifies (serial 2023112801)

# 3. 看看 zone file 有没有被自动的创建起来
[root@dns2 ~]# ll /var/named/slaves/
-rw-r--r--. 1 named named 4505 Nov 28 17:01 named.ap.vbird
-rw-r--r--. 1 named named 5014 Nov 28 17:01 named.lan.vbird
-rw-r--r--. 1 named named  828 Nov 28 17:01 named.server.vbird

只要 zone file 有自动被创建起来,那就应该是正常运作了!只是,这个 slave 的数据格式为 named 的数据库格式, 并不是我们习惯的纯文本模式喔!所以,如果想要以纯文本模式来观察时,就得要通过某些特别的指令来观察了:

[root@dns2 ~]# named-compilezone -f raw -o - server.vbird /var/named/slaves/named.server.vbird
zone server.vbird/IN: loaded serial 2023112801
server.vbird.             600 IN SOA  dns1.server.vbird. adm.mail.server.vbird. 2023112801 10800 900 86400 600
server.vbird.             600 IN NS   dns1.server.vbird.
server.vbird.             600 IN NS   dns2.server.vbird.
dns1.server.vbird.        600 IN A    192.168.30.211
dns2.server.vbird.        600 IN A    192.168.30.212
masterdmz.server.vbird.   600 IN A    192.168.30.254
server01.server.vbird.    600 IN A    192.168.30.1
.....
OK

如果够小心翼翼的话,那么在 dns2 同样使用 dig 的方式,一个一个主机名称与设置去检查!确认 OK 才好喔!

8.3.3、反解档的设置方式

确定正解流程没问题之后,同时也解决了 master/slave 的设置,那就可以开始来处理反解。如同图 8.2.1 所示, 我们基本上会有 3 组反解的 zone,要记得反解的 zone 设置的方式是 (1)IP 地址反过来写 (2)结尾需加上 .in-addr.arpa.。 所以,192.168.{10,20,30}.0/24 这三组网段,其 zone name 就会变成:

  • 10.168.192.in-addr.arpa.
  • 20.168.192.in-addr.arpa.
  • 30.168.192.in-addr.arpa.

依循正解档的对应,反解数据除了实际应用的 IP 地址之外,也只使用 1~100 号而已!接下来就让我们依序来处理:

  • 主设置档 /etc/named.conf 的修改

先来处理 dns1 的 master DNS 设置:

[root@dns1 ~]# vim /etc/named.conf
zone "10.168.192.in-addr.arpa" IN {
        type master;
        file "named.192.168.10";
        allow-transfer { 192.168.30.212; };
};
zone "20.168.192.in-addr.arpa" IN {
        type master;
        file "named.192.168.20";
        allow-transfer { 192.168.30.212; };
};
zone "30.168.192.in-addr.arpa" IN {
        type master;
        file "named.192.168.30";
        allow-transfer { 192.168.30.212; };
};

[root@dns1 ~]# named-checkconf

确认上述设置并不会出问题才行!接下来继续做 zone file 设置!

  • zone file 反解设置

反解几乎只有 PTR 设计而已,你要注意的是,主机名称务必使用 FQDN,不要用正解的自动加上 zone 的模式! 这是因为反解的 zone 是一组 IP 的 domain,不是主机名称!

[root@dns1 ~]# cd /var/named
[root@dns1 named]# vim named.192.168.10
; 这个 zone file 的 zone (@) 缺省为 10.168.192.in-addr.arpa.
$TTL 600
@       IN SOA  dns1.server.vbird. adm.mail.server.vbird. ( 2023112801 3H 15M 1D 600 )
; 这个 zone 的 DNS server 指定,反解要用 PTR
@       IN NS   dns1.server.vbird.
@       IN NS   dns2.server.vbird.
211     IN PTR  dns1.server.vbird.
212     IN PTR  dns2.server.vbird.
; 其他用户端的设置!主要是分给内网用的,共计 100 台!
1       IN PTR  ap001.ap.vbird.
2       IN PTR  ap002.ap.vbird.
...

[root@dns1 named]# named-checkzone 10.168.192.in-addr.arpa named.192.168.10
zone 10.168.192.in-addr.arpa/IN: loaded serial 2023112801
OK

相同的设置数据,请输入到 named.192.168.{20,30} 文件内。事实上,NS 的设置除了 192.168.30.0/24 那一段是正确的之外, 其余两段的 NS 设置是错误的!不过毕竟我们是放置在内网,也直接指定这两部 DNS 作为代查找服务器,所以都可以找到正确的反解数据, 这样就可以了!

  • 重新启动 named-chroot 与测试

接下来就是重新启动服务,并且尝试测试我们的设置值!

[root@dns1 named]# systemctl restart named-chroot
[root@dns1 named]# dig +short -t soa 10.168.192.in-addr.arpa
dns1.server.vbird. adm.mail.server.vbird. 2023112801 10800 900 86400 600

[root@dns1 named]# dig +short -t ns 10.168.192.in-addr.arpa
dns2.server.vbird.
dns1.server.vbird.

[root@dns1 named]# dig +short -x 192.168.10.1
ap001.ap.vbird.
[root@dns1 named]# dig +short -x 192.168.20.10
client010.lan.vbird.
[root@dns1 named]# dig +short -x 192.168.30.5
server05.server.vbird.

至少得要完成上述的动作才行喔!这样,我们的正反解也就在 dns1 完成了!接下来,准备处理 slave DNS 吧!

  • 将反解 zone file 同步到 slave DNS 上

跟正解的 slave 设置相同,我们不用处理 zone file,只要让 slave 向 master 要数据就好!

# 记得,底下的动作是在 dns2 上面完成的!
# 1. 处理主设置档,并且测试设置是否正确
[root@dns2 ~]# vim /etc/named.conf
zone "10.168.192.in-addr.arpa" IN {
        type slave;
        file "slaves/named.192.168.10";
        masters { 192.168.30.211; };
};
zone "20.168.192.in-addr.arpa" IN {
        type slave;
        file "slaves/named.192.168.20";
        masters { 192.168.30.211; };
};
zone "30.168.192.in-addr.arpa" IN {
        type slave;
        file "slaves/named.192.168.30";
        masters { 192.168.30.211; };
};

[root@dns2 ~]# named-checkconf

# 2. 重新启动服务并且测试
[root@dns2 ~]# systemctl restart named-chroot
[root@dns2 ~]# tail -n 100 /var/log/messages| grep '168.192.in-addr.arpa'
# 这时应该要看到类似底下的信息:
transfer of '10.168.192.in-addr.arpa/IN' from 192.168.30.211#53: Transfer completed:

[root@dns2 ~]# dig +short -x 192.168.10.1
ap001.ap.vbird.

就这样,连反解也完成啦!

8.4、局域网路内 client 的 DNS 设置 (/etc/resolv.conf, search)

现在,根据图 8.2.1 的说明,我们已经建置好内部三个 IP 地址网段的正反解设计,master/slave 的 DNS 架构也进行完毕, 那么该对于内部的系统修改 DNS 设置了!我们先以 master 骨干系统来处理好了。现在,假设我们需要让 master 骨干服务器使用这两部 dns 系统, 同时,为了简化主机名称的应用,我们希望使用类似 /etc/hosts 里面的简易设置,例如当输入 client001 时, DNS 系统就应该要知道去找到 client001.lan.vbird 这个主机名称,并取得 192.168.20.1 的 IP 地址才好!也就是说:

  • 需要使用 dns1, dns2 这两部 DNS 服务器
  • 需要依序查找 server.vbird, lan.vbird, ap.vbird 这三个 domain 的 IP 地址正解。
  • 使用 nmcli 做设置

如果仔细看 nmcli 的输出,会发现有一个 ipv4.dns-search 的设置,该设置就是搜索 domain name 的意思! 所以,要达成上述的功能,我们可以在 master 骨干系统上面这样做:

[root@master ~]# nmcli connection modify enp1s0 ipv4.dns 192.168.30.211,192.168.30.212 \
> ipv4.dns-search server.vbird,lan.vbird,ap.vbird
[root@master ~]# nmcli connection up enp1s0
[root@master ~]# cat /etc/resolv.conf
search server.vbird lan.vbird ap.vbird vbird
nameserver 192.168.30.211
nameserver 192.168.30.212

[root@master ~]# dig www.vbird.tw
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;www.vbird.tw.                  IN      A
;; ANSWER SECTION:
www.vbird.tw.           600     IN      CNAME   linux.vbird.tw.
linux.vbird.tw.         600     IN      A       140.116.44.180
;; SERVER: 192.168.30.211#53(192.168.30.211)
# 我们只截取部份会观察到的信息!可以看到 master 向 dns1 要求数据了!
  • 删除 /etc/hosts 不必要的数据

因为之前为了方便我们记忆,我们有将一些私有 IP 对应主机名称放置到这边来~这时就该整理整理:

[root@master ~]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.201.249    cloud.vbird       cloud
192.168.201.245    master.vbird      master

实际上,就是将我们本章设置的 192.168.{10,20,30}.0/24 的 IP 网段对应取消而已!其他还是要保留喔! 然后就可以开始来测试看看了:

[root@master ~]# ping -c 2 dns1
PING dns1.server.vbird (192.168.30.211) 56(84) bytes of data.
64 bytes from dns1.server.vbird (192.168.30.211): icmp_seq=1 ttl=64 time=0.171 ms
64 bytes from dns1.server.vbird (192.168.30.211): icmp_seq=2 ttl=64 time=0.343 ms

[root@master ~]# ping -c 2 client001
PING client001.lan.vbird (192.168.20.1) 56(84) bytes of data.
64 bytes from client001.lan.vbird (192.168.20.1): icmp_seq=1 ttl=64 time=0.207 ms
64 bytes from client001.lan.vbird (192.168.20.1): icmp_seq=2 ttl=64 time=0.423 ms

[root@master ~]# ping -c 2 ap010
PING ap010.ap.vbird (192.168.10.10) 56(84) bytes of data.
From master.vbird (192.168.10.254) icmp_seq=1 Destination Host Unreachable
From master.vbird (192.168.10.254) icmp_seq=2 Destination Host Unreachable

你可以发现,使用短主机名称 (hostname) 时,我们的系统还是可以找到对应的 FQDN 主机名称,这是因为 /etc/resolv.conf 里头 search 的设置!这真是个不错用的功能啊!只是,dig 不能这样用~dig 还是得要输入完整的 FQDN 才行! 但是 ping, curl 等等的网络指令,都可以这样应用喔!未来就可以『 ssh dns1 』之类的方式去连接了!

请修改 dns1, dns2 及 client001 的网络设置,让我们整个网域的数据都用相同的 DNS 与 dns search 设置!

8.5、高端设置方式

上面的 DNS 设置是比较常见的使用方式,简单的正反解设计完毕后,就可以实际应用了。不过,某些特殊的情境下, 可能还是会遇到一些需要了解的部份!包括子网域授权、互联网/局域网路查找方式的差异、动态 DNS 的设计等等, 这些都可以来玩一玩!

8.5.1、子网域授权方式

所有的孩子都有个父母亲是吧?名字大部份都是承袭家长对吧?那么,如果你的下属单位跟你说,他们需要自己独立的 DNS 设置! 这样方便他们自己管理~这时,你就得要『将你的网域的部份查找权,交给下属单位的 DNS 系统管理』才行! 举例来说,成大 (ncku.edu.tw) 的资工系 (csie) 跟成大说,我需要自己架设 DNS 服务,以方便自己处理未来各研究室的主机名称管理! 这样要修改比较方便~此时,成大可能就会将 csie.ncku.edu.tw 的查找权交给资工系自己馆,从此就不再帮资工系设置主机名称的正解设置了! 资工系也能更快速的在自己系上就完成相关的设置,而不用提交到校的层级去处理!真是 win win 啊!

# 1. 查找成大是否具有自己的 domain name server
[root@dns1 ~]# dig +short -t ns ncku.edu.tw
apple.ncku.edu.tw.
name.ncku.edu.tw.
# 结果是有的!所以 ncku.edu.tw 就是一个完整的 domain

# 2. 查找成大资工系是否具有自己的 domain name server
[root@dns1 ~]# dig +short -t ns csie.ncku.edu.tw
dns.csie.ncku.edu.tw.
# 结果也是有的!所以 csie.ncku.edu.tw 也是个完整的 domain

# 3. 查找成大环工系 (ev) 是否具有自己的 domain name server
[root@dns1 ~]# dig +short -t ns ev.ncku.edu.tw
# 空的!没任何信息!所以 ev.ncku.edu.tw 还是由成大计中校级单位所控制

如同图 8.1.1 当中提到的,子网域的 zone 必须要包含父网域才行!所以上面的例子当中,成大资工系自己的 domain 必须要完整的包含成大整体的 domain, 所以就 csie.ncku.edu.tw 这样的存在!而 dns.csie.ncku.edu.tw. 这部主机未来只能规划 *.csie.ncku.edu.tw 的主机名称喔!

  • 在总公司设置子网域授权 (NS) 的设置方式

举例来说,管理部门需要管理自己的 manage.server.vbird 的网域,未来所有的 *.manage.server.vbird 他们都要自己管理! 不让总公司的 IT 部门管理了!子单位要求的子网域为 manage.server.vbird,且提供该 DNS 服务的 IP 地址为 192.168.30.210 时, 你有主机名称与 IP 地址了~那么总公司的 IT 部门,只要修改 zone file 即可!修改的方式如下:

# 1. 在 master DNS 上面,修改 named.server.vbird 文件,除了 NS 与 A,还要记得改序号!
[root@dns1 ~]# vim /var/named/named.server.vbird
@       IN SOA  dns1.server.vbird. adm.mail.server.vbird. ( 2023112902 3H 15M 1D 600 )
# 上面 SOA 的序号请加大!使用日期格式处理较佳!
manage  IN NS dns.manage.server.vbird.
dns.manage.server.vbird. IN A  192.168.30.210
# 主机名称的部份,写 FQDN 好像问题比较小!其他的部份则保留不变

# 2. 分别检查两个 domain 的设置情况
[root@dns1 ~]# named-checkzone server.vbird /var/named/named.server.vbird
zone server.vbird/IN: manage.server.vbird/NS 'dns.manage.server.vbird' (out of zone) 
                      has no addresses records (A or AAAA)
zone server.vbird/IN: loaded serial 2023112902
OK
# 因为子网域授权的关系,这里会显示 out of zone,不过不用理会没关系

[root@dns1 ~]# named-checkzone manage.server.vbird /var/named/named.server.vbird
zone manage.server.vbird/IN: loaded serial 2023112902
OK
# 这里就显示 domain name 设置是正常的了!

# 3. 重新启动 named-chroot 吧!
[root@dns1 ~]# tail -n 100 /var/log/messages | grep 'server.vbird'
Nov 29 10:14:03 dns1 named[11857]: zone server.vbird/IN: loaded serial 2023112902
Nov 29 10:14:03 dns1 named[11857]: zone server.vbird/IN: sending notifies (serial 2023112902)
Nov 29 10:14:04 dns1 named[11857]: client @0x7fc9300073d8 192.168.30.212#59263 (server.vbird): 
                                   transfer of 'server.vbird/IN': AXFR-style IXFR started (serial 2023112902)
Nov 29 10:14:04 dns1 named[11857]: client @0x7fc9300073d8 192.168.30.212#59263 (server.vbird): 
                                   transfer of 'server.vbird/IN': AXFR-style IXFR ended: 1 messages, 
                                   19 records, 510 bytes, 0.001 secs (510000 bytes/sec) (serial 2023112902)
# 在 master 重新启动 named-chroot 时,会主动调用 slave 来更新喔!

这样就一切顺利处理完毕了!接下来,所有 *manage.server.vbird 的网域,就由 192.168.30.210 那部系统 (dns.manage.server.vbird) 自己去管理了!其他的设置,就请自己参考我们上面所谈到的流程了,只是子网域只有一部 DNS,所以也就不用设置 slave DNS 啰! 另外,在目前,当 dns.manage.server.vbird 尚未架设,或架设错误时,我们能不能找到设置在总公司的 dns.manage.server.vbird 的 A 设置呢?来测试看看:

[root@dns1 ~]# dig dns.manage.server.vbird
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 13409
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 870e35ffa8d0f3430100000065669fae55ab6c36c8a323e1 (good)
;; QUESTION SECTION:
;dns.manage.server.vbird.       IN      A

;; Query time: 1 msec
;; SERVER: 192.168.30.211#53(192.168.30.211)

你会发现没有 ANSWER 的结果!因为 DNS 的 NS 设置项目,会将子网域完整授权出去,所以当你找不到 dns.manage.server.vbird 这部主机的数据 (因为该主机根本没有建置啊!),就会显示错误!也就是说,未来任何的设计错误,都跟总公司无关了!哈哈哈! 从这里也是要跟大家说,如果你的 DNS 设置错误,那么所有的正确设置就无法被查找到,那你的 server name 反而会产生相当大的问题! 因此,到底是要自干 DNS 服务器?还是请外头 DNS 代管公司帮忙你处理?这个就有赖各位读者们的思考了!总之, 目前练功一下总是不错的!

8.5.2、以 nftables 负载平衡进行两部 DNS 的轮询

现在,假设你的 DNS 服务准备要提供给 internet 作为查找,主要是作为 query 的查找而不是 recursion 喔! 那么就得要开放防火墙的转递才行!然后,我们希望从外部来的 IP 地址找到的是 master 骨干的对外 public IP 地址, 而内部来的 IP 地址找到的则是我们内部的 private IP 地址~该如何进行这部 DNS 向外放行的功能?

  • nftables 的负载平衡功能

既然我们的 DNS 服务器是摆在 master 骨干系统内部,那么如果要对外提供服务的话,就势必要放行 port 53 的 DNAT 功能才行! 但是,我们有架设两部 DNS 服务器耶!要提供那一部?主要是提供 master DNS 嘛?那么 slave 未来几乎都不会被用到喔! 能不能两部主机都提供?但是我们只有一个对外 IP 地址喔!这时,就得要使用 nftables 的负载平衡 (load balance) 功能了! 这个功能还挺有趣的!我们可以使用底下的图标来了解一下:

图 8.5.2、通过 nftables 的 load balance 功能做负载平衡
图 8.5.2、通过 nftables 的 load balance 功能做负载平衡

如上图所示,我们有两个 DNS 服务器在 master 骨干内部,当网络来的封包要使用我们的 DNS 服务器时,1 号封包使用 dns1, 2 号封包使用 dns2,3 号封包回去使用 dns1,以此类推!也就是,针对封包以 2 作为循环,在 2 个系统间做切换! nftables 的指令运行挺容易的,如下所示:

[root@master ~]# nft 'add rule inet mynat mydnat iifname enp1s0 udp dport 53 \
> dnat ip to numgen inc mod 2 map { 0: 192.168.30.211, 1: 192.168.30.212 }'

重点在 numgen 那一段!原本的指令应该是『dnat ip to 192.168.30.211』类似这样的处理,现在因为有 2 部, 所以就用 numgen inc mod 2 map,然后分别指定 1 去 192.168.30.211 而 2 去 192.168.30.212 这样! 如此一来,就可以将 port 53 连接封包进行负载平衡了!相当的轻松愉快!实际加入系统设置,还得要依据第 7 章的内容, 修改 /root/nftables.sh 才行:

# 1. 在 master 骨干系统底下,修改 nftables 的脚本文件!
[root@master ~]# vim /root/nftables.sh
# part 2.4: 创建 DNAT 功能
nft add rule inet mynat mydnat iifname ${wanif} udp dport 53 dnat ip to \
    numgen inc mod 2 map { 0: 192.168.30.211, 1: 192.168.30.212 }
nft add rule inet mynat mydnat iifname ${wanif} tcp dport 53 dnat ip to \
    numgen inc mod 2 map { 0: 192.168.30.211, 1: 192.168.30.212 }
nft add rule inet mynat mydnat iifname ${wanif} tcp dport 80 dnat ip to 192.168.30.1

[root@master ~]# sh /root/nftables.sh

# 2. 观察 mydnat 链的内容
[root@master ~]# nft list chain inet mynat mydnat
table inet mynat {
   chain mydnat {
      type nat hook prerouting priority dstnat; policy accept;
      iifname "enp1s0" tcp dport 2121 redirect to :22
      iifname "enp1s0" udp dport 53 dnat ip to numgen inc mod 2 map { 0 : 192.168.30.211, 1 : 192.168.30.212 }
      iifname "enp1s0" tcp dport 53 dnat ip to numgen inc mod 2 map { 0 : 192.168.30.211, 1 : 192.168.30.212 }
      iifname "enp1s0" tcp dport 80 dnat ip to 192.168.30.1
   }
}

如果想要测试,是不是真的会根据封包来进行负载平衡,可以这样做:

  • 在 dns1, dns2 上面运行『 tcpdump -i enp1s0 -nn port 53 』
  • 在外网运行『 dig ap001.ap.vbird @192.168.201.245 』数次
  • 看看 dns1, dns2 那一部有回应 port 53

很快乐的就可以发现 nftables 帮我们搞定了负载平衡!

  • 直接放行 DNS 查找的问题

我们的 server.vbird, ap.vbird, lan.vbird 这三个正解 zone,以及各个反解的 zone 都是只提供给企业内部使用的 DNS 主机名称查找环境,并不想提供给外网~而且也没有必要提供给外网知道!另外,外网来的查找,应该一致认为是不能递归查找的! 只有内部可以递归查找!应该是这样才对啊!但是,我们可以从上一个练习当中知道,外部的 DNS 查找,可以查到 ap001.ap.vbird 这个主机名称的 IP 地址呢!这样是相当不合理的!那,能不能将 zone 做个分类,有只提供给内网查找的, 以及仅提供给外网查找的数据呢?这就需要用到 view 的功能了!

8.5.3、使用 view 依来源分别提供 DNS 查找服务

如前一章节所述,我们可能得要将外部来的 DNS 查找结果与内部网段来的查找结果,分开来设计! 简单的说,我们应该要将 root zone file (.) 以及我们自己定的 6 个 zone 放置到内网查找, 而外网基本上目前只能查到 root zone file 而已才对!这时,就得要 view 的帮忙了!

  • 使用 view 将内外 zone 切开

我们预计使用 view 切开两个界面,分别是:

  • 一个称为 intranet 给来源 IP 地址为内部的查找,可递归查找
  • 一个称为 internet 给来源 IP 地址为其他非内部的来源查找,不可递归查找

内部的 IP 地址来源直接放行递归 (反正就是内部来源啊),外部的来源则不许递归查找。 目前外部仅提供 root zone file 的 zone 而已,内部则需要全部的 zone 都放上去!所以,整体的主设置在 dns1 应该修改成这样:

# 注意,所有动作应该都在 master DNS 亦即 dns1 服务器上面实做
[root@dns1 ~]# vim /etc/named.conf
acl mynet  { 192.168.10.0/24; 192.168.20.0/24; 192.168.30.0/24; 127.0.0.0/8; };
acl outnet { ! mynet; any; };
options {
        listen-on port 53 { any; };
        listen-on-v6 port 53 { any; };
        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";
        secroots-file   "/var/named/data/named.secroots";
        recursing-file  "/var/named/data/named.recursing";
        allow-query     { any; };
        allow-transfer  { none; };
        recursion no;

        dnssec-validation yes;
        managed-keys-directory "/var/named/dynamic";
        geoip-directory "/usr/share/GeoIP";
        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";
        include "/etc/crypto-policies/back-ends/bind.config";
};
logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};
view intranet {
        match-clients { mynet; };
        recursion yes;
        forwarders { 120.114.150.1; 120.114.100.1; };
        zone "." IN {
                type hint;
                file "named.ca";
        };
        zone "lan.vbird" IN {
                type master;
                file "named.lan.vbird";
                allow-transfer { 192.168.30.212; };
        };
        zone "ap.vbird" IN {
                type master;
                file "named.ap.vbird";
                allow-transfer { 192.168.30.212; };
        };
        zone "server.vbird" IN {
                type master;
                file "named.server.vbird";
                allow-transfer { 192.168.30.212; };
        };
        zone "10.168.192.in-addr.arpa" IN {
                type master;
                file "named.192.168.10";
                allow-transfer { 192.168.30.212; };
        };
        zone "20.168.192.in-addr.arpa" IN {
                type master;
                file "named.192.168.20";
                allow-transfer { 192.168.30.212; };
        };
        zone "30.168.192.in-addr.arpa" IN {
                type master;
                file "named.192.168.30";
                allow-transfer { 192.168.30.212; };
        };
        include "/etc/named.rfc1912.zones";
};
view internet {
        match-clients { outnet; };
        recursion no;
        zone "." IN {
                type hint;
                file "named.ca";
        };
        include "/etc/named.rfc1912.zones";
};
include "/etc/named.root.key";

[root@dns1 ~]# named-checkconf
[root@dns1 ~]# systemctl restart named-chroot

[root@dns1 ~]# grep zone.*vbird.*intranet.*load /var/log/messages
Nov 29 14:54:15 dns1 named[12269]: zone lan.vbird/IN/intranet: loaded serial 2023112801
Nov 29 14:54:15 dns1 named[12269]: zone ap.vbird/IN/intranet: loaded serial 2023112801
Nov 29 14:54:15 dns1 named[12269]: zone server.vbird/IN/intranet: loaded serial 2023112902

[root@dns1 ~]# grep zone.*168.192.*intranet.*load /var/log/messages
Nov 29 14:54:15 dns1 named[12269]: zone 20.168.192.in-addr.arpa/IN/intranet: loaded serial 2023112801
Nov 29 14:54:15 dns1 named[12269]: zone 10.168.192.in-addr.arpa/IN/intranet: loaded serial 2023112801
Nov 29 14:54:15 dns1 named[12269]: zone 30.168.192.in-addr.arpa/IN/intranet: loaded serial 2023112801

看起来上头我们设计过的 3 组正反解设置,都只出现在 intranet 是没问题的!我们分别在内网与外网来测试看看:

# 1. 在内网,我们以 master 骨干系统来测试:
[root@master ~]# dig client005.lan.vbird
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;client005.lan.vbird.           IN      A
;; ANSWER SECTION:
client005.lan.vbird.    600     IN      A       192.168.20.5

# 2. 在外网,我们以 cloud 系统来测试(一定要测试两次以上):
[root@cloud ~]# dig client005.lan.vbird @192.168.201.245
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 26655
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

这样果然可以让 DNS 提供不同的来源查找!只是,在外网的查找测试部份,经常会一个成功一个失败!很有趣喔! 这是因为我们使用了 nftables 的负载平衡的缘故!因此查找一下子是正确的 master DNS,一下子是全部提供的 slave DNS 啊!

  • 处理 slave DNS 的同步
所以,DNS 同步很重要!现在,请自行将 slave DNS 设置修改成如上所示的 view 分类功能!注意喔! 因为 slave 使用的 zone file 都是同步来的 (type slave),所以你不能直接拷贝 /etc/named.conf!需要自行慢慢修改才行!

# 底下所有动作都应该要在 slave DNs (dns2) 上面进行
[root@dns2 ~]# vim /etc/named.conf
acl mynet { 192.168.10.0/24; 192.168.20.0/24; 192.168.30.0/24; 127.0.0.0/8; };
acl outnet { ! mynet; any; };
options {
	....
        allow-transfer  { none; };
        recursion no;
	....
};
...
view intranet {
        match-clients { mynet; };
        recursion yes;
        forwarders { 120.114.150.1; 120.114.100.1; };
        ....
};
view internet {
        match-clients { outnet; };
        recursion no;
        ....
};

[root@dns2 ~]# named-checkconf
[root@dns2 ~]# systemctl restart named-chroot
[root@dns2 ~]# grep zone.*vbird.*intranet.*load /var/log/messages
Nov 29 15:25:12 dns2 named[6977]: zone ap.vbird/IN/intranet: loaded serial 2023112801
Nov 29 15:25:12 dns2 named[6977]: zone lan.vbird/IN/intranet: loaded serial 2023112801
Nov 29 15:25:12 dns2 named[6977]: zone server.vbird/IN/intranet: loaded serial 2023112902

连 slave DNS 都设置好的话,外网应该就什么也查不到了!

  • 外网/内网针对同一个 zone 的不同设计

上面的 view 是将内部/外部的 zone 都切开,不让内部专用的 zone 被查找到!那假设你在 DMZ 架设一部 WWW 服务器, 名称为 www.wan.vbird 好了,假设 'wan.vbird' 这个 domain 是实际可用的~那么外部与内部要连接到这部网页服务器, 应该要如同底下这样的连接方式才合理:

图 8.5.3、不同来源连接时,同一个 hostname 应该给不同的 IP 地址
图 8.5.3、不同来源连接时,同一个 hostname 应该给不同的 IP 地址

也就是说,相同的 wan.vbird 的 zone,应该要分别存在于 intranet 与 internet 的 view 界面中,且分别有不同的 zone file 设置! 如此一来,才有办法提供同一个主机名称,依据不同的来源,给予不一样的 IP 地址!现在,假设实际存在 wan.vbird 这个 zone, 而且这个 zone 里面暂时仅有 www.wan.vbird 这个主机名称的正解对应而已~我们可以简单的这样设计:

# 1. 针对 master DNS (dns1) 的设置
# 1.1 针对主设置档的 zone 与 zone file 文件名设置:
[root@dns1 ~]# vim /etc/named.conf
...
view intranet {
        zone "wan.vbird" IN {
                type master;
                file "named.wan.vbird.lan";
                allow-transfer { 192.168.30.212; };
        };
        ...
};
view internet {
        zone "wan.vbird" IN {
                type master;
                file "named.wan.vbird.wan";
                allow-transfer { 192.168.30.212; };
        };
};
# 特别注意两者的 zone file 文件名并不相同喔!

[root@dns1 ~]# named-checkconf

# 1.2 开始设置内网的 zone file 内容
[root@dns1 ~]# cd /var/named
[root@dns1 named]# vim named.wan.vbird.lan
$TTL 600
@       IN SOA  dns1.wan.vbird. adm.mail.wan.vbird. ( 2023112901 3H 15M 1D 600 )
@       IN NS   dns1.wan.vbird.
@       IN NS   dns2.wan.vbird.
dns1    IN A    192.168.30.211
dns2    IN A    192.168.30.212
www     IN A    192.168.30.220

[root@dns1 named]# chmod 640 named.wan.vbird.lan
[root@dns1 named]# chown root.named named.wan.vbird.lan
[root@dns1 named]# named-checkzone wan.vbird named.wan.vbird.lan
zone wan.vbird/IN: loaded serial 2023112901
OK

# 1.3 开始设置外网的 zone file 内容
[root@dns1 named]# vim named.wan.vbird.wan
$TTL 600
@       IN SOA  dns1.wan.vbird. adm.mail.wan.vbird. ( 2023112901 3H 15M 1D 600 )
@       IN NS   dns1.wan.vbird.
dns1    IN A    192.168.201.245
www     IN A    192.168.201.245
# 首先,DNS server 只剩一台,因为只有对外 IP,而且 www 应该也要设置为外部 IP

[root@dns1 named]# chmod 640 named.wan.vbird.wan
[root@dns1 named]# chown root:named named.wan.vbird.wan
[root@dns1 named]# named-checkzone wan.vbird named.wan.vbird.wan
zone wan.vbird/IN: loaded serial 2023112901
OK

# 1.4 重新启动并观察
[root@dns1 named]# systemctl restart named-chroot
[root@dns1 named]# tail -n 100 /var/log/messages | grep zone.*wan.*load
Nov 29 22:54:42 dns1 named[12791]: zone wan.vbird/IN/intranet: loaded serial 2023112901
Nov 29 22:54:42 dns1 named[12791]: zone wan.vbird/IN/internet: loaded serial 2023112901
# 2. 针对 slave DNS (dns2) 的设置
# 2.1 主设置档的修改
[root@dns2 ~]# cd /var/named
[root@dns2 named]# vim /etc/named.conf
view intranet {
        ...
        zone "wan.vbird" IN {
                type slave;
                file "slaves/named.wan.vbird.lan";
                masters { 192.168.30.211; };
        };
        ...
};
view internet {
        ...
        zone "wan.vbird" IN {
                type master;
                file "named.wan.vbird.wan";
        };
        ...
};
# 因为 dns1, dns2 都在内网,查找不到外网~所以外网文件要用 type master 的类型

[root@dns2 named]# named-checkconf
[root@dns2 named]# scp dns1:/var/named/named.wan.vbird.wan .
[root@dns2 named]# chown root:named named.wan.vbird.wan

# 2.2 重新启动 named-chroot 与测试
[root@dns2 named]# systemctl restart named-chroot
[root@dns2 named]# journalctl -u named-chroot | grep zone.*wan.vbird | cut -d ']' -f 2-
: zone wan.vbird/IN/intranet: loaded serial 2023112901
: zone wan.vbird/IN/intranet: sending notifies (serial 2023112901)
: zone wan.vbird/IN/internet: loaded serial 2023112901

[root@dns2 named]# dig +short www.wan.vbird
192.168.30.220

这样就搞定了!你在外网使用如下的方式查找,应该可以查找到正确的对外 IP 地址才对:

# 在外网,例如母机器 cloud 系统上,可以这样追踪
[root@cloud ~]# dig +short www.wan.vbird @192.168.201.245
192.168.201.245

8.5.4、使用 DDNS

什么是 DDNS 呢?这是 Dynamic DNS, 动态 DNS 的缩写,就是可以让用户去修改自己的 A 或其他纪录的数据! 也就是说,用户可以在自己的电脑上面,通过某些指令,去更新 DNS server 上面关于自己主机名称的设置值! 所以才叫做动态 DNS 设置的意思。那什么时候会用到 DDNS 呢?基本上有两种情境经常会用到:

  • 在内网 DHCP 自动取得网络参数的情况下,当用户取得 IP 地址之后,DHCP server 才主动向 DNS 要求动态加设主机名称与 IP 的对应
  • 在外网 Internet 的环境中,某些主机的 public IP 地址是会改变的,例如中华电线的光纤到府服务,会有 8 个随机取得的 IP 地址可用! 如果要用这种 IP 地址来架设公开的网站,就可以使用 DDNS 的协助,让用户的主机在 IP 地址改变后,可以立即前往 DNS server 更新主机名称对应的最新对应!
  • 内网更新功能: 使用 allow-update

内网的设置相对简单,我们可以针对某一台或者是某几台电脑的 IP 地址进行 DDNS 更新权的放行,被规范到可更新的用户电脑, 只要使用类似 nsupdate 这种 bind 提供的软件,就可以更新了!我们现在假设内网的 192.168.30.213 以及 192.168.30.254 这两部主机, 可以对我们的 master DNS (dns1) 进行主动更新~主要更新的 zone 只能是 lan.vbird 那个 zone 而已。那就可以这样做看看:

# 1. 底下的所有设置值,请在 dns1 上面实做!
# 1.1 在主设置档内,增加 allow-update 的功能(只对内网放行)
[root@dns1 ~]# vim /etc/named.conf
        zone "lan.vbird" IN {
                type master;
                file "named.lan.vbird";
                allow-transfer { 192.168.30.212; };
                allow-update { 192.168.30.213; 192.168.30.254; };
        };

# 1.2 让 SELinux 放行更新功能
[root@dns1 ~]# setsebool -P named_write_master_zones on

# 1.3 让相关的 zone file 变成可让 named 用户更新的模样
[root@dns1 ~]# chmod 664 /var/named/named.lan.vbird
[root@dns1 ~]# chown named.named /var/named/named.lan.vbird
[root@dns1 ~]# ll /var/named/named.lan.vbird
-rw-rw-r--. 1 named named 3355 Nov 28 22:14 /var/named/named.lan.vbird

# 1.4 重新启动 named-chroot
[root@dns1 ~]# systemctl restart named-chroot
# 这个 /var/named/named.lan.vbird 文件内容以后会被自动修订喔!所以请记得要备份

在 DNS 的设置阶段,这样就完成了!要注意喔! allow-update 是个很重大权限放行,所以,请仅针对内网的某些重要 server 放行! 不要全部放行喔!主要放行的服务器,通常就是 dhcp 自动分配网络参数的服务器主机而已。我们这边还没有设置好 dhcp, 所以才额外放行 master 骨干啦!现在,我们到 master 骨干系统上面,通过一般 DNS 设置方式,如下所示的功能,来处理一个 A 的纪录:

  • 语法: domain ttl [RR] [RR data]
  • 范例: check.lan.vbird 600 A 192.168.30.112
# 2. 底下的所有动作,请在 master 骨干系统上面运作,直接使用 nsupdat 更新!
[root@master ~]# nsupdate
> server 192.168.30.211
> update delete check.lan.vbird A
> update add check.lan.vbird 600 A 192.168.30.112
> send
> [ctrl]+d
[root@master ~]# dig +short check.lan.vbird
192.168.30.112
[root@master ~]# dig +short -t soa lan.vbird
dns1.lan.vbird. adm.mail.server.vbird. 2023112803 10800 900 86400 600

两个重点,一个是 check.lanv.vbird (结尾不用加上小数点) 这个 hostname 可以有对应的 IP 地址了! 另外则是原本 lan.vbird 这个 zone 的 SOA 序号会主动加一!为什么呢?因为这样 slave DNS (dns2) 就可以主动更新到最新的数据库 zone file 了! 现在,再让我们回去看看 dns1 的 zone file 数据:

# 3. 底下回到 dns1 去看看 zone file 的变化:
[root@dns1 ~]# ll /var/named/named.lan*
-rw-r--r--. 1 named named 3161 Nov 30 14:31 /var/named/named.lan.vbird
-rw-r--r--. 1 named named  985 Nov 30 11:12 /var/named/named.lan.vbird.jnl
# 会多出一个扩展名为 .jnl 的文件喔!那就是更改数据档!

[root@dns1 ~]# grep check /var/named/named.lan.vbird
check                   A       192.168.30.112
# 果然被主动加入这个纪录值了!

# 4. 尝试管理 .jnl 的日志档,将他删除吧!
[root@dns1 ~]# rndc sync -clean
# 这个动作会将 *.jnl 的数据倒回去原始的 zone file,之后再删除 .jnl 档

这样,内网的比较重要的服务器,就可以主动来 DNS server 上面修改它们需要的主机名称对应纪录数据了! 不用管理员跑来手动修改!同时,每次改了新的纪录,序号还会主动 +1,可以让 slave DNS 真的来更新数据库! 啊!这样管理真是轻松愉快的多!

  • 外网更新功能: 使用 update-policy 限缩权限

allow-update 虽然很好用,但是...功能实在太强了!所以,如果我们使用于 internet 的话,可能会造成许多的资安困扰。 另外,刚刚提到,DDNS 也可以开放给 IP 地址变化后,想要更新 IP 地址对应到主机名称的用户上,如此一来, allow-update 也无法写入固定的 IP 地址啊!所以,就得要使用密钥系统了。

所谓的密钥系统,其实就是通过 bind 本身提供的 ddns-confgen 指令的功能,产生一把加密过后的密码锁, 这个密码锁其实就是一串运算过后的字符串,DNS server 与想要更新 DNS 纪录的用户端,通过这把密码锁达成沟通之后, 就可以进行 DNS 纪录的更新了!这样一来,就安全的多。至少,没有密钥的连接要来进行 DNS 纪录的修改时,我们的 DNS server 就不会理会!

让我们开始来针对外网做个 update 的范例吧!我们主要针对 wan.vbird 的 zone,然后仅放行 web2.wan.vbird 这个主机名称对 A 纪录的更新! 实验的方式流程如下:

# 1. 在 dns1 上面实做的流程!
# 1.1 使用 ddns-confgen 运算产生一把密码锁 (只是密码字符串)
[root@dns1 ~]# ddns-confgen -a [算法] -k [密钥名] -s [主机名]
# 选项与参数:
-a :后面接的算法是加密的机制,主要算法有 hmac-sha1 hmac-sha256 hmac-sha512. 
     缺省使用 hmac-sha256 算法
-k :密钥的名称为何,基本上只跟 named.conf 的设置有关而已!任何名称均可
-s :后面接的就是我们想要变更的主机名称!

[root@dns1 ~]# cd /var/named
[root@dns1 named]# ddns-confgen -a hmac-sha256 -k web2 -s web2.wan.vbird.
# To activate this key, place the following in named.conf, and
# in a separate keyfile on the system or systems from which nsupdate
# will be run:
key "web2" {
        algorithm hmac-sha256;
        secret "2CgYCqw7L3eWsXR3bS3Xtp+QtoRB1u7jighQk4W0xI0=";
};

# Then, in the "zone" statement for the zone containing the
# name "web2.wan.vbird.", place an "update-policy" statement
# like this one, adjusted as needed for your preferred permissions:
update-policy {
          grant web2 name web2.wan.vbird. ANY;
};

# After the keyfile has been placed, the following command will
# execute nsupdate using this key:
nsupdate -k <keyfile>
# 其实缺省就会有详细的说明!上面的特殊字体部份,就是密码锁了!

# 1.2 修改主设置档,并且确认设置没问题
[root@dns1 named]# vim /etc/named.conf
view internet {
        ...
        key "web2" {
                algorithm hmac-sha256;
                secret "2CgYCqw7L3eWsXR3bS3Xtp+QtoRB1u7jighQk4W0xI0=";
        };
        zone "wan.vbird" IN {
                type master;
                file "named.wan.vbird.wan";
                allow-transfer { 192.168.30.212; };
                update-policy {
                        grant web2 name web2.wan.vbird. A;
                        // 让 web2 这把密码锁只能修改 web2.wan.vbird. 的 A 纪录
                };
        };
        ...
};

[root@dns1 named]# named-checkconf

# 1.3 修改 zone file 的权限之后,重新启动 named-chroot
[root@dns1 named]# chown named.named named.wan.vbird.wan
[root@dns1 named]# chmod 664 named.wan.vbird.wan
[root@dns1 named]# ll named.wan.vbird.wan
-rw-rw-r--. 1 named named 265 Nov 29 22:53 named.wan.vbird.wan

[root@dns1 named]# systemctl restart named-chroot

基本上,如果你内网只有一部 DNS 的话,那上面的动作就完成了!只是我们有两部...同时还无法对外网进行 zone file 同步... 所以,上面同样的步骤,得要在 dns2 上面全部实做一次才行!

# 2. 底下全部的动作,都需要在 dns2 上面完成!
[root@dns2 ~]# vim /etc/named.conf
# 修改方式跟 dns1 一模一样!请往前参考!不需要重新运行 ddns-confgen 喔!

[root@dns2 ~]# named-checkconf
[root@dns2 ~]# cd /var/named
[root@dns2 named]# chown named.named named.wan.vbird.wan
[root@dns2 named]# chmod 664 named.wan.vbird.wan
[root@dns2 named]# systemctl restart named-chroot

这样就做好了!

  • 在外网用户端使用 nsupdate 进行更新 (要两次!)

因为我们有密钥在 DNS server 上,且只能在外网更新~所以,我们先跑到 cloud 母系统上面,测试一下:

# 底下的动作,我们都是仿真外网~缺省在 cloud 母机器上面实做!
# 1. 使用相同的密码锁创建一把密码档,文件内容就是密码锁
[root@cloud ]# vim web2.key
key "web2" {
        algorithm hmac-sha256;
        secret "2CgYCqw7L3eWsXR3bS3Xtp+QtoRB1u7jighQk4W0xI0=";
};

# 2. 尝试使用这把钥匙重新修改 web2.wan.vbird 的 A 成为 192.168.201.243
[root@cloud ]# nsupdate -k web2.key
> server 192.168.201.245
> update delete web2.wan.vbird
> update add web2.wan.vbird 300 A 192.168.201.244
> send
> [ctrl]+c

[root@cloud ]# nsupdate -k web2.key
# 因为我们有两部轮询的 DNS server,所以要做两次才行!否则只会更新到一部

[root@cloud ]# dig +short web2.wan.vbird @192.168.201.245
192.168.201.244

这样就完成了 DDNS 的设计啰!轻松愉快!

8.6、参考数据

修改历史:
  • 2023/11/30:修改完 DNS 章节!加入全部都是 master/slave 架构的设计,而且还增加 nftables 的负载平衡!我觉得很有趣!
2023/11/30以来统计人数
计数器
其他链接
环境工程模式篇
鸟园讨论区
鸟哥旧站

今日 人数统计
昨日 人数统计
本月 人数统计
上月 人数统计