Docker 自建 dns 服务器 bind 以及使用详解


共计 10789 个字符,预计需要花费 27 分钟才能阅读完成。

一、简介

DNS(Domn Name System)是互联网上的一个分布式系统,主要作用是把域名和 IP 地址相互映射起来。在通信过程中,DNS 服务器会通过查询域名对应的 IP 地址,从而实现数据的传输和接收。

它基于 C/S 架构,服务器端:53/udp, 53/tcp。UDP 通常用于发送较小的、简单的 DNS 请求,如查询一个域名的 IP 地址。而 TCP 通常用于发送较大的、复杂的 DNS 请求,如查询一个域名的完整 DNS 记录。

二、DNS工作原理

DNS服务器有多种类型,其中较为常见的是递归查询和迭代查询。下面简单介绍一下这两种DNS查询方式的原理:

  1. 递归查询

递归查询是指客户端向本地DNS服务器发送查询请求,本地DNS服务器会尽可能地去查询目标服务器或其他DNS服务器,以获得最终的结果并返回给客户端。相当于客户端向本地DNS服务器提出问题,本地DNS服务器会自主解决问题并返回结果。

  1. 迭代查询

与递归查询不同,迭代查询则是本地DNS服务器向根DNS服务器查询信息,并一层层向下传递查询请求,直到获得最终结果。相当于本地DNS服务器自己从更高的权威者那里查询答案,不会向其他DNS服务器打听答案。

Docker 自建 dns 服务器 bind 以及使用详解

/>

三、安装

使用如下命令即可安装:

docker run -d \
--name bind \
--restart=always \
-p 53:53/tcp \
-p 53:53/udp \
-p 10000:10000/tcp \
-v /home/docker/bind:/data \
sameersbn/bind

四、DNS配置文件详解

以下配置文件都在 /home/docker/bind/bind/etc/ 目录下,运行容器后自动生成。

1. 主配置文件

/home/docker/bind/bind/etc/ 目录下,有多个带 conf 的文件,这些就是主配置文件,其实可以只有一个 named.conf,这里按用途分为了几个,包含全局配置选项、区域设置和其他重要设置。并用 named.conf 将其包含进来。

// This is the primary configuration file for the BIND DNS server named.
//
// Please read /usr/share/doc/bind9/README.Debian.gz for information on the
// structure of BIND configuration files in Debian, *BEFORE* you customize
// this configuration file.
//
// If you are just adding zones, please do that in /etc/bind/named.conf.local

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";

使用如下命令检测配置文件是否有语法错误。

named-checkconf

2. 全局配置选项

named.conf.options 文件负责配置 bind 服务器的监听地址,允许查询、传输的 IP 地址,日志记录、转发、安全设置等。

options {
        // 指定BIND服务器使用的缓存目录的路径。
        directory "/var/cache/bind";
        // 指定DNSSEC验证的设置。常见的选项包括:auto、yes、no
        dnssec-validation auto;
        // 指定BIND服务器监听的IP地址和端口号。常见的选项包括:any、具体ip(只监听指定的IP地址)、none(不监听任何IP地址,即禁用服务),默认监听所有
        listen-on { any; };
        listen-on-v6 { any; };
        // 对非本机所负责解析区域的请求,全转发给指定的服务器,需要 forward、forwarders 配合
        // first表示先转发,如果转发服务器不能解析,则自己去互联网查找;only 表示仅通过转发器进行查询,如果转发服务器不能解析,返回未知结果
        forward first|only;
        // 列出了要用于转发的 DNS 服务器的 IP 地址
        forwarders {
                114.114.114.114; // 公共 DNS
                8.8.8.8;  // Google Public DNS
                1.1.1.1;  // Cloudflare DNS
        };
        // 指定允许查询的客户端IP地址或IP地址范围,默认允许所有客户端查询
        allow-query { any; };
        // 指定是否允许BIND服务器执行递归查询。选项包括:yes、no,默认 yes
        recursion yes;
        // 指定允许传输的服务器或IP地址。
        allow-transfer {
                192.168.0.2;
                10.0.0.0/24;
        };

};

3. 区域配置文件

named.conf.default-zones 是区域配置文件,用于指定不同的域名解析区域和相应的配置文件路径。

// 配置根服务器文件
zone "." {
        type hint;
        file "/usr/share/dns/root.hints";
};

// 配置localhost域名解析,可作为模板示例
zone "localhost" {
        type master;
        file "/etc/bind/db.local";
};

// 带有in-addr.arpa都是反向解析,即通过ip反查域名
zone "127.in-addr.arpa" {
        type master;
        file "/etc/bind/db.127";
};

zone "0.in-addr.arpa" {
        type master;
        file "/etc/bind/db.0";
};

zone "255.in-addr.arpa" {
        type master;
        file "/etc/bind/db.255";
};

// 创建test.com的域名解析区域
zone "test.com" {
        type master;
        file "/etc/bind/test.com.zone";
};
// 如果是从服务器
/*
zone "test.com" {
        type slave;
        masters { 10.0.0.1;};
        file "/etc/bind/slave/test.com.zone.slave";
};
*/

4. 本地配置文件

named.conf.local 是本地配置文件,在这里可以进行一些特定于本地环境的配置,如果需要使用 RFC 1918 私有 IP 地址范围的情况下,可以将相关的解析配置包含在这个位置,以便 BIND 服务器可以正确解析这些私有 IP 地址。

RFC 1918 中规定了三个私有 IP 地址范围,用于在内部网络中使用,而不会与公共互联网上的其他设备冲突。这些私有 IP 地址范围分别是:10.0.0.0 到 10.255.255.255(CIDR 表示为 10.0.0.0/8)、172.16.0.0 到 172.31.255.255(CIDR 表示为 172.16.0.0/12)、192.168.0.0 到 192.168.255.255(CIDR 表示为 192.168.0.0/16)

//
// Do any local configuration here
//

// Consider adding the 1918 zones here, if they are not used in your organization
//include "/etc/bind/zones.rfc1918";

zones.rfc1918 这个文件定义 RFC 1918 私有 IP 地址范围的反向解析区域,指定了对应的解析文件位置为 "/etc/bind/db.empty"。db.empty 是一个空数据文件,这样做的目的是告诉DNS服务器在解析这些私有IP地址的反向查询时返回空结果。

5. 具体数据文件

区域配置文件中配置了多个区域,每个区域对应一个自己的数据文件,以 test.com 为例。

; 配置全局的ttl,ttl即dns记录在缓存中的有效时间
$ttl 604800
; SOA记录即 Start of Authority(起始授权记录),一个区域解析库仅能有一个,并位于解析库的第一条记录,指定了该区域的权威服务器和其他参数。
test.com.       IN      SOA     ns1.test.com. mail.test.com. (
                        1 ; 序列号,数据文件更新时需要更新版本序列号
                        10M ; 刷新时间,其他DNS服务器需要重新查询的时间
                        1H ; 重试时间,其他DNS服务器无法联系到时重试时间
                        1H ; 过期时间,其他DNS无法联系到时,继续使用区域数据文件的时间
                        24H ) ; 负缓存时间,查询不到特定记录时,该不存在的记录缓存的时间

; 设置NS记录,指定权威服务器
@       IN      NS      ns1
@       IN      NS      ns2
ns1     IN      A       172.21.9.125
ns2     IN      A       172.21.9.123
; 指定其他记录
@       IN      A       172.21.9.125
www     IN      A       172.21.9.171

域名解析的的格式为:

name   [TTL]    IN      rr_type      value
  • name 为域名记录,可以省略域名如 www,也可以写全 www.test.com
  • TTL 为 dns 缓存时间,这个参数是可选的,不填默认用全局的 ttl 值
  • IN 为记录的类别(Class),通常是"IN",表示 Internet 类别
  • rr_type 为解析类型,常见的类型有 A、CNAME、MX、AAAA、TXT、NS
  • value 为记录的具体值,根据记录类型的不同而有所不同。例如,对于 A 记录,value 是一个 IPv4 地址;对于 MX 记录,value 是一个邮件交换服务器的域名。

检测数据文件是否有语法错误使用如下命令:

named-checkzone  "test.com" /etc/bind/test.com.zone

五、主DNS服务器搭建

1. 安装命令

安装命令就是上面提到的命令。

docker run -d \
--name bind \
--restart=always \
-p 53:53/tcp \
-p 53:53/udp \
-p 10000:10000/tcp \
-v /home/docker/bind:/data \
sameersbn/bind

2. 修改配置文件

修改配置文件 named.conf.options,以下配置如果有不同的需要修改,没有的需要新增。

options {
        // 指定BIND服务器使用的缓存目录的路径。
        directory "/var/cache/bind";
        dnssec-validation auto;
        listen-on { any; };
        listen-on-v6 { any; };
        allow-query { any; };
        recursion yes;
};

3. 测试

查看 dns 解析可以使用 dig 命令或者 nslookup 命令,如果没有安装可以运行如下命令。

# centos
yum install bind-utils

# ubuntu
apt install dnsutils

测试如下:

[root@localhost docker]# dig www.baidu.com @127.0.0.1

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.14 <<>> www.baidu.com @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33390
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.baidu.com.                 IN      A

;; ANSWER SECTION:
www.baidu.com.          1200    IN      CNAME   www.a.shifen.com.
www.a.shifen.com.       120     IN      A       14.119.104.189
www.a.shifen.com.       120     IN      A       14.119.104.254

;; Query time: 4525 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: 六 10月 07 20:18:34 CST 2023
;; MSG SIZE  rcvd: 104

可以看见自建的 dns 是可用的。

4. 自定义正向区域解析

正向区域解析即通过域名查询 ip。

在 named.conf.default-zones 文件中添加 test.com 的区域。

zone "test.com" {
        type master;
        file "/etc/bind/test.com.zone";
};

在 /etc 目录下创建 test.com.zone 文件。

$ttl 604800
test.com.       IN      SOA     ns1.test.com. mail.test.com. (
                        1
                        10M
                        1H
                        1H
                        24H )
@       IN      NS      ns1
ns1     IN      A       172.21.9.125
@       IN      A       172.21.9.125

使用 dig 命令测试。

[root@localhost etc]# dig test.com @127.0.0.1

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.14 <<>> test.com @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28292
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;test.com.                      IN      A

;; ANSWER SECTION:
test.com.               604800  IN      A       172.21.9.125

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: 六 10月 07 20:54:18 CST 2023
;; MSG SIZE  rcvd: 53

5. 自定义反向区域解析

反向区域解析即通过 ip 反查域名。

区域名称需要反写,比如:

172.21.9. --> 9.21.172.in-addr.arpa.

在 named.conf.default-zones 文件中添加 172.21.9 的反向区域。

; 需要反过来写,不然找不到
zone "9.21.172.in-addr.arpa" {
        type master;
        file "/etc/bind/172.21.9.zone";
};

创建 172.21.9.zone 文件,内容如下:

$ttl 604800
@       IN      SOA     ns1.test.com. mail.test.com. (
                        1
                        10M
                        1H
                        1H
                        24H )
@       IN      NS      ns1.test.com.
100     IN      PTR     www.baidu.com.

需要特别注意根域名后面需要加点,否则会自动拼接本域名。

使用 dig 命令测试。

[root@localhost etc]#  dig -x 172.21.9.100 @172.21.9.125

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.14 <<>> -x 172.21.9.100 @172.21.9.125
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53572
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;100.9.21.172.in-addr.arpa.     IN      PTR

;; ANSWER SECTION:
100.9.21.172.in-addr.arpa. 604800 IN    PTR     www.baidu.com.

;; Query time: 0 msec
;; SERVER: 172.21.9.125#53(172.21.9.125)
;; WHEN: 日 10月 08 16:07:45 CST 2023
;; MSG SIZE  rcvd: 81

六、主从DNS服务器

1. 主从服务器安装

主服务器 172.21.9.125 和从服务器 172.21.9.123 上运行如下命令。

docker run -d \
--name bind \
--restart=always \
-p 53:53/tcp \
-p 53:53/udp \
-p 10000:10000/tcp \
-v /home/docker/bind:/data \
sameersbn/bind

2. 主服务器配置

修改配置文件 named.conf.options。

options {
        directory "/var/cache/bind";
        dnssec-validation auto;
        listen-on { any; };
        listen-on-v6 { any; };
        allow-query { any; };
        recursion yes;
        // 安全配置,只允许172.21.9.123传输主服务器上的dns数据
        allow-transfer {
                172.21.9.123;
        };
};

在 named.conf.default-zones 文件中添加 test.com 的区域。

zone "test.com" {
        type master;
        file "/etc/bind/test.com.zone";
};

在 /etc 目录下创建 test.com.zone 文件,与之前不同的地方在于,这里需要新增从服务器的记录,这样记录修改时才会通知从服务器进行同步数据。

$ttl 604800
test.com.       IN      SOA     ns1.test.com. mail.test.com. (
                        1
                        10M
                        1H
                        1H
                        24H )
@       IN      NS      ns1
; 指定从服务器地址
@       IN      NS      ns2
ns1     IN      A       172.21.9.125
ns2     IN      A       172.21.9.123
@       IN      A       172.21.9.125

3. 从服务器配置

修改配置文件 named.conf.options。

options {
        directory "/var/cache/bind";
        dnssec-validation auto;
        listen-on { any; };
        listen-on-v6 { any; };
        allow-query { any; };
        recursion yes;
        // 安全配置,不允许其他服务器传输数据
        allow-transfer { none; };
};

在 named.conf.default-zones 文件中添加 test.com 的区域,类型为 slave,并指定 master 的地址和指定区域数据文件地址。需要注意的是,同步过来的区域数据文件是二进制的,不能直接进行查看。

zone "test.com" {
        type slave;
        masters { 172.21.9.125;};
        file "/etc/bind/test.com.zone.slave";
};

区域数据文件会自动同步,不需要手动进行创建。

4. 测试主从数据同步

这里演示在主服务器新增一条记录,看看指定从服务器作为 dns 服务器时,是否能进行解析即可。

需要注意的是,修改数据文件,需要进行修改版本序列号,并重启 bind 服务,否则从服务器不会进行同步。

在主服务器 test.com.zone 文件中添加一条 www 的解析记录,同时将版本号修改为 2,然后重启 bind 容器。

$ttl 604800
test.com.       IN      SOA     ns1.test.com. mail.test.com. (
                        2
                        10M
                        1H
                        1H
                        24H )
@       IN      NS      ns1
@       IN      NS      ns2
ns1     IN      A       172.21.9.125
ns2     IN      A       172.21.9.123
@       IN      A       172.21.9.125
www     IN      A       172.21.9.123

接下来测试 172.21.9.123 是否可以正常解析 www.test.com。

[root@localhost etc]# dig www.test.com @172.21.9.123

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.14 <<>> www.test.com @172.21.9.123
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4477
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.test.com.                  IN      A

;; ANSWER SECTION:
www.test.com.           604800  IN      A       172.21.9.123

;; Query time: 0 msec
;; SERVER: 172.21.9.123#53(172.21.9.123)
;; WHEN: 日 10月 08 00:10:26 CST 2023
;; MSG SIZE  rcvd: 57

发现可以正常解析 www 记录,即从服务器搭建完成。

七、子域服务器

1. 服务器安装

主服务器 172.21.9.125 和子服务器 172.21.9.123 上运行如下命令。

docker run -d \
--name bind \
--restart=always \
-p 53:53/tcp \
-p 53:53/udp \
-p 10000:10000/tcp \
-v /home/docker/bind:/data \
sameersbn/bind

2. 主服务器配置

修改配置文件 named.conf.options。

options {
        directory "/var/cache/bind";
        listen-on { any; };
        listen-on-v6 { any; };
        allow-query { any; };
        recursion yes;
        //建议关闭加密验证
        dnssec-enable no;
        dnssec-validation no;
};

在 named.conf.default-zones 文件中添加 test.com 的区域。

zone "test.com" {
        type master;
        file "/etc/bind/test.com.zone";
};

在 /etc 目录下创建 test.com.zone 文件,与之前不同的地方在于,这里需要新增子域服务器的 NS 记录。

$ttl 604800
test.com.       IN      SOA     ns1.test.com. mail.test.com. (
                        1
                        10M
                        1H
                        1H
                        24H )
@       IN      NS      ns1
; 指定 bengjing.test.com 的域名服务器
beijing IN      NS      beijingns
ns1     IN      A       172.21.9.125
beijingns     IN      A       172.21.9.123
@       IN      A       172.21.9.125

记得重启 bind 容器。

3. 子域服务器配置

修改配置文件 named.conf.options。

options {
        directory "/var/cache/bind";
        listen-on { any; };
        listen-on-v6 { any; };
        allow-query { any; };
        recursion yes;
        //建议关闭加密验证
        dnssec-enable no;
        dnssec-validation no;
};

在 named.conf.default-zones 文件中添加 beijing.test.com 的区域。

zone "beijing.test.com" {
        type master;
        file "/etc/bind/beijing.test.com.zone";
};

在 /etc 目录下创建 beijing.test.com.zone 文件。

$ttl 604800
beijing.test.com.       IN      SOA     ns1. mail.test.com. (
                        1
                        10M
                        1H
                        1H
                        24H )
; 指定主服务器地址
@       IN      NS      ns1
ns1     IN      A       172.21.9.125
; 此时的记录应该为 www.beijing.test.com
www     IN      A       172.21.9.123

记得重启 bind 容器。

4. 测试子域

[root@localhost etc]# dig www.beijing.test.com @172.21.9.125

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.14 <<>> www.beijing.test.com @172.21.9.125
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13163
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.beijing.test.com.          IN      A

;; ANSWER SECTION:
www.beijing.test.com.   604790  IN      A       172.21.9.123

;; Query time: 0 msec
;; SERVER: 172.21.9.125#53(172.21.9.125)
;; WHEN: 日 10月 08 14:04:27 CST 2023
;; MSG SIZE  rcvd: 65

指定主 dns 进行查询 www.beijing.test.com 的解析,发现可以正常返回,说明搭建完成。

八、Webadmin

其实之前安装的容器提供了一个 web 界面,对于添加区域、在区域中添加记录都可以进行可视化修改。

访问 https://xx.yy:10000 即可登录 webadmin,账号密码:root/password。

1. 配置语言

如图所示,修改为简体中文,然后点击确定修改。虽然说修改了系统语言,但是还是有部分还是英文。

Docker 自建 dns 服务器 bind 以及使用详解

/>

2. bind配置界面

点击服务器可查看 bind 服务器相关配置。

上面显示全局服务器选项,包括配置日志、转发等等。

下面显示现有 DNS 区域,在这里可以创建主区域、从区域等等,还可以点击区域进行修改区域数据文件。

Docker 自建 dns 服务器 bind 以及使用详解

/>

3. 区域页面

点击 test.com,进入如下界面,在这里可以看见区域配置的地址、命名服务器等等。

Docker 自建 dns 服务器 bind 以及使用详解

/>

4. 解析界面

点击地址可以看见之前配置的解析,并可以对解析进行增删改。

Docker 自建 dns 服务器 bind 以及使用详解

/>

webadmin 功能很强大,更多功能可以自己探索。

提醒:本文发布于380天前,文中所关联的信息可能已发生改变,请知悉!

Tips:清朝云网络工作室

阅读剩余
THE END