1. 背景

1.1 DNS

DNS ( Domain Name Service) 作为一个非常让人耳熟能详的概念,可以把复杂难记的IP地址转化成为一个容易被记住域名供人们去调用,这样人们只需要记住每一个网站的域名而不需要记住非常复杂的IP地址。此外,由于网络组网通讯的局限性,不能将所有的网站的IP地址一一规划用,因此 DNS 也提供了网络地址转换的相关功能。

这种技术在这里不做深入探讨,只需要对DNS的过程有一个大概的了解即可,未来会有一篇专门探讨 DNS 协议及其安全问题的安全博客,在这篇安全博客将会详细描述安全实验的步骤。

DNS ZONE:

DNS Zone,DNS域,被用来划分DNS主域。传统的DNS域类似一个树状的结构,被分成不同的区域,这些区域可区分一个DNS服务器中命名空间中不同的区域。

DNS区域是构成DNS命名空间的一部分,由特定组织或管理员加以管理,其可以对权威性域名服务器等DNS组件更加精细的控制。 域名空间是一个分层数,其中DNS的根域位于顶部,DNS区域始于该树中的一个域,并且可以扩展到下边的子域。

常见的资源记录类型

A :Address地址, IPv4

AAAA:Address地址 IPv6

NS :Name Server域名服务器

SOA:Start of Authority 起始授权机构

MX:Mail Exchanger 邮件交换

CNAME:Canonical Name规范名

PTR:Pointer 指针,即反向DNS系统,用于查询IP地址时给出相关的域名,即查询IP地址的PTR记录给出该IP指向的域名,在 Zone 文件中被设置;

TXT:Text,网络名称系统的记录,可讲文字信息提供给网络意外的来源,其中有一个非常重要的功能就是当外部查询需要显示BIND的相关版本号时,可以指定 TXT查询,这个配置是默认的;谷歌会使用 TXT 记录来验证网站的拥有权以及确保电子邮件的安全;

SRV:Service 记录,域名中用于指定服务器并提供服务的位置:主机好、端口号;一般在 Zone File 中被定义;

CNAME

CNAME-records ( Canonical name for an alias )是域名的别名。一个服务器的域名地址 nyc3.example.com 这个主机域名可能会提供不同的服务,比如说域名 nyc3.example.com 指向的主机即要去提供 web服务,也要提供 ftp 服务,那么这个时候就需要一个别名域名来指向原来的域名,这个时候就可以使用一个 A 记录来管理多个域名,为DNS后期修改配置提供方便。举个例子:

我想要搭建一个博客网站后台为博客网页提供web服务,我想要节省我服务器搭建的成本开销,只想租用一个服务器并配置相关域名解析,我的博客网站现在提供的服务有评论,分享,登陆授权,注册,这个时候我需要同时在这个服务器上开通这些服务,一开始你的博客网站默默无闻,访问量以及下载量并不是那么大,这个时候你的服务器负载并不是那么严重;当你的访问量暴增的时候,这个时候就需要考虑到你的服务器的流量转发问题了~原始服务器的流量暴增已经让你的服务器性能急剧下降,你需要将原来的提供服务的服务器的相关模块提供一个内容分发模块 (CDN),这个CDN提供商要求你的域名做一个Pointer来指向他们为你提供的 DNS地址,这个时候你的 CName 就可以指向他们提供的域名,做到对DNS流量的分发,从而实现网站的流量负载均衡作用。

NS (Name Server)

域名服务器,NS,用于确定哪些服务器(注意不是单个服务器)为一个局域网传递DNS信息以及确定域名由哪个服务器进行解析。

一般NS配置在 BIND9 中的 db 文件中进行配置,在 SOA 配置之后。NS记录 和 SOA记录是任何一个DNS区域都不能或缺的两条记录。

在 BIND 的配置中,可以在 Zone 文件中指定多个 Name Server,一般来说 Name Server 需要搭配 SOA 进行配置;

SOA( Start of Authority)

SOA 又被称作 起始授权机构记录, 被标记成在众多NS记录中哪一台是主服务器。

SOA 记录表示此域名的权威解析服务器地址,当要查询的域名在所有递归解析服务器没有域名的解析缓存时,会回源到请求此域名的SOA 记录,也叫做权威解析记录。

SOA 作为所有区域文件的强制性记录,他必须是 ZONE 文件中的第一个记录。

SRV (Service)

SRV 记录是从 RFC2052 中对 SRV资源进行了定义。SRV 被用来记录服务器提供什么样的服务。

1.2 FQDN

FQDN(Fully Qualified Domain Name) 完全合格域名/全程域名,即域名可以通过DNS进行解析,其公式 FQDN = HostName + Domain。

这门技术解决了一个多个主机的问题,一个网站或者服务器集群一般都是有多个主机一起协作的,比如说包括正向代理服务器、反向代理服务器、Web服务器、Email服务器、OA服务器、FTP服务器等等,这个时候就涉及是不是需不需要为每一个主机申请一个域名。 有了这个技术之后每一个主机都可以自己申请一个 Hostname 来区别于其他的主机,这个时候就只需要一个域名就可以做到管理所有的主机。

比如我申请了一个域名: doheras.com

现在我有两个服务器需要用到这个域名,一个 FTP服务器,一个Web服务器,这两个服务器都需要用到 doheras.com这个域名,根据公式,我们知道可以采用 hostname 的方式来访问不同的主机:

Web 服务器: web.doheras.com

FTP 服务器: ftp.doheras.com

因此, FQDN 服务可以简化在服务和应用中的配置流程,提高配置文件的可维护性。

在配置DNS的过程中,因为服务端的工作在UDP协议端口53上,DNS需要FQDN提供正向解析 (FQDN —> IP)以及反向解析 (IP —> FQDN) 的服务。

1.3 BIND

BIND(Berkeley Internet Name Domain)作为一款目前市面是最主流的开源DNS软件,占据了市面上DNS服务器软件的九成,目前由 互联网系统协会 (Internet Systems Consortium) 负责开发和维护。目前,最新的稳定版BIND已经更新到了 BIND 9 版本。

目前市面上的主流操作系统( Linux/Windows/Windows Server) 都可以承载BIND的DNS服务,从官网上来看,目前支持的主流的Linux操作系统及其服务器种类有: Ubuntu、Debian、Fedora/CentOS。其中对于Fedora的版本支持已经涵盖了最新版本:Fedora 33。在Linux平台上可以做到对 BIND 源码的编译和特殊功能定制的操作,对于该软件在实际运行过程中的安全性的探讨研究。其基本功能支持在服务器或者是本机上搭建定制的DNS服务并做到域名解析功能。对于将该软件部署到Linux平台最具有优势的方面是定制化的DNS服务,因为源码对于每一个开发人员和网络管理人员都是透明的,因此可以做到对该软件相关功能的定制以及二次开发。

另外,对于使用较为广泛的Windows操作系统,BIND也给出了可以运行的解决方案,但是其定制化的功能因为平台的原因收到了限制和Windows 10 操作系统的相关问题,因此我认为不推荐 BIND 在 Windows上的实验,但是本文也给出了在 Windows 10 操作系统下的安装办法,对于 Windows Server ,对于相关IT从业人员的操作系统管理经验以及熟练度要求太高,因此本文没有给出相关配置步骤。

1.4 本文中搭建模拟DNS服务网络虚拟设备架构示意图 - 基于 Debian 9.11 操作系统

本文中涉及到的搭建 BIND 服务的 Linux操作系统 及其 实验、操作步骤,之后的每个不同章节的内容给出了说明,请在不同章节前自行查找相关的配置信息作为参考。

下边给出的图片列举了Big Sur下搭建模拟DNS虚拟机网络的拓扑图,使用的:

ISC BIND9 - 图1

  • 172.16.2.11 作为主要的 (Master) DNS解析服务器,主要为客户端提供域名解析服务,所有客户端的首要访问的DNS解析服务器是NS1
  • 172.16.2.12 作为一个灾备的服务器NS2,被当作一个灾备DNS服务器使用,在主机无法提供域名解析服务的时候被启用,其配置流程与NS2基本上一样,唯一的区别是配置需要分清与NS1的主次关系;
  • 172.16.2.5 / 172.16.2.6 / 172.16.2.7 做为模拟请求客户端的虚拟机,其用来模拟和重现配置DNS解析客户端的配置流程;
  • 172.16.2.0 作为虚拟机连接本机的 NAT 网络的网关地址,用于与 Mac 主机进行通信;

Caution

  • 以上所有网络设备对应的设备都是基于 Mac Big Sur 下 VMware Fusion 的虚拟机;
  • 自行搭建复现过程IP地址不需要与上图保持一致,请自行规定虚拟设备的IP;

1.5 操作系统的选择

在 ISC 官网上的 BIND 9 支持的 Linux 版本包括: Debian 、 CentOS 、 Fedora 、 Ubuntu。从我查找的网上的资料来说,大多数的选择都是 Debian 作为服务器端的选择。对于非Linux操作系统,Windows / Windows Server 也支持搭建 BIND 9 DNS 服务。

根据互联网上的比较著名的技术论坛网友的相关评论出发,本着稳定、安全、实用并容易管理的原则,对上述的主流操作系统的特性以及使用中的情况进行分析:

对于 Debian 系列的操作系统对于开源社区的更新和支持力度比较大,版本更新较快,新发行的版本可能会存在不稳定的问题和补丁容易带来系统的安全性、完整性的问题,但其优点是ISC提供预编译的 BIND 9 包在 Debian 操作系统上可以轻松做到运行,Debian Server 版本更新补丁的速度都比较快;

Debian,其操作系统经历从 Debian 9 到 Debian 11 的版本更新,其特性没有发生很大的变化,而且社区的更新和讨论非常活跃;

CentOS 作为一款专业的服务器端,拥有稳定、安全的特性,其发行版本一般较为稳定并经过许多专业人员在服务器端的大量测试以及红帽自身的改进,ISC 也为其编译了BIND 9 的安装包,但其缺点在不容易上手和难以操作,并且在实际的管理配置中比较繁琐,没有在 Debian 下的 BIND 配置管理方便;

另外对于 CentOS 7 和 CentOS 8 的社区支持和版本更新会在 2021年和2029年终止,并且以后 CentOS Stream 不再作为 RHEL的“免费”的商业版本而成为介于 Fedora 和 RHEL 之间,其定位与 Fedora 较为相近;在尝试配置 CentOS 8 的过程中出现很多不应该出现的问题,比如说从 yum 安装BIND9时对应目录下的文件无法找到,sudo 的用户添加过于复杂的问题让人非常恼火。

Ubuntu 作为经典的桌面版Linux的操作系统,非常稳定和容易上手,但是作为服务器端的操作系统的选择较少,有可能带来的问题难以被估计。

总结 - Debian 和 CentOS 的对比

  • Debian 的优点:

    • 强大的社区支持以及活跃度,从 CentOS 被商业化收购后,Debian 收到中、小企业的关注度较多;
    • 系统管理、配置较为简单,对系统有很好的掌控程度,配置网络、防火墙等功能轻松简单;
  • Debian 的缺点:

    • apt 安装工具对于依赖的处理没有 yumnpm 对于包及其依赖的管理那么优秀,在离线安装包及其依赖时,apt 的安装问题会让你比较头疼;
    • 对于系统日志的管理没有 CentOS 那么优秀和详尽;
  • CentOS 的优点:

    • 基于最强大的商业Linux操作系统 - RedHat, 网上的资料非常非常的多,目前使用的个人群体也非常非常多,容易找到问题对应的资料;
    • 强大的操作系统管理以及设计,很多关于Linux的讲解书籍都是以CentOS为例子来进行讲解的;
    • yum / npm 的包管理比 apt 要更优秀一点,更容易在;
    • 受众面较大,选择的企业很多~
  • CentOS 的缺点:

    • 未来的前景不被开源社区看好,好多公司已经开始更改技术栈;
    • BIND 的配置管理混乱,没有在 Debian 下对于BIND服务配置文件流畅度那么好;
    • 相关的系统配置、网络配置的配置比Debian较为复杂;

综上,我选择 Debian9 作为 测试版 DNS Server 的承载操作系统,选择的依据依赖于其稳定的更新频率和良好的开源社区,备用的选择为 RHEL 和 CentOS。

1.5 BIND9 与 F5-GTM

写这篇博客的目的是做一个替代F5核心GTM的BIND服务器,构建这个服务器目标是为了在局域网内核心F5的GTM设备出现故障时候,配置好的 BIND服务器 可以立刻取代F5 GTM设备充当整个区域网的域名解析服务器为访问终端或服务器提供域名解析服务。

在这里我必须指出在构建这个BIND域名解析服务器时,遇到的一个非常大的困惑。

从上面的模拟DNS虚拟机网络的拓扑图中,NameServer(NS)是与主机在同一个网段下的,但实际上,在生产链路中的F5 GTM设备并不是和其他的服务器连接在同一个网段下的,这就会带来一个问题,就是当终端想要访问外网段的DNS解析服务器时,NameServer 会不会不能为其提供服务?

问题的重现从这篇详细阐述F5-GTM运作原理的官方文档开始:https://techdocs.f5.com/kb/en-us/products/big-ip_gtm/manuals/product/gtm-concepts-11-5-0/4.html

这里边详细介绍了F5 GTM的运作原理,以及出现了下边的图片,这个部分引起了我的担忧,当链路的GTM失效之后,因为GTM与LTM连接的子服务器以及子终端因为不在同一个网段中而无法进行工作:

ISC BIND9 - 图2

举个例子,GTM作为整个链路的核心设备,用于为LTM设备提供域名解析服务,在实际的生产网络中中GTM在网络中拓扑并不是与LTM存在于同一个网段的,画一个图来表述这个问题:

ISC BIND9 - 图3

上图中,作为一个简单的网络拓扑的再现,四个网络中LTM都与中间的GTM不在同一个网段中,因为我在之前画的模拟拓扑所有的设备不管是DNS服务器还是host终端都在同一个网段,因此设备与设备之间的访问以及设备与DNS服务器之间的服务建立并不需要跨越网段,因此访问以及提供服务是没有任何问题的。

但是如果不在同一个网段呢? 当然这个部分省略了很多关键的网络设备,这里不一一阐述。

其实这个问题我是想的有一点偏的,或者来说比较多余,因为:

  • 其实作为谷歌还是阿里提供的免费的权威域名服务器都是在不同的网段下进行运作的,那么不同网段不应该成为DNS服务器无法提供服务的一个阻碍条件;
  • 其次,我的困惑是在整个体系中 GTM 与 LTM 是搭配进行使用的,所以我错误地认为 GTM是为LTM服务的,我需要解决的事是GTM与LTM之间的配置问题,为LTM提供服务,这个想法是完全错误的;在整个网络体系中,GTM 为所有的访问域名客户端的客户端提供解析服务,并不影响 LTM的工作,两者的工作状态是独立的;
  • 最后,如果说F5设备的特色是负载均衡,那么这个负载均衡体现在GTM设备之间的负载均衡或者来说是“双活”,而不是与LTM的负载问题。

如果想要了解 GTM 与 BIND 之间的关系,请详细了解 BIG-IP-GTM 中内嵌的模块 - ZONERUNNER


2.BIND 9 配置文件讲解

这里以 Debian9 作为配置讲解的环境。

BIND9 的配置文件在安装之后配置文件名字: named.config, 在 Linux下被易名为 named.conf 文件存储的位置为:/etc/bind,其中文件named.conf引用了三个文件: named.conf.optionsnamed.conf.localnamed.conf.default-zone

在 Debian9 中查找和重启当前 BIND9 服务的命令是: sudo systemctl status bind9sudo systemctl restart bind9

2.1 CONF 文件

在完成 BIND9 的变异和安装之后,BIND9 已经创建了一个默认的配置文件 named.conf.local 和 文件 named.conf.options 用于配置 BIND9 的基础服务,这两个文件作为配置DNS的核心文件,修改这两个文件需要管理员权限,默认的权限为: root:named,不要随便更改这两个文件的运行权限,DNS 服务会出现问题。

配置文件的注释符号为 //

acl

一般来说,ACL模块用来承担控制主机可以访问域名解析服务器的角色,其设置不会让控制文件的配置非常冗余和庞大。采用这个配置可以有效防范DOS以及Spoofing攻击。一般来说定义这部分的内容来规定IP是否能够被接入以及Blocklist来阻止某些特定的IP地址介入到域名解析服务器中。

ACL匹配客户端是否能够接入到域名服务器基于三个基本的特征:

  • 客户端的IPv4或者IPv6地址
  • 用于签署请求的 TSIG 和 SIG(0) 密钥
  • 在DNS客户端子网选项中编码的前缀地址

匹配 acl 定义以及使用规则如下: string 是用来命名IP地址集的一个变量名,可以随意地被命名;

acl <string> { <address_match_element>; ... };

举一个在 named.conf.options 文件中被定义的例子:

logging

logging 部分的配置为DNS解析服务器提供了日志记录的功能,DNS服务器上的所有日志记录被存储到了指定的文件中。其通用的配置文件为:

从上边的通用配置格式可以看出来,logging 模块分为两个部分,categorychannel,channel的作用是指定输出的方式、日志格式的选项和事件的严重性,每一个channel 可以指定一个 category 来指定记录的事件类型。其中 category 用来区分不同的事件产生的类别或者场景,比如:客户端请求-client request、配置文件解析处理-Configuration file parsing and processing

如果在 named.conf.options 文件中没有指定 logging 模块系统会给出一个默认的配置

channel 的配置规则:

  • 所有的日志输出都需要 channel 来指定输出格式,BIND9 对于创建 channel 的数量没有限制。

  • 每一个 channel 都需要为该通道的日志信息指定一个 destination clause - 目的句柄,目的句柄在 channel 阶段被配置,这个目的句柄用来区分: 1)输出到具体的文件的名字 - file;2)输出到具体的系统日志工具中(syslog/syslogd)- syslog;3)输出到终端显示- 标准错误流(standard error stream);4)或者该错误消息直接被丢弃 - null
    其次,channel 的配置可以规定每一个错误日志消息的响应级别,默认的响应级别是info ,channel 可以规定接受错误消息的级别;此外,channel 还可以控制输出错误日志消息的格式,可以包含:响应时间戳、category名字、严重等级等。

channel 的配置参数:

  • buffered: 用来规定是否刷新错误日志的文件,其参数值为<boolean>,在 BIND9 中 <boolean> 值的参数值为 yes / no,如果设置成为 yes 那么日志消息流(一般每一个错误日志消息都是一个 Log Entry)就不会刷新,而是被保存在缓冲区中了,不会刷新到文件中。

  • file: 类似于Linux的通道概念,file 将日志输出流通过通道直接输出给文件,从上边的通用配置可以看出来可以为 file 指定文本文件的大小 - size ;指定 log 文件的版本号 - version;指定用于命名备份版本的格式 - suffix
    size 用来限制log文件的大小,如果log文件的大小设置超过了设定的阈值,那么系统会自动停止输出内容到文件中;
    versions: 用于指定新创建的 log文件数存储到本地的上限值,默认的参数值为unlimited,当指定的文件的大小超过设定的size值得时候,如果没有指定 versions,那么系统就不会继续写进log;如果制定了versions,那么就会继续写入;
    suffix :设定用来命名log文件的方式;好像没啥用,我添加这个参数没有什么反应…;

  • syslog:将通道定向到系统的日志文件流中; 常用的支持日志文件服务为:dameonsysloglocal6local7

  • severity:用来承担定义日志严重级别的定义角色,相当于 syslog - priorities。比如说定义了日志的严重级别为 Debug,那么会输出日志事件 Debug 以上的错误到文件中。一般常用的严重等级: debug[level]noticewarningdynamic - 与当前服务器的日志保持一致;一般的 DNS服务器的日志等级调成 info即可;

  • stderr:将通道指向服务器的标准错误流。这是为了在服务器作为前台进程运行时使用;

  • print-timeyes / no / local / iso8601 / iso8061-utc 可以设定不同的输出到日志文件的时间格式;

  • print-category:打印日志消息配置category 的信息到你设定的日志文件中;

  • print-severity: 打印日志的严重等级

category词组配置规则:category <config_string> { <channel_name_string>; ... };

  • client: 客户端请求;
  • cname:由于是CNAME而不是a /AAAA记录 的域名服务器;
  • config: 配置文件解析和处理过程;
  • database:与名称服务器内部用于存储区域和缓存数据的数据库相关的消息;
  • general: 没有被归类的 category 类别的其他种类的日志文件信息;
  • lame-servers: 远程服务器中的错误配置,BIND 9在解析期间试图查询这些服务器时发现;
  • network: 网络操作;
  • notify: 通知协议;
  • queries:记录所有查询 DNS服务器的 query;
  • query-errors: 关于导致某些失败的查询的信息;
  • xfer-in:区域传输服务器正在接收;
  • xfer-out:区域传输服务器正在发送的信息;
  • zoneload:加载区域和创建自动空区域;

怎么去配置这个服务?

配置的 logging 服务会创建指定的日志文件,该日志文件从服务挂起的时候被创建,用于记录DNS服务中的相关的配置信息以及交换信息。在 Debian9 的默认存储目录为 /var/cache/bind/*。你也可以为其指定你想要存储的位置,我个人喜欢将 BIND 日志和系统日志保存在一起,即保存路径为:/var/log/bind。这个路径不是在你安装 BIND 时候就已经创建了,需要你自己创建对应的文件目录;

如果你想要配置成一个自己的目录,首先你需要创建一个自定义的目录,比如说我指定了我想要存放日志的文件的目录: /var/log/bind,如果不为这个文件使用chown命令指定权限的话会出现 isc_stdio_open '/var/log/example.log' failed 的报错:

  • 首先你必须手动创建自己的文件到指定目录下;
  • 解决方法是: sudo chown bind:root /var/log/bind/*

现在我们已经基本上了解了 logging 的工作原理,其工作机制简单地来说就是,首先你需要创建一个 channel 来规定输出日志流的格式还以及日志文件名、文件版本,每一个 channel 可以被多个 category 调用使用,每一个 category 相当于一个 BIND9 内嵌的服务模块,服务模块去调用日志配置模最后输出格式化日志。

在这里我之前并没有给出对应的配置示例,现在给出示例:

options

options 的参数设置会影响整个 BIND9 DNS环境的配置,具体各部分常用到的配置参数如下:

  • listen-on: 用于配置监听的端口以及IPv4地址,默认的监听端口为:53;
  • listen-on-v6:用于监听 IPv6 地址以及端口;
  • directory: 用于指定读取DNS数据文件的文件夹,默认的文件夹的路径为:/var/cache/bind
  • dump-file:选项用来设置域名缓存数据库文件的位置,可以自己定义。默认的存储文件为:named_dump.db
  • statistics-file:选项用来设置状态统计文件的位置,可以自己定义。;
  • memstatistics-file :选项用来设置服务器输出的内存使用统计信息。默认保存在 /var/named/data 目录下,文件名为 named.memstats
  • allow-query:选项用来设置允许DNS查询的客户端地址,默认值为localhost, 可以设置为某个网段、任意地址、具体的某台主机三种情况。例如,要修改为任意地址,就在括号内的加入 any,也可以引用之前创建的 acl 内的所有地址;
  • recursion:用于设置递归查询,一般客户机和服务器之间属于递归查询,即当客户机向DNS服务器发出查询请求后,若DNS服务器本身不能解析,则会向另外的DNS服务器发出查询请求,得到结果后转交给客户机。此选项有yesno两个值。这个选项用于设置 Failover 非常有用;
  • dnssec-enable: 选项用来设置是否启用DNSSEC支持,DNSSEC可以用来验证DNS数据的有效性,该选项有yesno两个值,默认值为yes
  • dnssec-validation:选项用来设置是否启用DNSSEC确认,默认值为yes,可以选择 auto
  • bindkeys-file : 用来设置内置信任的密钥文件,其默认值为 /etc/named/iscdlv.key
  • managed-keys-directory: 选项用于指定目录中的文件存储位置,跟踪管理 DNSSEC 密钥, 这部分的内容在后边会有介绍;
  • forwarders:DNS转发器。用于设定该DNS解析服务器无法进行当前域名解析的情况下,进行转发解析的DNS地址,其中 8.8.8.88.8.4.4 是谷歌的免费DNS服务器的网络地址;233.5.5.5233.6.6.6 是阿里云的免费DNS地址。当设置了 forwarder 的转发器之后,所有的非本域的和在缓存中无法查找到的域名查询都转发都设置的DNS转发器,由DNS转发器 完成转发操作。因此这台转发器的缓存中就记录了丰富的域名信息。因此如果遇到非本域的查询,转发器的缓存就可以做到查询,从而减少了向外部的查询流量。
  • forward: 选择默认的IP地址即可;
  • rrset-order
    在 BIND 9 提供的负载均衡策略建立在一个名称(域名 - Name)使用多个资源记录 ( Records ) 的情况下,其实现的轮询机制并不是传统的负载均衡服务器实现的轮询机制 - 即追踪和记录每一次应答的资源顺序;
    BIND 9 实现了一个类似 List 的数据结构,将所有的资源记录填入到 一个顺序表中,这个填入的次序随机,或者根据设定的参数随机;
    格式:[class class_name] [type type_name] [name “domain_name”] order ordering
    如果参数没有被赋值,那么默认的赋值为: class: ANY type: ANY Name: *
    参数:

    • fixed : 根据 zone 文件定义资源记录的顺序按照顺序逐个进行解析;
    • random: 根据 zone 文件资源记录随机返回解析记录;
    • cyclic: 创建一个循环,循环输出资源记录;
    • none: 完全随机的资源返回形式;

controls

controls语句声明了系统管理员用于管理名称服务器远程操作的控制通道。rndc使用这些控制通道向名称服务器发送命令,并从名称服务器检索非dns结果。

2.2 Zone 的引导配置文件 - named.conf.local

该文件定义了 BIND9 中的 ZONE(区域)文件在named.conf.local文件中的定义,用于定义存储解析的域名的数据库文件,即域名与IP地址的映射关系以及DNS发送的解析域名数据包的相关参数设置,其定义的格式如下:

当然你也可以定义你的反向解析域名通过以下的格式进行定义:

常用的参数配置如下:

  • file - 和 options 的参数的含义是一样的,用于指出域名与IP地址解析的数据库配置文件;
  • allow-transfer: 这个地方的配置是用来给出 Failover 或者是 递归查询DNS服务器的IP地址,如果之前在 options 里配置的allow-transfer 如果设置成了参数 yes, 那么需要在这里指出递归查询服务器的IP地址;
  • type: 用于指定当前DNS解析服务器的位置,是主服务器 - master 还是从服务器 - slaver?

2.3 Zone File - 保存 RR (Record Resource) 信息的文件

我们在配置自己的 Zone File 的时候需要明晰以下几点:

  • 第一个是这个配置用来做什么?
    DNS Record Types 分为很多种:地址解析 ( Address Records) 、别名记录(Alias Records)、邮件交换记录(Email Exchange Records)、域名服务器记录(Name Server Records);
    确定你的需求,再编写你的Zone File;

  • 第二个就是你真的理解所有编写配置的含义的吗?

我们创建一个新的文件被保存在 /etc/bind/zones/db.domain.com (Debian 环境中)

在 zone file 中,注释的符号是:;

几个比较特殊的符号

@ ( at - sign ) 是代表当前的区域,即 每一个 域名就是一个区域 - region,一般在;

$ORIGIN [REGION NAME] 设定了当前作用的区域,作用区域是代表当前的解析域名区域;

我们可以简单在这里举个例子,在你刚才创建的文件中输入下边的配置:

上边的配置中:

  • @ 代表了当前的区域 domain.com.
  • domain.com. 就是当前的区域

Zone File - TTL

TTL 规定了Resource Record 的失效时间,即当前资源记录能够被缓存的时间长短,默认的单位为秒,能够设定的最大时间长度是 32 bit 的整形变量 ( 0 到 4294967295 ),单位是秒;RR都会被保存在DNS的解析服务器的cache上,有一个失效的时间,TTL就是控制这个失效时间的一个参数;

这个参数可以单独进行设定,也可以在 SOA 设定中进行配置:

  • 单独设定: $TTL [TIME]
  • 在 SOA 中进行设定: SOA - Negative Cache TTL

举一个例子:

Zone File - SOA

SOA - Start of Authority, 起始授权部分,是每一个 Zone File 必须包含的部分,也是包含域名的关键信息。

如果有多台DNS来管理同一个域名,就需要在 zone file 中规定如何规定两个域名解析服务器了 - Name Server;

即需要在定义 Zone Fie 的时候,需要特别明确 SOA 的定义,SOA 定义了域名解析服务器的对于区域 (Location) 的数据信息来源,即规定了解析区域的IP相关地址;

每一个域名区域都需要一个 SOA 记录;

定义的方式是:

配置举例:

解释一下上边的相关参数:

  • Location Name 从前边 $ORIGIN 我们已经知道是一个区域的名称,或者用 @ 进行代替;

  • PRIMARY_DNS_SERVER_NAME 用于规定解析当前域名的主服务器,这个服务器的IP地址以及详细资源需要在后边被规定;

  • EMAIL_ADDRESS_NAME 指定了管理员的 Email 地址,以上边为例: admin.domain.com. == admin@domain.com.

  • Serial - 序号,代表着当前数据库文件的新旧, 该值越大表示当前数据库的配置越新,一般来说这个值设定的值遵循 YYYYMMMMDDDD 的格式; 这个数值必须小于 4294967296;
    在这里涉及到一个 从服务器 ( Slave )的 配置问题,如果你需要 从服务器 何时从主服务器拉取最新的配置,就需要保持从服务器这个数值低于主服务器的数值;

  • Refresh - 更新的频率,设置 Slave DNS 服务器 去向 主服务器 进行配置更新的周期;

  • Retry- 失败重新尝尝试时间,如果 Slave 服务器无法对 Master 进行链接,则需要设置这个值规定多长时间进行一次重试连接;

  • Expire - 是失效时间,如果一直失败连接,那么这个配置规定了重试连接的最大时间;

  • Negative Cache TTL - 缓存时间,在整个 zone file 都没有规定 TTL 时间的情况下,那么就以 SOA 中规定的 TTL 为主;

对于各个参数的限制:

  • Refresh >= Retry × 2
  • Refresh + Retry < Expire
  • Expire >= Retry × 10
  • Expire >= 7 Days

尤其注意!

  • 在所有的配置中,ns.domain.com != ns.domain.com. ,必须注意在 zone file 中的配置文件的最后 . 必须不能省略;
    如果不写最后一个的 . 那么该域名就是一个 相对名 ,结果就是在解析的过程中,这条资源就被当成 ns.domain.com.domain.com

zone file - Name Server Records

Name Server Records 定义了在当前 DNS服务器 中的 NS 的 IP地址,在每一个 zone file 中必须指定 主/从 域名解析器的IP地址, 使用 A 记录,这个IP地址必须与你搭建的DNS服务器保持一致;

举例:

zone file - Address Records

Address Records 记录了 域名 与 IP 地址的对应关系;

zone file - Canonical Name Records

CName 将 单个昵称或者别名映射到一个可能存在在区域外的真实的区域,在一个域名下存在多个子域名,如果需要更改映射之前的子域名,那么只需要更改映射的域名地址就可以了;

3. Windows下的安装测试

3.1 BIND 9 Executable Windows Edition 下载及其安装

Windows 桌面及Server运行版本要求

BIND 9 部署到 Windows 环境需要满足以下的环境条件:

ISC 要求需要满足运行环境下 Microsoft Visual Studio 2012 及其依赖的安装。

不能运行Microsoft Windows XPMicrosoft Windows Server 2003 下。

感谢 @lovenhe 的指正,在这里我重新补充一下 Win 10 环境下 安装 Microsoft Visual Studio 2012 的步骤,你不需要安装VS2012,因为在安装BIND的时候会自动安装VS2017:

  1. 在 网站 https://msdn.itellyou.cn/ 中选择, 开发人员工具 → Visual Studio 2012 → Visual Studio Ultimate 2012 (x86) - DVD (Chinese-Simplified) 。复制下边的 ed2k 开头的字符串,用 迅雷打开,就可以下载 Visual Studio 2012 的 ISO 文件了,这个网站非常好用,推荐大家收藏下来。

ISC BIND9 - 图4

  1. 加载下载的 cn_visual_studio_ultimate_2012_x86_dvd_920954.iso,然后进行安装。

ISC BIND9 - 图5

  1. 在安装的过程中,保持默认就可以了。

ISC BIND9 - 图6

BIND 9 Windows版本

Windows版本下载的网址请单击: https://www.isc.org/download/

目前 ISC 给出了三种可以下载的版本,第一种是测试版本 9.17.9 , 第二种是稳定版本 9.16.11,我使用的是该版本作为 Windows下的测试版本,第三种版本是 9.11.27 作为一种稳定的老旧版本,将会在 2021年11月停止维护和更新支持。

ISC BIND9 - 图7

上图给出的信息是我在2021年3月份在ISC官网上进行的截图,因为在2021年5月17日开始对这个部分进行更新,因此我重新去官网上检查了一下版本,更新地好快呀…. 目前的版本已经来到了 9.16.15 了,如下图显示:

ISC BIND9 - 图8

在实际的使用中,不管是在生产环境还是自己搭建的网络环境下,并不需要去频繁更新你之前安装的 BIND 服务器版本,你可以关注 Release Notes 去决定你是否需要更新 BIND 版本。离线安装实在是太蛋疼了…

我在这里举个例子:

打开: https://downloads.isc.org/isc/bind9/9.16.15/doc/arm/html/notes.html# - ISC BIND 9 Relase Notes

ISC BIND9 - 图9

从上图,你可以获得相关版本更新信息:

  • 安全的修复… Security Fixes
  • 特性的更改… Feature Changes

如果你使用的环境是生产环境,那么我认为你更应该关注的是漏洞:

Windows DNS 服务器在实验环境下的网络拓扑结构

我安装的第一个 ISC BIND 软件就是在 Windows 环境下进行安装的,因为没有什么经验,其实旧版的(2021年5月18日以前)的配置是有问题的 XD,不知道你们有没有发现,不过从2021年5月18日之后所有的配置都将会没有问题了!

下边放上我的 Windows 虚拟机在我本机的网络结构拓扑:

ISC BIND9 - 图10

安装步骤

1.下载完成之后,需要安装的文件被保存在一个压缩文件 ( BIND9.16.15.x64.zip ),在 Windows下解压之后即可正常运行。下图为解压之后的文件目录。

ISC BIND9 - 图11

2.使用管理员权限打开 BINDInstall.exe 文件,进入到界面的安装步骤中。未使用管理员权限打开该文件可能会带来安装过程中的错误。

3.在下边的图片请选择:

  • Keep Config Files After UninstallStart BIND Service After Install 以及 Automatic Startup 选项,确保能够在设备重启之后DNS服务可以正确被运行。
  • 保留 Service Account Name 为默认值不要更改,更改成其他的字符串会发生错误。
  • 输入一个默认密码进行安装,我这里输入的是: 123

ISC BIND9 - 图12

4.正确配置之后会提示你安装 Microsoft Visual C++ 2017, 如果已经安装请单击 修复 保证安装的环境是正确的,如果系统环境中没有该运行的环境请按照提示进行安装。

ISC BIND9 - 图13

我觉得比较 low 的点是:

  • 这个 Install 按钮其实就是一个Windows批处理脚本,最后不管你安装成功还是失败都会提示安装成功,离谱…
  • 这个安装器的功能就很简单: 1)安装 C语言环境; 2)复制文件到 C:\Program File\ISC BIND 文件夹下;3) 创建一个新的用户named

5.安装成功之后会提示:

ISC BIND9 - 图14

6.将所有的工具加入到Windows环境变量中。

右键单击 “此电脑”,单击 “属性”,单击“高级”,单击“环境变量”。

找到 Path 的环境变量,双击并加入新的路径: C:\Program Files\ISC BIND 9\bin

验证:

  • 在命令行界面输入: dig

3.2 BIND 9 在 Windows环境的配置

区别于旧版的 ISC BIND 服务,旧版的软件安装在 C:\Windows\System32\dns中,新版软件安装的目录则在 C:\Program Files\ISC BIND 9,因此新版软件的环境配置相比旧版的直接在系统目录下安装更加复杂。

总体来说:

  • C:\Program Files\ISC BIND 9\bin 文件中存储了已经编译好的小工具: rndc-confgen named-checkconf 等工具,使用这些工具需要以:管理员权限 打开 命令行 来运行 命令,具体使用的方法参照下边的命令:

  • 创建了一个 C:\Program Files\ISC BIND 9\etc 文件夹,用来存储 DNS 服务器的相关配置文件;

配置步骤

1.安装结束之后,进入到安装目录 C:\Program Files\ISC BIND 9\bin 下运行 rndc-config.exe 来生成一个 rndc.key。这个 key 是 BIND 9.x版本的新功能,是有关DNS更新以及更新时加密处理的,跟我们个人用户无太大关系,不过基于兼容性,还是照做。 这个 key 生成的路径为: C:\Program Files\ISC BIND 9\etc

生成后的 key 显示如下:

ISC BIND9 - 图15

使用 rndc-confgen 命令 来生成一个 rndc.conf 的文件:

2.通过步骤1,已经生成了一个 rndc.conf 文件,这个文件是配置 DNS 服务器 的远程管理配置文件。

在本步骤中,需要生成一个 新的 named.conf 文件,该文件保存的目录在: C:\Program Files\ISC BIND 9\etc

3.从ISC网站上下载相关的named文件到本地上,网址为: https://www.internic.net/domain/named.root 去下载 name.root 文件。 在https://www.internic.net/domain/root.zone 网址中下载root.zone 文件。并将这两个文件拷贝到C:\Program Files\ISC BIND 9\etc 目录。

打开你的命令行:

下载默认的 root.zone 文件

目前当前路径的所有文件如下:

4.创建一个新的 localhost.zoneC:\Program Files\ISC BIND 9\etc 中来配置 localhost的正向解析。

5.创建一个新的 localhost.rev 文件到 C:\Program Files\ISC BIND 9\etc 中来配置 localhost 的反向解析。

6.创建一个新的 123.com.zone 文件到 C:\Program Files\ISC BIND 9\etc 中来为自己的域名来配置正向解析。

7.创建一个新的whalecloudvcenter.com.zoneC:\Program Files\ISC BIND 9\etc 中配置自己的服务器域名的正向解析服务。

目前我们在 C:\Program Files\ISC BIND 9\etc 目录下的文件有:

ISC BIND9 - 图16

9.在刚才安装的过程中,系统已经默认创建了一个新的用户 named, 这个用户用来构建 DNS 服务,下一步需要做到的是为当前的文件夹配置权限,在目录 C"\Program Files\ISC BIND 9 配置所有的权限为: 全部允许。

这步的操作需要对所有在 “组或用户名” 下的所有用户和组添加权限,需要时更改的是你笨鸡的 Users,在我这里显示是:

Users (DESKTOP-LJ09B4B8\USer

给这个用户所有的权限就可以了,截图如下:

ISC BIND9 - 图17

10.在“系统服务”中配置 ISC BIND 9 Service 的相关配置。先打开管理命令行,并输入 services.msc,回车。

ISC BIND9 - 图18

进入到 “管理服务” 页面之后,找到 ISC BIND 服务之后双击改变属性。在下图中,请确认使用账户 ./named 用户进行登录,密码在默认的时候已经被配置了,不需要进行更改。

ISC BIND9 - 图19

11.最后,完成所有文件的创建和配置更新之后,可以运行本机的DNS解析服务了,有两种启动方式:

  • 第一种:在“管理服务”右键单击 ISC BIND 服务进行启动
  • 第二种:使用命令行(管理员模式)启动当前服务

这里主要介绍第二种启动方式:

启动当前服务:

结束当前服务:

12.验证一下刚才的配置,更改你本机的 默认 DNS 配置:

把你本机的DNS服务器地址更改成: 127.0.0.1

ISC BIND9 - 图20

TroubleShooting

遇到如果现出“ Window 无法启动 ISC BIND 服务 错误1067

解决办法:

  • 检查所有的文件是否全部导入到 C:\Program Files\ISC BIND 9\etc中,运行 named-checkconf 以及 named-checkzone
  • 检查目录 C:\Program Files\ISC BIND 9 目录的权限是否改为全部授权的权限;
  • 程序意外结束导致named.pid文件没有正确删除:

    • 检查目录 C:\Program Files\ISC BIND 9\etc 并删除 named.pid文件
    • 再次启动ISC BIND服务

4. Debian Server 下的安装配置

4.1 Debian 9.11.0 下载

新版的 Debian 的 Release 版本的链接: https://www.debian.org/releases/

历史的 Debian 版本下载: http://cdimage.debian.org/cdimage/archive/

其中,目前Virtual Private Server 常用的版本为:
Debian 7:Debian 7.8
Debian 8:Debian 8.0/8.2/8.5
Debian 9:Debian 9.1/9.9/9.11

最终考虑其适配的设备的范围以及稳定性,牺牲最新的 Debian特性以及架构,选择较为稳定的版本 Debian 9.11 进行下载,其磁力链接的下载地址为: http://bttracker.debian.org:6969/stat

下载的文件为: (打开迅雷,复制下边的磁力链接)

Debian_9.11 - magnet:?xt=urn:btih:5c9634e7805c8a5049afa92f99946edaa574d449&dn=debian-9.11.0-amd64-DVD-1.iso&tr=udp://bttracker.debian.org:6969&tr=http://bttracker.debian.org:6969/announce

版本信息:

4.2 安装Debian

安装的步骤省略…或者留到以后进行更补… 配置安装实体机与虚拟机的安装选项配置保持一致即可。

4.3 安装 BIND 9 服务到 Debian Server

在 Debian9 中查找和重启当前 BIND9 服务的命令是: sudo systemctl status bind9sudo systemctl restart bind9

4.3.1 NS1 初始配置流程

1.Debian 的默认是没有安装sudo 工具的,这非常不方便,我们先安装sudo 工具,安装之前因为 Debian 9 的特性,需要修改apt 默认的源,其源文件为:/etc/apt/resources.list

2.现在安装 sudo 工具

3.使用 sudo 工具 安装 BIND 9 并启动 BIND 9 服务

4.将 BIND 9 设置成为 IPv4 模式,将下列的 OPTIONS = "-u bind" 设置成 OPTIONS = -u bind -4s, 并重启BIND服务。

5.请参照之前配置 Windows BIND 服务的流程,我们需要先配置 Debian 下的 BIND 服务 namemd.conf.options。配置这个文件需要用到管理员权限,完成之后这些配置指定只有您自己的服务器(受信任的服务器)才能查询您的DNS服务器的外部域 (Domain)。

6.更改完 named.conf.options 文件之后,需要更改 named.conf.local 文件来配置正向和反向代理,一般来说这个文件用来配置 DNS Zone。因为我们设定的主域是nyc3.example.com,所以我们需要设定一个正向区域,用来转发和映射域名 nyc3.example.com到子网 10.120.0.0/18

7.步骤6设定了DNS Zone 的正向区域,现在设定反向区域。如果您的服务器跨越多个专用子网,但位于同一数据中心,请确保为每个不同的子网指定其他区域和区域文件。 完成所有所需区域的添加后,保存并退出named.conf.local文件。现在,我们的区域已在BIND中指定,我们需要创建相应的正向和反向区域文件。

8.创建一个正向转发区域文档,转发区域文件是 BIND 用来转发DNS和查找DNS的文件,也就是说当DNS Server收到了一个DNS请求的时候,用来查找 Domain Name和对应IP之间的关系。

在前边的 步骤6 创建的正向区域文件的对应路径是 /etc/bind/zones,我们创建一个这样的文件夹。

创建完成之后,需要新建一个zone file,在刚刚新建的文件夹中。

9.进入到修改/etc/bind/zones/db.nyc3.example.com 区域文件中修改成下边给出的文件内容:

10.现在创建反向区域的文档 ,反向区域文件是我们为反向DNS查找定义DNS PTR记录的地方。我们需要创建的文件为: /etc/bind/zones/db.10.128 ,复制的源文件为: /etc/bind/db.127, 复制的命令为:

创建完成之后的内容如下:

其中 PTR 的顺序为子网IP地址的倒序: 172.16.2.11 -> 11.2.16.172

11.现在我们已经完成了所有文件的创建,现在需要检查创建的规则是否满足要求:

检查文件 named.conf.options的命令

检查 正向区域 (Forward Zone) 是否满足配置的要求

检查 反向区域 (Reverse Zone) 是否满足配置的要求

12.重启 BIND 服务 和 配置 UFW 服务在Debian 9服务器上以及允许BIND服务

  • 重启 bind9 服务来使之前的配置生效

  • 安装和配置 UFW 服务在Debian 9 服务器上

  • 允许 BIND Service 从防火墙上通过(我也搞不清楚到底是哪一个…感觉服务名是不是不需要区分大小写)

4.3.2 NS2 初始配置流程

1.配置的流程与 NS1 配置流程基本上相同,因为 NS2 作为 NS1 的备用DNS服务器,配置需要保持一样,这里附上详细的每个文件的配置内容。

named.conf.options

named.conf.local

在主DNS服务器上定义与主域对应的从域。注意,类型是slave,文件不包含路径,并且有一个主指令,应该设置为主DNS服务器的私有IP地址。如果在主DNS服务器中定义了多个反向区域,请确保将它们全部添加到此处

2.根据 NS1 配置流程安装和配置 UFW 服务,并开启 UFW 服务。

4.4 配置 Client

说明: Client_n 为以上配置的 Host_n,其IPv4地址需要与上边的保持一致。

4.4.1 Ubuntu 20.04 客户端

1.首先,使用ip address命令查询私网子网,找到与私网关联的设备。

会有一个输出:

2.在 Ubuntu 的路径 /etc/netplan 路径下找到 *-private-nameservers.yaml 文件,其文件名可能会根据不同的设备而不同,请仔细检查该路径下的文件进行更改,比如说在我的虚机里我的文件就是 01-private-nameservers.yaml

内容为:

3.完成配置之后,使用下边的命令让 NetPlan 采用新的配置,如果存在网络问题那么新的配置就会中断。如果你想要接收当前配置,那么就输入 Enter

4.现在,检查系统的DNS解析器以确定您的DNS配置是否已应用

正确的内容会显示你刚刚配置的 DNS Server 和 DNS Domain

现在可以正确的使用DNS Server作为域名解析了~

4.4.2 CentOS 8 客户端

1.编辑/etc/sysconfig/network-scripts/ifcfg-ens33文件。您可能必须用当前主机的主网络接口的名称替换ens33,因为本次模拟搭建的环境为虚拟机环境,所以必须查看网卡是否对应。

查看网络配置,从下边的文字可以看出虚机的IP地址为: 172.16.2.6/24,对应的网卡名称为: ens33

因此,修改的文件名称为 /etc/sysconfig/network-scripts/ifcfg-ens33

将上述打开的文件更改为:

2.重启NetworkManager服务

3.安装 bind-utils

4.查看 resolv.conf 确认配置是否生效

4.5 测试客户端

4.5.1 Forward Lookup Test

在客户端 (Host) 输入以下命令:

正确输出:

4.5.2 Reverse Lookup

在客户端 (Host) 输入以下命令:

正确输出:

4.6 维护 DNS 配置信息

再完成上边的任务之后,我们已经搭建了一个简单的 DNS 服务器 在虚拟机网络上,现在的任务是我们需要维护我们的 DNS记录来保证服务器的运作稳定和便于维护,这个功能可以及时、有效地反映服务器的环境以及运行情况。

4.6.1 添加一个新的Host到当前的BIND配置中

4.6.1.1 Primary Server - ns1
  • 第一步: 将新主机的私有IP地址添加到受信任的ACL中(named.conf.options)。
  • 第二步: 更改 Primary Server下的 db.nyc3.example.com 文件, 为新主机添加一条 A 记录,增加Serial的值;格式根据之前的格式来增加即可。
  • 第三步:更改 Primary Server下的 db.16.172 文件,为新主机增加一条新的 PTR 记录,增加 Serial 的值,格式根据之前的格式来调整即可。
  • 第四步:运行之前的配置过程的所有检查步骤。
  • 第五步:重新启动 BIND9 服务。

4.6.1.2 Secondary Server - ns2
  • 第一步: 将将新主机的私有IP地址添加到受信任的ACL中(named.conf.options)。
  • 第二步: 检查配置文件是否正确: sudo named-checkconf
  • 第三步: 重启 Secondary Server的 BIND9 服务

4.6.1.3 Host-Client 配置
  • 添加新的Host(客户端) 的流程就参照之前的步骤

4.6.2 DNS日志记录

从上边来看,我们可以为 DNS Server 增加一个 logging模块,添加的内容为下边:

5. DNS Server的压力测试 - queryperf 工具

对于普通的DNS服务器来说,根据进行域名解析的过程不同,被分成了两种解析模式:递归查询和迭代查询。简单来比较这两个的区别:

递归查询

递归查询由客户端向本地域名服务器发送请求,然后等待本地域名服务器返回结果。

如果客户端向一个本地域名服务器请求一个域名的查询操作但是本地域名服务器并不知道查询域名的IP地址,那么本地域名服务器就会模仿扮演成客户端向根域名服务器发送继续查询的请求而不是让主机自己再向根域名服务器发送进行下一步的查询,直到查询到结果或者查询完所有的根域名服务器;

所以 查询的结果就是 一个特定的IP地址 或者 是未找到域名的报错信息

迭代查询

如果根域名服务器收到了本地域名服务器发送的迭代查询请求报文时,要么给出所要查询的IP地址,要么返回引导的域名服务器进行查询,所以查询的动作如果不能给出最终的结果,那么就是给客户端返回一个DNS服务器列表供客户端继续查询。

从上边的概念来看,实现递归的DNS服务器性能评价更加困难,因为被测试的DNS服务器有可能与其他的根域名服务器或者是其他权威服务器进行查询交互,或者是管理以及维护之前了解到的域名数据缓存。

安装 queryperf

queryperf 是一个 BIND9 内置的一个压力测试工具用来测试已经配置好的 BIND DNS服务器处理域名解析的性能,在实际测试的情况下需要多次进行测试并最终取一个平均值作为最后的性能标准值;

在之前的例子中,我们构建的简单的DNS解析虚拟网络架构并不需要过于复杂的查询,除非你需要维护在权威域名服务器上的查询,即面向外网的

1.下载queryperf的源码到本地中并解压导出

2.安装gcc 以及 编译queryperf工具

安装一下 C++ 最重要的

进入到刚刚下载的bind源码中找到对应的 queryperf 工具源码进行编译

3.试运行 queryperf 工具

配置 queryperf

在进行测试之前,我们可能需要一个 SHELL 脚本来验证我们的配置是否是正确的,在 queryperf 中并没有自带错误检查工具,因此这个工具只是一个性能检查工具,并不能提供错误检查工具,因此我们的在遇到配置错误的时候非常难以排查出问题,因此需要一个脚本来帮助我们检查配置上的错误

以上边给出的例子我们需要写一个以下的 SHELL 脚本:

如果出现错误则需要按照错误进行更改,没有错误的话可以进行到接下来的一步,开始配置 queryperf 的相关参数配置参考下边的参数配置:

6. DNS Server的安全性配置

首先, BIND9 的 options 提供的 allow-query 参数可以对访问DNS解析服务器的客户端地址和网段进行限制,从而达到对陌生客户端和恶意IP地址的封禁。

named.conf.options 中的参数 dnssec-enablednssec-validation 等配置参数都是维护 DNS 服务器安全性的非常重要的配置参数,DNS 的设计起始于上世纪 80 年代,当时互联网规模小得多,安全性并非首要设计考虑因素。当DNS的递归解析器(DNS Resolver )向权威域名服务器发送查询请求的时候,解析器无法验证响应的真实性。解析器只需要检查响应的IP地址与解析器发送初始查询的IP地址是否相同。 但是, 这种检查机制存在一个非常严重的问题:权威域名服务器的请求包的源地址非常容易被伪造和仿冒,攻击者很容易冒充来自权威域名服务器的响应,然后伪装成解析器最初查询的权威域名服务器,因此可以很轻松将用户重定向到其他的恶意网站。

因为需要考虑到递归解析器可能被入侵的场景,域名解析器有一种缓存的机制用来加速解析流程,其原理是从权威域名服务器和根解析器时候收到的上次DNS数据存储到本地来加速下一次应答,避免查询一个或者多个权威服务器引发的服务延迟。然而,依靠缓存存在一个缺点,如果攻击者发送的假冒的DNS权威域名服务器响应被接受,那么其缓存就会被一直缓存在递归解析服务器中,因此之后所有的查询DNS Server 的主机都会接收到欺诈性DNS数据。如果用户访问银行网站,会怎么样?用户设备在其配置的递归域名服务器中查询银行网站的 IP 地址。不过,攻击者可以通过伪造IP地址向解析器注入恶意的缓存数据,届时 IP 地址并非指向目标合法网站,而是指向攻击者创建的某个网站。这个欺诈网站冒充银行网站,看上去毫无差别。用户会毫无防备地输入名称和密码,这就导致用户在不经意间向攻击者透露了自己的银行凭证,攻击者可以堂而皇之地以用户的身份登录合法银行网站进行转账或执行其他未经授权的操作。

对于解决这个问题, BIND 提供了一种名叫 DNSSEC 的安全扩展服务以及配套的密钥生成工具供网络人员使用。

DNSSEC

DNSSEC 采用基于公钥加密的数字签名技术来加强 DNS的验证强度。 DNSSEC 并非对DNS查询和响应的过程进行传输加密,而是数据所有者对 DNS 数据进行签名加密。

每一个 DNS Zone 在配置的时候 BIND 服务会为其创建一个公钥和私钥的配对的秘钥对。 DNS zone 的所有者使用该区域的私钥对区域内的DNS数据进行签名,并为这些数据生成签名。 DNS 解析器生成的 公钥 对该区域内所有的 DNS数据验证真实性。如果有效,证明DNS数据合法,则将所有的DNS数据返回给用户。如果没有通过验证,解析器会认为发生了攻击,丢弃数据并为用户返回错误。

DNSSEC 在 DNS协议中新增加的两个安全的功能:

  • 数据来源验证 - DNS 解析器通过加密的方式验证收到的数据是否确实来自其认定的数据传送区域。
  • 数据完整性保护 - DNS 解析器可以确信,自区域所有者使用私钥第一次进行数字签名,数据在传输过程中并未遭到修改。

每个zone都会发布一个公钥,递归解析器可以检索公钥以验证区域中的数据,区域的公钥也必须经过签名。

DS-records (Delegation Record)

DS-records 用来保证密钥分发的安全和DNS消息内容的分发安全;

常见的 DS-records的分发格式为:

  • 关键字标签 (Key Tags):一个简短的数值,可以帮助快速识别所引用的DNSKEY记录;
  • 算法 (Algorithm):引用 DNSKey-record 的密码学算法;
  • 摘要类型 (Digest Type):用于创建摘要值的加密哈希算法;
  • 摘要 (Digest):引用的DNSKEY记录的加密哈希值;

ZONE 文件安全配置分析

在 Debian9 下的所有的数据库文件都存储到了配置的文件夹中,其路径为:/etc/bind,每创建一个新的 ZONE 的配置文件都会在当前路径下创建一个新的db文件来记录资源地址和域名之间的映射关系,为了了解 DNSSEC在其中到底是怎么应用的,我们可以去分析这些文件的DNSSEC公钥配置来明确 DNSSEC 在其中的配置原理。

在 Debian9 DNS服务器上配置密钥 - NS

1.首先需要在 named.conf.options 文件以及引用文件中的 options 加入一下配置:

2.确定我们保存密钥的路径,一般来说保存 zone 的数据库文件的路径为: /var/cache/bind,这个地方保存着 zone 配置的数据库文件。我们在这个地方新建一个文件夹 keys,然后找到 dnssec-keygen 的配置文件夹,调用创建密钥的命令:

创建密钥的方式如下:

3.创建完密钥之后,现在该文件夹下边存在两组公钥和私钥,这两组公钥和私钥创建完成之后,已经创建在了当前的目录下 /var/cache/bind/keys 下,现在需要创建的公钥的引用信息导入到 ZONE 文件中让其生效。在这个过程中,需要明确的是新建的 ZONE 文件是之前创建的 db.nyc3.example.com ,所以需要将之前创建的ZONE文件引用新创建的两个公钥,Zone Signing KeyKey Signing Key

Debian9 默认的BIND软件的默认安装目录是:/etc/bind,新创建的 ZONE 配置文件的目录是: /etc/bind/zones,现在我们需要将刚才创建的密钥目录 /var/cached/bind/keys 复制到 /etc/bind/zones 目录下,以便随后去调用密钥来进行 ZONE 绑定。这里边有一个BIND9 设定的环境BUG,就是在 ZONE 文件引用的 keys 必须保存在和 ZONE文件相同的目录下,

4.在/etc/bind/zones 中,我们需要将ZONE 文件引用新生成的 KSK 和 ZSK, 之后进行 ZONE 绑定:

引用完成之后,现在需要使用 /usr/sbin/dnssec-signzone 命令来签名 ZONE,使刚新建的公钥在ZONE上生效。

5.使用 /usr/sbin/dnssec-signzone 来签名 ZONE,生成新的signed 文件。具体的参数配置文件可以访问 dnssec-signzone,下边列举了我在这部分用到的参数以及相关参数配置的含义。

在当前路径下:/etc/bind/zones,生成了多个新的文件

运行完上边的命令之后,会生成几个新的文件,这些文件对接下来配置DNS权威域名服务器有帮助。至于反向解析DNS的配置我们留到最后根据之前的配置流程再进行配置。

6.目前我们已经创建了新的绑定ZONE 文件,生成新的 zone 文件的名字为 db.nyc3.example.com.signed,因此先来比较一下命令 dnssec-signzone 为新的文件增加了什么。

从上边的文件对比,我们可以看出对于一条新的DNS资源记录都新增了一个公钥和加密后的域名地址,整个文件的大小横向增长,新生成的 ZONE 文件需要替代之前老的 ZONE 文件,因此需要更改原始的 named.conf.zone 配置来适配新的配置。

重启 BIND9 服务,这个时候已经配置好了安全设置。


7. BIND 9 在离线 (生产环境) 下的安装过程

详细的安装的步骤描述以及TroubleShooting:

VMware vSphere 离线虚拟机安装 BIND 9