Linux配置DNS服务

DNS 简介

- 什么是域名

域名(DomainName),简称域名、网域,是由一串用点分隔的名字组成的Internet上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位。具有独一无二,不可重复的特性。

- 域名的关系和组成

常见域名:www.baidu.com
完整域名:www.baidu.com.

注意com 后面有一点

1
. :根域,可省略不写。
1
com:顶级域,由ICANN组织指定和管理。
1
2
3
4
5
分类:
1、国家地区域名: (cn(中国)、hk(香港)、sg (新加坡)等。
2、通用项级域名: com (商业机构)、org (非营利组织)、edu (教育机构)等。
3、新通用顶级域名: red (红色、热情)、top (顶级、高端)等。
4、com.cn属于“二级域名”,是cn项级域的子域。
1
baidu:级域(注册域) ,可由·个人或组织申请注册。
1
www:三级域(子域),服务器网站名代表。(www.baidu.com)

image-20250402083329281

- 什么是DNS?

域名系统(Domain Name System,缩写: DNS)是互联网的一项服务。域名解析是把域名指向网站空间IP,让人们通过注册的域名可以方便地访问到网站的一种服务。IP地址是网络上标识站点的数字地址,为了方便记忆,采用域名来代替IP地址标识站点地址。域名解析就是域名到IP地址的转换过程。域名的解析工作由DNS服务器完成。可以理解为DNS就是翻译官。

正向解析:域名 --> IP地址。
反向解析:IP地址 --> 域名。

DNS 工作过程

image-20250402084707783

客户端在浏览器输入一个域名:www.baidu.com,浏览器自动补充域名:www.baidu.com:80。80端口是web服务器的端口

1.在从自己本机中查询host文件,是否有此域名的解析记录,如果有则返回给浏览器

2.如果host文件没有域名的解析记录,则会在本机上继续查询是否有DNS的解析缓存,如果有则返回给浏览器

3.如果本机没有DNS的解析记录,则会在网卡设置的DNS服务器上,查询域名的解析结果

4.如果DNS服务器上也没有查询到,则会从别人询问的结果的缓存中查找

5.就迭代查询,顶级域名,二级域名,三级域名

DNS 配置文件

  • / etc / named.conf :主配置文件

image-20250402090006154

  • / etc / named.rfc1912.zones:区域配置文件

image-20250402090420936

  • / var / named / :数据配置文件

named.ca:记录了13台根域服务器的位置
named.localhost:正向代理
named.loopback:反向代理

image-20250402092142493

serial:主DNS每次改完zone必须加1,触发slave来同步;可填:纯数字、YYYYMMDDnn、Unix时间戳。
refresh:slave隔多久去查一次serial是否更新;可填:秒数或带单位的时间(如3600、1H、1D)。
retry:refresh失败后隔多久再试;可填:同上(如1800、30M)。
expire:多久拉不到数据就把zone视为失效;可填:同上(如604800、1W)。
minimum:否定/无记录结果在缓存里的最短生存时间;可填:同上(如10800、3H)。

类型 描述
A 地址记录,用来指定域名的 IPv4 地址的记录。
CNAME 将域名指向另一个域名,再由另一个域名提供 ip 地址,就需要添加 CNAME 记录。
TXT 可填写任何东西,长度限制 255。绝大多数的 TXT 记录是用来做 SPF 的(反垃圾邮件)。
NS 域名服务器记录,如果需要把子域名交给其他 DNS 服务商解析,就需要添加 NS 记录。
AAAA 地址记录,用来指定域名的 IPv6 地址的记录。
MX 邮件交换记录,如果需要设置邮箱,让邮箱能收到邮件,就需要添加 MX 记录。
PTR PoinTeR,IP --> FQDN
  • 软件名称:bind
  • 服务名称:named
  • 软件端口:

UDP 53 数据通信(域名解析)
TCP 53 数据同步(主从同步)

DNS 服务搭建

配置DNS地址:/etc/resolv.conf

主机名 ip 内存 硬盘 cpu OS
master 192.168.48.101 2g 100g 2v Centos7
slave 192.168.48.102 2g 100g 2v Centos7
client 192.168.48.103 2g 100g 2v Centos7

前情提要:以下是三台机的网卡dns配置,自行设置

matser: DNS1=192.168.48.101

slave: DNS1=192.168.48.102

client: DNS1=192.168.48.101 , DNS2=192.168.48.102

服务端配置

一、安装

1
yum install -y bind bind-utils

二、配置文件

操作节点:[master]

1.配置主文件 vim /etc/named.conf

1
2
// listen-on port 53 { 127.0.0.1; };
// allow-query { localhost; };

listen-on port 53 { 192.168.48.101; };
→ 只在 192.168.48.101 这台机器的 53 端口上提供 DNS 服务。如若注释掉:BIND 不再限定监听地址,会在服务器所有可用 IP 的 53 端口上提供 DNS 服务。这样就可以在多ip地址下进行dns了

allow-query { any; };
→ 允许任何来源向这台 DNS 服务器发起查询请求。如果不注释掉,只要网络可达(没有防火墙、路由等限制),任何 IP 地址(公网、私网、本机),这些设备把 DNS 指向你的服务器 IP 都可以向这台 DNS 服务器发起查询,如果注释掉了,他只会允许这台机同网段下局域网内的机子可以向这台dns服务器发起查询

这次实验主要是实现企业内网dns,所以这两项我都注释掉

这次实验主要是实现企业内网dns,所以这两项我都注释掉

这次实验主要是实现企业内网dns,所以这两项我都注释掉

2、配置区域文件 vim /etc/named.rfc1912.zones

1
2
3
4
5
6
7
8
9
10
cat >> /etc/named.rfc1912.zones <<"EOF2"
zone "aaa.com" IN {
type master;
file "aaa.com.zone";
};
zone "48.168.192.in-addr.arpa" IN {
type master;
file "aaa.loopback";
};
EOF2

3、编辑正向解析数据文件 vim /var/named/aaa.com.zone

1
2
3
4
5
6
7
cat > /var/named/aaa.com.zone <<"EOF"
$TTL 1D
@ IN SOA aaa.com. admin@qianyios.top. ( 0 1D 1H 1W 3H )
NS master
master A 192.168.48.101
www A 192.168.48.128
EOF

@:代表本域名的根域(zone 本身)

IN:记录类别为Internet(标准 TCP/IP)

SOA:这是一条起始授权记录(Start of Authority);

aaa.com.:该域的**主 DNS 服务器(primary nameserver)**主机名;(只是描述信息

admin@qianyios.top.:管理员邮箱地址(把第一个点换成 @),如果不需要则用 .invalid 表示示例/无效地址。(只是描述信息

NS master:声明本域的权威 DNS 服务器名字叫 master(相对名,实际全名是 master.aaa.com.)。

master A 192.168.48.101:给NS的名字为 master 绑定真实 IP 192.168.48.101,让别人能解析到这台权威服务器。

检查zone文件语法用:

[root@master ~]# named-checkzone aaa.com /var/named/aaa.com.zone
zone aaa.com/IN: loaded serial 0
OK

4、编辑反向解析数据文件 vim /var/named/aaa.loopback

举例了两条反向记录

1
2
3
4
5
6
7
cat > /var/named/aaa.loopback <<"EOF"
$TTL 1D
@ IN SOA aaa.com. admin@qianyios.top. ( 0 1D 1H 1W 3H )
NS master.aaa.com.
129 PTR www1.aaa.com.
128 PTR www.aaa.com.
EOF

NS master.aaa.com.:在正向zone不是配置了NS master吗,那反向这里就要写全称域名后面要加小数点

5.启动named服务

1
2
systemctl enable --now named 
systemctl restart named

重启无报错

客户端配置

操作节点:[client]

一、安装

1
yum install -y bind bind-utils

二、配置网卡dns

这是我的网卡名称是ens33你自己按你自己的改

1
vim /etc/sysconfig/network-scripts/ifcfg-ens33
1
DNS1=192.168.48.101

image-20250402093721868

重启网卡

1
systemctl restart network

查看是否配置成功

1
2
3
[root@client ~]# cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 192.168.48.101

三、 测试 nslookup

  • 正向解析测试
1
2
3
4
5
6
[root@client ~]# nslookup www.aaa.com
Server: 192.168.48.101
Address: 192.168.48.101#53

Name: www.aaa.com
Address: 192.168.48.128 #自己查看正向解析文件
  • 反向解析测试
1
2
3
4
[root@client ~]# host 192.168.48.128 && host 192.168.48.129
128.48.168.192.in-addr.arpa domain name pointer www.aaa.com.
129.48.168.192.in-addr.arpa domain name pointer www1.aaa.com.
#自行查看反向解析文件

成功

主从DNS服务器搭建

减轻主服务器的压力,数据从 主服务器上复制到 从服务器上

主服务器配置

操作节点:[master]

1.配置主文件 vim /etc/named.conf

1
2
listen-on port 53 { 192.168.48.101; }; //masterIP
allow-query { any; };

listen-on port 53 { 192.168.48.101; };
→ 只在 192.168.48.101 这台机器的 53 端口上提供 DNS 服务。如若注释掉:BIND 不再限定监听地址,会在服务器所有可用 IP 的 53 端口上提供 DNS 服务。这样就可以在多ip地址下进行dns了

allow-query { any; };
→ 允许任何来源向这台 DNS 服务器发起查询请求。如果不注释掉,只要网络可达(没有防火墙、路由等限制),任何 IP 地址(公网、私网、本机),这些设备把 DNS 指向你的服务器 IP 都可以向这台 DNS 服务器发起查询,如果注释掉了,他只会允许这台机同网段下局域网内的机子可以向这台dns服务器发起查询

这次实验主要是实现企业内网dns,所以这两项我都注释掉

这次实验主要是实现企业内网dns,所以这两项我都注释掉

这次实验主要是实现企业内网dns,所以这两项我都注释掉

2、配置区域文件 vim /etc/named.rfc1912.zones

allow-update(可选):只允许 192.168.48.102 这台主机向本 DNS 服务器发送动态更新

allow-update { any; };含义:允许任何主机向本 DNS 服务器提交动态更新请求,即谁都可以增删改该区域的资源记录。安全风险极大,生产环境务必改成 { none; } 或只列出可信 IP/密钥,否则任何人都能篡改你的域名解析。

1
2
3
4
5
6
7
8
9
10
zone "aaa.com" IN {
type master;
file "aaa.com.zone";
allow-update { none; };
};
zone "48.168.192.in-addr.arpa" IN {
type master;
file "aaa.loopback";
allow-update { none; };
};

3、编辑正向解析数据文件 vim /var/named/aaa.com.zone

1
2
3
4
5
6
7
cat > /var/named/aaa.com.zone <<"EOF"
$TTL 1D
@ IN SOA aaa.com. admin@qianyios.top. ( 0 1D 1H 1W 3H )
NS master
master A 192.168.48.101
www A 192.168.48.128
EOF

4、编辑反向解析数据文件 vim /var/named/aaa.loopback

1
2
3
4
5
6
7
cat > /var/named/aaa.loopback <<"EOF"
$TTL 1D
@ IN SOA aaa.com. admin@qianyios.top. ( 0 1D 1H 1W 3H )
NS master.aaa.com.
129 PTR www1.aaa.com.
128 PTR www.aaa.com.
EOF

从服务器配置

操作节点:[slave]

1
2
#安装
yum install -y bind bind-utils

1.配置主文件 vim /etc/named.conf

1
2
3
#注释掉
// listen-on port 53 { 127.0.0.1; };
// allow-query { localhost; };

2、配置区域文件 vim /etc/named.rfc1912.zones

1
2
3
4
5
6
7
8
9
10
11
12
cat >> /etc/named.rfc1912.zones << "EOF"
zone "aaa.com" IN {
type slave;
file "slaves/aaa.com.zone";
masters { 192.168.48.101; }; //主服务器的IP
};
zone "48.168.192.in-addr.arpa" IN {
type slave;
file "slaves/aaa.loopback";
masters { 192.168.48.101; }; //主服务器的IP
};
EOF

image-20250402100911225

如果主从同步之后区域数据文件会同步到/var/named/slaves这个目录下,现在还是空的

1
2
3
[root@slave ~]# ll /var/named/slaves
total 0
[root@slave ~]#

两台重启named服务

操作节点:[master,slave]

1
systemctl restart named

这时候经过两台服务器重启named之后,master里的两个文件就已经同步到slave的/var/named/slaves这个目录下

image-20250402100935884

客户端配置并测试正反向解析

操作节点:[client]

设置dns添加slave的IP地址

DNS2=192.168.48.102 然后重启网卡

修改网卡dns添加一个从服务器的ip

1
vim /etc/sysconfig/network-scripts/ifcfg-ens33

image-20250402101403809

重启网卡

1
systemctl restart network
1
2
3
4
5
#检查是否配置成功
[root@client ~]# cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 192.168.48.101
nameserver 192.168.48.102

测试主从服务

当我们给master模拟named服务故障时,由从服务器进行接管

测试前,是由master提供服务

1
2
3
4
5
6
7
8
9
10
[root@client ~]# nslookup www.aaa.com
Server: 192.168.48.101
Address: 192.168.48.101#53

Name: www.aaa.com
Address: 192.168.48.128

[root@client ~]# host 192.168.48.128 && host 192.168.48.129
128.48.168.192.in-addr.arpa domain name pointer www.aaa.com.
129.48.168.192.in-addr.arpa domain name pointer www1.aaa.com.

断开master的named的服务

1
2
[root@master ~]# systemctl stop named
[root@master ~]#

再次进行测试

1
2
nslookup www.aaa.com
host 192.168.48.128 && host 192.168.48.129

image-20250722003316519

这时重启master的named,客户机又从主服务器查询域名了

1
systemctl start named
1
2
3
4
5
6
7
8
9
[root@client ~]# host 192.168.48.128 && host 192.168.48.129
128.48.168.192.in-addr.arpa domain name pointer www.aaa.com.
129.48.168.192.in-addr.arpa domain name pointer www1.aaa.com.
[root@client ~]# nslookup www.aaa.com
Server: 192.168.48.101
Address: 192.168.48.101#53

Name: www.aaa.com
Address: 192.168.48.128

自动主从同步

我们已经配置了主从服务器了,如果这时主服务器的区域数据文件中又添加了新的解析条目,怎么实现从服务器也能自动同步这个数据呢?很简单

操作节点:[matser]

1.配置正向区域文件

1
2
3
4
5
6
7
8
9
10
cat > /var/named/aaa.com.zone <<"EOF"
$TTL 1D
@ IN SOA aaa.com. admin@qianyios.top. ( 1 1D 1H 1W 3H )
NS master
NS slave
master A 192.168.48.101
slave A 192.168.48.102 ;增加slave解析记录
www A 192.168.48.128
abc A 192.168.48.130
EOF

( 1 1D 1H 1W 3H );第一个数字,原先是0要增加到1,就是说dns要确定这个文件已经更新过了,靠这个数字来判断的,递增一次就是更新一次了,才可以进行同步

2.配置反向解析文件

1
2
3
4
5
6
7
8
9
cat > /var/named/aaa.loopback <<"EOF"
$TTL 1D
@ IN SOA aaa.com. admin@qianyios.top. ( 1 1D 1H 1W 3H )
NS master.aaa.com.
NS slave.aaa.com.
129 PTR www1.aaa.com.
128 PTR www.aaa.com.
130 PTR abc.aaa.com.
EOF

( 1 1D 1H 1W 3H );第一个数字,原先是0要增加到1,就是说dns要确定这个文件已经更新过了,靠这个数字来判断的,递增一次就是更新一次了,才可以进行同步

如果说你不想加NS slave.aaa.com.

你就要在vim /etc/named.rfc1912.zones里配置该域名下的添加

notify yes;,also-notify { 192.168.48.102; }

  • notify yes;
    主 DNS 变更后自动给 NS 列表里的辅 DNS 发“快更新”通知。
  • also-notify { 192.168.48.102; }
    在“自动推导的 NS 列表”之外,额外再通知一个/一批 IP。就是说如果你没加NS slave.aaa.com.,那么他会额外再通知192.168.48.102;

如下图

image-20250402102940010

3、测试

测试前查看slave数据的文件时间

image-20250402103413907

重启master的named的服务

1
systemctl restart named

image-20250402103830941

这时候已经更新了,再次在客户端进行测试

1
2
3
4
5
6
7
8
9
[root@client ~]# nslookup abc.aaa.com
Server: 192.168.48.101
Address: 192.168.48.101#53

Name: abc.aaa.com
Address: 192.168.48.130

[root@client ~]# host 192.168.48.130
130.48.168.192.in-addr.arpa domain name pointer abc.aaa.com.

都能成功进行解析,主从自动同步成功

失败案例

我有测试没有修改序号就添加数据顺便重启,是没有同步成功的

序号为1,没增加1,本身应该是2的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cat > /var/named/aaa.loopback <<"EOF"
$TTL 1D
@ IN SOA aaa.com. admin@qianyios.top. ( 1 1D 1H 1W 3H )
NS master.aaa.com.
NS slave.aaa.com.
129 PTR www1.aaa.com.
128 PTR www.aaa.com.
130 PTR abc.aaa.com.
131 PTR qy.aaa.com.
EOF
cat > /var/named/aaa.com.zone <<"EOF"
$TTL 1D
@ IN SOA aaa.com. admin@qianyios.top. ( 1 1D 1H 1W 3H )
NS master
NS slave
master A 192.168.48.101
slave A 192.168.48.102
www A 192.168.48.128
abc A 192.168.48.130
qy A 192.168.48.131
EOF

重启之前查看时间

1
2
3
4
5
[root@slave ~]# ll /var/named/slaves/
total 8
-rw-r--r-- 1 named named 329 Jul 22 08:46 aaa.com.zone
-rw-r--r-- 1 named named 393 Jul 22 08:46 aaa.loopback

重启之后

1
2
[root@master ~]# systemctl restart named
[root@master ~]#

slave下的文件还是和原来一样

1
2
3
4
[root@slave ~]# ll /var/named/slaves/
total 8
-rw-r--r-- 1 named named 329 Jul 22 08:46 aaa.com.zone
-rw-r--r-- 1 named named 393 Jul 22 08:46 aaa.loopback

并且客户端解析不到我新添加的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@client ~]# host 192.168.48.131
131.48.168.192.in-addr.arpa domain name pointer qy.aaa.com.
[root@client ~]# nslookup qy.aaa.com
Server: 192.168.48.101
Address: 192.168.48.101#53

Name: qy.aaa.com
Address: 192.168.48.131
#好奇怪这不是解析到了吗,因为dns里不是设置了两个dns吗,我们删掉master的dns,重启网卡
[root@client ~]# cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 192.168.48.102
#再次进行解析
[root@client ~]# host 192.168.48.131
Host 131.48.168.192.in-addr.arpa. not found: 3(NXDOMAIN)
[root@client ~]# nslookup qy.aaa.com
Server: 192.168.48.102
Address: 192.168.48.102#53

** server can't find qy.aaa.com: NXDOMAIN
#就说明192.168.48.102并没有实现同步

只有当我修改序号为2时,再进行重启,才能进行同步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
cat > /var/named/aaa.loopback <<"EOF"
$TTL 1D
@ IN SOA aaa.com. admin@qianyios.top. ( 2 1D 1H 1W 3H )
NS master.aaa.com.
NS slave.aaa.com.
129 PTR www1.aaa.com.
128 PTR www.aaa.com.
130 PTR abc.aaa.com.
131 PTR qy.aaa.com.
EOF
cat > /var/named/aaa.com.zone <<"EOF"
$TTL 1D
@ IN SOA aaa.com. admin@qianyios.top. ( 2 1D 1H 1W 3H )
NS master
NS slave
master A 192.168.48.101
slave A 192.168.48.102
www A 192.168.48.128
abc A 192.168.48.130
qy A 192.168.48.131
EOF
systemctl restart named

slave查看是否更新

1
2
3
4
5
[root@slave ~]# ll /var/named/slaves/
total 8
-rw-r--r-- 1 named named 367 Jul 22 08:56 aaa.com.zone
-rw-r--r-- 1 named named 456 Jul 22 08:56 aaa.loopback
#之前是8:46的,更新之后就是8:56

client查看解析

1
2
3
4
5
6
7
8
[root@client ~]# host 192.168.48.131
131.48.168.192.in-addr.arpa domain name pointer qy.aaa.com.
[root@client ~]# nslookup qy.aaa.com
Server: 192.168.48.102 #slave成功解析
Address: 192.168.48.102#53

Name: qy.aaa.com
Address: 192.168.48.131

ssh免密

此步骤是为了方便以下自动脚本

操作节点:【三台服务器】

这是我的ip和主机名,你根据需要自行修改

1
2
3
4
5
cat >> /etc/hosts << "EOF"
192.168.48.101 master
192.168.48.102 slave
192.168.48.103 client
EOF

操作节点:【master】

脚本里password="123456"是我三台机的密码,我三台都一样,如何你是不一样,你自己自行进行手动免密了

[master] yum install -y sshpass

[master] ssh-keygen -t rsa -N “” -f ~/.ssh/id_rsa

以下这个命令的主机名,三个主机名都要输一遍,也就是三条命令了

[master] sshpass -p “密码” ssh-copy-id -o StrictHostKeyChecking=no “主机名”

测试免密,三个主机名都要输一遍,也就是三条命令了

[master] sshpass -p “密码” ssh -o StrictHostKeyChecking=no “主机名” “echo ‘免密登录成功’”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
yum install -y sshpass 
cat > sshmianmi.sh << "EOF"
#!/bin/bash
# 目标主机列表
hosts=("master" "slave" "client")
# 密码
password="123456"
# 生成 SSH 密钥对
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa

# 循环遍历目标主机
for host in "${hosts[@]}"
do
# 复制公钥到目标主机
sshpass -p "$password" ssh-copy-id -o StrictHostKeyChecking=no "$host"

# 验证免密登录
sshpass -p "$password" ssh -o StrictHostKeyChecking=no "$host" "echo '免密登录成功'"
done
EOF

sh sshmianmi.sh

自动添加解析脚本

你要做的就是修改脚本中的SLAVE_IP="192.168.48.102"这是我的从节点的ip

你要把你的主从节点做好免密之后,才可以进行以下操作

操作节点:[master]

1
vim jx.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/bin/bash

# 检查参数数量
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <IP_ADDRESS> <DOMAIN>"
exit 1
fi

IP="$1"
DOMAIN="$2"
# 获取本机 IP 地址(假设主机只有一个有效 IP)
MASTER_IP=$(hostname -I | awk '{print $1}')
# 从服务器的 IP 地址
SLAVE_IP="192.168.48.102"

# 解析域名和反向 IP
BASE_DOMAIN=$(echo "$DOMAIN" | awk -F. '{print $(NF-1)"."$NF}')
ZONE_FILE="/var/named/$BASE_DOMAIN.zone"
REV_ZONE_FILE="/var/named/$(echo $IP | awk -F. '{print $3"."$2"."$1".in-addr.arpa"}').zone"
ZONE_CONFIG="/etc/named.rfc1912.zones"

# 解析反向 IP 和主机名
REV_IP=$(echo $IP | awk -F. '{print $3"."$2"."$1}')
REV_HOST=$(echo $IP | awk -F. '{print $4}')
SHORT_NAME=$(echo "$DOMAIN" | awk -F. '{print $1}')

# 确保 /var/named 目录存在
mkdir -p /var/named/
touch "$ZONE_FILE" "$REV_ZONE_FILE"
chown named:named "$ZONE_FILE" "$REV_ZONE_FILE"
chmod 644 "$ZONE_FILE" "$REV_ZONE_FILE"

# 检查是否已存在相同的解析记录
if grep -q "^$SHORT_NAME[[:space:]]*A[[:space:]]*$IP" "$ZONE_FILE"; then
echo "记录 $DOMAIN -> $IP 已存在,无需添加"
exit 0
fi

# **递增 serial 号**
increment_serial() {
# 提取当前 serial 值
current_serial=$(awk '/serial/{print $1}' "$1")

if [[ -z "$current_serial" ]]; then
# 如果没有找到 serial(空),初始化为 1
current_serial=1
fi

# 递增 serial
new_serial=$((current_serial + 1))

# 替换 serial 行,保留前导空格和注释
sed -i "s/\([[:space:]]*\)\([0-9]\+\)\([[:space:]]*; serial\)/\1$new_serial\3/" "$1"
}



# 添加正向解析区域配置(如果不存在)
if ! grep -q "zone \"$BASE_DOMAIN\" IN" "$ZONE_CONFIG"; then
cat >> "$ZONE_CONFIG" <<EOF
zone "$BASE_DOMAIN" IN {
type master;
file "$ZONE_FILE";
notify yes;
also-notify { $SLAVE_IP; };
allow-update { $SLAVE_IP; };
};
EOF
fi

# 添加反向解析区域配置(如果不存在)
if ! grep -q "zone \"$REV_IP.in-addr.arpa\" IN" "$ZONE_CONFIG"; then
cat >> "$ZONE_CONFIG" <<EOF
zone "$REV_IP.in-addr.arpa" IN {
type master;
file "$REV_ZONE_FILE";
notify yes;
also-notify { $SLAVE_IP; };
allow-update { $SLAVE_IP; };
};
EOF
fi

# **初始化 Zone 文件(正向解析)**
if [ ! -s "$ZONE_FILE" ]; then
cat > "$ZONE_FILE" <<EOF
\$TTL 1D
@ IN SOA $BASE_DOMAIN rname.invalid. (
1 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS $BASE_DOMAIN
$BASE_DOMAIN A $MASTER_IP

EOF
increment_serial "$ZONE_FILE" # 初始化时递增 serial
fi

# **追加 A 记录(使用短名)**
if ! grep -q "^$SHORT_NAME[[:space:]]*A[[:space:]]*$IP" "$ZONE_FILE"; then
echo "$SHORT_NAME A $IP" >> "$ZONE_FILE"
increment_serial "$ZONE_FILE" # 追加记录后递增 serial
fi

# **初始化 Zone 文件(反向解析)**
if [ ! -s "$REV_ZONE_FILE" ]; then
cat > "$REV_ZONE_FILE" <<EOF
\$TTL 1D
@ IN SOA $BASE_DOMAIN rname.invalid. (
1 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS $BASE_DOMAIN
$BASE_DOMAIN A $MASTER_IP

EOF
increment_serial "$REV_ZONE_FILE" # 初始化时递增 serial
fi

# **追加 PTR 记录**
if ! grep -q "^$REV_HOST[[:space:]]*PTR[[:space:]]*$SHORT_NAME.$BASE_DOMAIN." "$REV_ZONE_FILE"; then
echo "$REV_HOST PTR $SHORT_NAME.$BASE_DOMAIN." >> "$REV_ZONE_FILE"
increment_serial "$REV_ZONE_FILE" # 追加记录后递增 serial
fi

# 在从服务器上追加主从同步配置
ssh -T root@$SLAVE_IP <<EOF
# 检查从服务器配置文件是否已存在主从同步区域
if ! grep -q "zone \"$BASE_DOMAIN\" IN" "$ZONE_CONFIG"; then
cat >> "$ZONE_CONFIG" <<EOT
zone "$BASE_DOMAIN" IN {
type slave;
file "slaves/$BASE_DOMAIN.zone";
masters { $MASTER_IP; }; # 主服务器的IP
};
EOT
fi

# 检查反向解析的从服务器配置
if ! grep -q "zone \"$REV_IP.in-addr.arpa\" IN" "$ZONE_CONFIG"; then
cat >> "$ZONE_CONFIG" <<EOT
zone "$REV_IP.in-addr.arpa" IN {
type slave;
file "slaves/$REV_IP.loopback";
masters { $MASTER_IP; }; # 主服务器的IP
};
EOT
fi
EOF

# 重新加载主服务器的 Bind 配置
systemctl restart named
echo "✅ DNS 记录已添加并重新加载 Bind 服务"

# 重新加载从服务器上的 Bind 配置
ssh -T root@$SLAVE_IP <<EOF
systemctl restart named
echo "✅ 从服务器 $SLAVE_IP 配置已更新并重新加载 Bind 服务"
EOF

echo "✅ 主从同步配置已成功添加到从服务器 $SLAVE_IP"


systemctl restart named
1
2
3
bash jx.sh 192.168.111.201 bs.qianyios12.top
bash jx.sh 192.168.123.202 bs1.qianyios1245.top
bash jx.sh 192.168.236.203 bs3.qianyios22224.top

image-20250402132308000

接下来进行测试,三台机都可以进行测试

1
2
3
4
5
6
nslookup bs.qianyios12.top
nslookup bs1.qianyios1245.top
nslookup bs3.qianyios22224.top
host 192.168.111.201
host 192.168.123.202
host 192.168.236.203

master

image-20250402132443227

slave

image-20250402132517976

client

image-20250402132543331

特别声明
千屹博客旗下的所有文章,是通过本人课堂学习和课外自学所精心整理的知识巨著
难免会有出错的地方
如果细心的你发现了小失误,可以在下方评论区告诉我,或者私信我!
非常感谢大家的热烈支持!