当前位置: 代码网 > 服务器>服务器>Linux > Linux环境下DNS服务器搭建全过程

Linux环境下DNS服务器搭建全过程

2026年07月31日 Linux 我要评论
前言dns(domain name system,域名系统)是互联网最基础的服务之一,它的核心作用只有一个:把人类易记的域名转换成机器可读的 ip 地址。没有 dns,你访问网站就得记 142.250

前言

dns(domain name system,域名系统)是互联网最基础的服务之一,它的核心作用只有一个:把人类易记的域名转换成机器可读的 ip 地址。没有 dns,你访问网站就得记 142.250.70.78 而不是 google.com

本文从实战出发,亲手搭建一套完整的 dns 服务体系,涵盖:

  • 高速缓存 dns —— 加速域名解析,减少出口流量
  • 正向解析(a 记录) —— 域名 → ipv4 地址
  • 邮件交换记录(mx 记录) —— 指定邮件服务器
  • 反向解析(ptr 记录) —— ip 地址 → 域名
  • 多向解析(view 视图) —— 不同网段返回不同结果
  • 主从同步(辅助 dns) —— 高可用、自动数据同步

一、高速缓存 dns(caching dns)

1.1 什么是缓存 dns?

当客户端向缓存 dns 发起查询时,缓存 dns 替它向互联网上的权威 dns 服务器递归查询,拿到结果后缓存到本地。下次同样的查询直接返回缓存结果,大幅提高解析速度。

工作流程图解:

客户端 → 缓存dns → 根dns → .com dns → baidu.com dns(权威)
         ↓                                      ↑
      缓存 ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ←

1.2 实验环境

主机名ip用途
red(dns 服务器)192.168.17.138部署缓存 dns
ub(客户端 1)192.168.17.131测试查询
ub2(客户端 2)192.168.17.137测试查询

1.3 安装 bind 并启动服务

# 安装 bind 软件包(bind.x86_64 是 linux 上最主流的 dns 服务器软件)
[root@bogon ~]# dnf install bind.x86_64 -y

# 启用并立即启动 named 服务(named = name daemon,bind 的守护进程名)
[root@bogon ~]# systemctl enable --now named

1.4 修改主配置文件

[root@bogon ~]# vim /etc/named.conf
options {
        listen-on port 53 { any; };            # 监听所有网卡的 53 端口(默认只监 listening 127.0.0.1)
        listen-on-v6 port 53 { ::1; };          # 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; };               # 允许所有客户端向本机发起 dns 查询
        forwarders      { 144.144.144.144; };   # 指定上游 dns 服务器(缓存未命中时向谁转发)
};

重点参数说明:

参数作用
listen-on port 53 { any; }默认只监听 127.0.0.1,必须改为 any 才能对外服务
allow-query { any; }访问控制,默认只允许本机,改为 any 开放给局域网
forwarders上游 dns,缓存没命中的请求会转发给这个地址(可根据你的网络环境设为 114.114.114.114 或 8.8.8.8)

1.5 重启并验证服务状态

[root@bogon ~]# systemctl restart named

# 查看 named 是否正常监听端口
[root@bogon ~]# netstat -antlupe | grep named
tcp        0      0 127.0.0.1:53            0.0.0.0:*               listen      25         89111      35133/named         
tcp        0      0 192.168.17.138:53       0.0.0.0:*               listen      25         89115      35133/named

看到 192.168.17.138:53 在 listen,说明 dns 服务器已正常对外提供服务。

1.6 客户端测试

在客户端 ub(192.168.17.131)上测试:

# dig 是最常用的 dns 查询工具,@ 指定要查询的 dns 服务器
root@qwe-virtual-machine:~# dig www.baidu.com @192.168.17.138

二、dns 权威解析部署

缓存 dns 是"代理查询",而下面要搭建的是权威 dns—— 自己管理一个域名,自己决定域名指向哪个 ip。

2.1 正向解析(a 记录)

作用:将域名解析为 ipv4 地址,这是 dns 最基础、最常用的功能。

2.1.1 添加区域声明

首先要告诉 named:“我负责管理 qwer.com 这个域”。

[root@bogon ~]# vim /etc/named.rfc1912.zones

在文件末尾添加:

zone "qwer.com" in {
        type master;                # 类型为主 dns 服务器
        file "qwer.com.zone";       # 区域数据文件的路径(相对于 /var/named/)
        allow-update { none; };     # 是否允许动态更新(这里不允许,安全考虑)
};

配置参数解读:

参数含义
type master本机是这个域的主 dns,数据由本机管理
file "qwer.com.zone"指向 /var/named/qwer.com.zone 这个区域文件
allow-update { none; }禁止外部动态更新 dns 记录(防止被篡改)

2.1.2 创建区域数据文件

[root@bogon ~]# cd /var/named/

# -p 表示保留原文件的权限和属组(bind 对文件权限十分敏感)
[root@bogon named]# cp -p named.localhost qwer.com.zone

[root@bogon named]# vim qwer.com.zone
$ttl 1d
@       in soa  admin.qwer.com.         root.qwer.com.  (
                                        0       ; serial   序列号,从 0 开始,每次修改递增
                                        1d      ; refresh  辅 dns 刷新间隔(1 天)
                                        1h      ; retry    刷新失败后重试间隔(1 小时)
                                        1w      ; expire   辅 dns 数据过期时间(1 周)
                                        3h )    ; minimum  否定缓存 ttl(3 小时)
        ns      dns.qwer.com.           ; 声明权威 dns 服务器为 dns.qwer.com
dns     a       192.168.17.138          ; dns.qwer.com 指向本机 ip
www     a       192.168.17.138          ; www.qwer.com 指向本机 ip

逐行详解:

记录含义
$ttl 1d默认 ttl(time to live)为 1 天,告诉其他 dns 缓存这条记录多久
@代表当前域名(qwer.com),是 zone 语句里域名的简写
soastart of authority,起始授权记录,每个域必须有且只有一条
ns dns.qwer.com.nameserver 记录,指定该域的权威 dns 是哪个
dns a 192.168.17.138a 记录,dns.qwer.com 指向 192.168.17.138
www a 192.168.17.138a 记录,www.qwer.com 指向 192.168.17.138

⚠️ 注意域名结尾的点dns.qwer.com. 最后一个点表示这是一个"完全限定域名(fqdn)",不加点的话 bind 会自动追加上 zone 名变成 dns.qwer.com.qwer.com

2.1.3 重启 named 并测试

[root@bogon named]# systemctl restart named

客户端测试:

root@qwe-virtual-machine:~# dig www.qwer.com @192.168.17.138

;; answer section:
www.qwer.com.     86400    in    a    192.168.17.138

成功! www.qwer.com 成功解析到 192.168.17.138

2.2 邮件交换记录(mx 记录)

作用:mx 记录告诉发件服务器:“发往 user@qwer.com 的邮件应该投递到哪个邮件服务器”。

mx 记录 = 邮件服务器的"导航牌"。

2.2.1 添加 mx 记录

[root@bogon named]# vim qwer.com.zone

在文件末尾添加一行:

qwer.com.       mx 5    192.168.17.138.

格式拆解:

域名            类型  优先级  邮件服务器域名
qwer.com.       mx    5       192.168.17.138.

优先级(preference)说明:

  • 数字越小优先级越高
  • 如果配置了多条 mx:
    qwer.com.  mx  5   mail1.qwer.com.
    qwer.com.  mx  10  mail2.qwer.com.
    
    发件方会优先尝试 mail1(优先级 5),失败后才尝试 mail2(优先级 10)
  • 相同优先级可在多台服务器间负载均衡

⚠️ mx 记录的目标必须是域名,虽然上面例子直接写了 ip(简单演示),但生产环境标准的 mx 记录应该指向一个 a 记录域名,再通过 a 记录指向 ip:

qwer.com.  mx  5  mail.qwer.com.
mail       a     192.168.17.138

重启并测试:

[root@bogon named]# systemctl restart named
root@qwe-virtual-machine:~# dig qwer.com mx @192.168.17.138

2.3 反向解析(ptr 记录)

作用:ptr 记录是 a 记录的"反向操作"——给定一个 ip 地址,查出它对应的域名。

为什么需要反向解析?

  • 反垃圾邮件:接收方检查发件 ip 的 ptr 记录是否匹配发件域名。如果不匹配,邮件可能被标记为垃圾邮件或被拒收
  • 日志审计:根据 ip 反查域名,更容易读懂访问来源
  • 访问控制:某些服务(如 ssh、ftp)可根据 ptr 限制访问

2.3.1 添加反向区域声明

反向解析的 zone 名是 ip 反转 + .in-addr.arpa

  • 网段 192.168.17.0/24 → 反转 17.168.192 → 得到 17.168.192.in-addr.arpa
[root@localhost ~]# vim /etc/named.rfc1912.zones
zone "17.168.192.in-addr.arpa" in {
        type master;
        file "192.168.17.ptr";
        allow-update { none; };
};

2.3.2 创建反向区域文件

[root@localhost ~]# cd /var/named/

# -p 保留权限,named.loopback 是反向区域文件的模板
[root@localhost named]# cp -p named.loopback  192.168.17.ptr

[root@localhost named]# vim 192.168.17.ptr
$ttl 1d
@       in soa  admin.qwer.com. root.qwer.com.  (
                                        0       ; serial
                                        1d      ; refresh
                                        1h      ; retry
                                        1w      ; expire
                                        3h )    ; minimum
        ns      dns.qwer.com.         ; 权威 dns 服务器
dns     a       192.168.17.138        ; 必须有一条 a 记录指向 dns 本身
111     ptr     haha.qwer.com.        ; 192.168.17.111 → haha.qwer.com

重点说明:

  • 111 是 ip 地址 192.168.17.111 的最后一段,bind 会自动拼接成 111.17.168.192.in-addr.arpa
  • ptr haha.qwer.com. —— 表示 ip 192.168.17.111 解析为域名 haha.qwer.com.
  • 反向区域文件中必须有对应的 a 记录dns a 192.168.17.138),否则 bind 会报错

2.3.3 测试反向解析

root@qwe-virtual-machine:~# dig -x 192.168.17.111 @192.168.17.138

;; answer section:
111.17.168.192.in-addr.arpa. 86400  in  ptr  haha.qwer.com.

参数 -x 是 dig 的反向查询快捷方式,相当于帮你把 ip 反转成 in-addr.arpa 格式。

三、dns 多向解析

3.1 什么是多向解析?

同一个 dns 服务器,根据客户端来源 ip 的不同,返回不同的解析结果。这在实际生产环境中非常实用:

客户端网段查询 www.example.com返回的 ip目的
内网 16 网段(192.168.16.x)10.16.0.10访问内网服务器
内网 15 网段(192.168.15.x)10.15.0.10访问就近的内网服务器
外网(互联网)1.2.3.4访问公网入口

为什么要这么做?

  • 内网用户不需要绕到外网再回来,直接解析到内网 ip,速度快、流量省
  • 不同网段可以指向不同服务器(负载分担 / 就近接入)
  • 外网用户解析到公网入口,走正常的外网访问路径

3.2 实验环境

主机名ip用途
dns 服务器192.168.17.1部署多向解析(view),同时服务 16 和 15 网段
客户端 a192.168.16.10016 网段用户
客户端 b192.168.15.10015 网段用户

3.3 配置多向解析

3.3.1 主配置文件启用 view

bind 的 view 配置写在 /etc/named.conf 中。注意:一旦使用了 view,所有的 zone 都必须放在 view 内部

[root@dns ~]# vim /etc/named.conf

整体结构如下:

options {
        listen-on port 53 { any; };
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        allow-query     { any; };
};

# ---------- 视图 1:16 网段 ----------
view "lan16" {
        match-clients { 192.168.16.0/24; };          # 匹配来自 16 网段的请求

        zone "." in {
                type hint;
                file "named.ca";                      # 根域提示(每个 view 都要有)
        };

        zone "example.com" in {
                type master;
                file "example.com.zone.lan16";        # 16 网段专用的区域文件
        };
};

# ---------- 视图 2:15 网段 ----------
view "lan15" {
        match-clients { 192.168.15.0/24; };          # 匹配来自 15 网段的请求

        zone "." in {
                type hint;
                file "named.ca";
        };

        zone "example.com" in {
                type master;
                file "example.com.zone.lan15";        # 15 网段专用的区域文件
        };
};

# ---------- 视图 3:其他(外网) ----------
view "external" {
        match-clients { any; };                       # 其他所有来源

        zone "." in {
                type hint;
                file "named.ca";
        };

        zone "example.com" in {
                type master;
                file "example.com.zone.external";     # 外网看到的区域文件
        };
};

配置详解:

配置作用
view "lan16"视图名称,可自定义,无实际功能影响
match-clients { 192.168.16.0/24; }匹配规则——只有源 ip 匹配的客户端才会进入这个 view
match-clients { any; }兜底匹配——必须放在最后,匹配所有不满足上面条件的客户端
多个 view 的匹配顺序bind 从上到下依次匹配,命中了就进入,不再继续

3.3.2 创建三个区域文件

每个 view 引用了不同的区域文件,现在分别创建:

16 网段区域文件——给内网 16 网段的用户看:

[root@dns ~]# cd /var/named/
[root@dns named]# vim example.com.zone.lan16
$ttl 1d
@       in soa  admin.example.com. root.example.com. (
                                        0       ; serial
                                        1d      ; refresh
                                        1h      ; retry
                                        1w      ; expire
                                        3h )    ; minimum
        ns      dns.example.com.
dns     a       192.168.17.1
www     a       10.16.0.10             # 16 网段用户访问 www,返回内网 10.16.0.10

15 网段区域文件——给内网 15 网段的用户看:

[root@dns named]# vim example.com.zone.lan15
$ttl 1d
@       in soa  admin.example.com. root.example.com. (
                                        0       ; serial
                                        1d      ; refresh
                                        1h      ; retry
                                        1w      ; expire
                                        3h )    ; minimum
        ns      dns.example.com.
dns     a       192.168.17.1
www     a       10.15.0.10             # 15 网段用户访问 www,返回 10.15.0.10

外网区域文件——给互联网用户看:

[root@dns named]# vim example.com.zone.external
$ttl 1d
@       in soa  admin.example.com. root.example.com. (
                                        0       ; serial
                                        1d      ; refresh
                                        1h      ; retry
                                        1w      ; expire
                                        3h )    ; minimum
        ns      dns.example.com.
dns     a       192.168.17.1
www     a       1.2.3.4               # 外网用户访问 www,返回公网 ip

⚠️ 注意文件名:bind 对区域文件的名称没有强制要求,但建议用有意义的命名区分不同视图,避免混淆。

3.3.3 重启 named

[root@dns named]# systemctl restart named

3.4 多向解析的核心要点

要点说明
匹配顺序view 按 named.conf 中定义的顺序从上到下匹配,命中即止
兜底 view最后一个 view 必须用 match-clients { any; },防止没有匹配的客户端被拒绝
根域提示每个 view 里都要配 zone "." { type hint; file "named.ca"; },否则递归查询失效
区域文件独立不同 view 的区域文件互不干扰,可以同名区域不同内容
安全隔离内网用户解析不到公网 ip,外网用户也看不到内网拓扑

四、主从 dns 同步(辅助 dns)

4.1 为什么需要主从架构?

单台 dns 服务器会面临单点故障——服务器宕机,整个域名解析就瘫痪。主从架构解决了这个问题:

  • 主 dns(master):数据源,可读可写
  • 从 dns(slave):从主 dns 同步数据,只读
  • 客户端可以配置两个 dns,一个宕机自动切到另一个

4.2 实验环境

主机名ip角色
node1172.25.254.10dns 主服务器(master),拥有 timinglee.org 的完整数据
node2172.25.254.20dns 从服务器(slave),从 node1 同步数据

4.3 配置主 dns(node1)

4.3.1 安装 bind

[root@node1 ~]# dnf install bind -y

4.3.2 修改主配置文件

[root@node1 ~]# vim /etc/named.conf
options {
        listen-on port 53 { any; };          # 监听所有网卡
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        allow-query     { any; };            # 允许所有客户端查询
        recursion yes;
};

4.3.3 添加主区域声明

[root@node1 ~]# vim /etc/named.rfc1912.zones
zone "timinglee.org" in {
        type master;
        file "timinglee.org.zone";
        allow-update { none; };
        allow-transfer { 172.25.254.20; };   # 仅允许从 dns node2 来同步数据
};

⚠️ allow-transfer 是关键:如果不加这一行,从 dns 请求区域传输时会被拒绝,无法同步任何数据。

4.3.4 创建区域文件

[root@node1 ~]# cd /var/named/
[root@node1 named]# cp -p named.localhost timinglee.org.zone
[root@node1 named]# vim timinglee.org.zone
$ttl 1d
@       in soa  admin.timinglee.org.  root.timinglee.org. (
                                        2026071901      ; serial
                                        1d      ; refresh
                                        1h      ; retry
                                        1w      ; expire
                                        3h )    ; minimum
        ns      dns.timinglee.org.
dns     a       172.25.254.10
timinglee       a       172.25.254.254
[root@node1 named]# systemctl restart named

4.4 配置从 dns(node2)

4.4.1 安装 bind

[root@node2 ~]# dnf install bind -y

4.4.2 修改主配置文件

从 dns 的 named.conf 配置与主 dns 类似,开放监听和查询权限:

[root@node2 ~]# vim /etc/named.conf
options {
        listen-on port 53 { any; };
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        secroots-file   "/var/named/data/named.secroots";
        recursing-file  "/var/named/data/named.recursing";
        allow-query     { any; };
};

4.4.3 添加从区域声明

[root@node2 ~]# vim /etc/named.rfc1912.zones
zone "timinglee.org" in {
        type slave;                         # 类型为从 dns
        masters { 172.25.254.10; };         # 指定主 dns 的 ip
        file "slaves/timinglee.org.zone";    # 同步来的数据存放位置
};

file "slaves/timinglee.org.zone" —— 为什么是 slaves/ 目录?因为 named 的 selinux 策略只允许从 dns 在 slaves/ 目录下创建文件。

4.4.4 启动从 dns

[root@node2 ~]# systemctl enable --now named

4.5 测试主从同步是否成功

在**从 dns(node2)**上查询 timinglee.org 域内的域名,看看数据是否同步过来了:

[root@node2 ~]# dig timinglee.timinglee.org @172.25.254.20

; <<>> dig 9.16.23-rh <<>> timinglee.timinglee.org @172.25.254.20
;; flags: qr aa rd ra; query: 1, answer: 1, authority: 0, additional: 1

;; answer section:
timinglee.timinglee.org. 86400  in  a  172.25.254.254

status: noerror + answer section 返回了正确的 ip 172.25.254.254主从同步成功 🎉

此时查看从 dns 的 slaves 目录,可以看到数据文件已被自动创建:

[root@node2 ~]# ls -l /var/named/slaves/
-rw-r--r--. 1 named named 432 jul 19 15:45 timinglee.org.zone

4.6 主 dns 数据变更后自动通知从 dns

问题:默认配置下,主 dns 修改了区域数据后,从 dns 要等 1 天(refresh 字段) 才会去检查并同步。更新跟不上变化。

解决方案:在主 dns 上配置 also-notify,当数据变更时主动通知从 dns 过来拉取最新数据。

4.6.1 主 dns 添加通知配置

[root@node1 named]# vim /etc/named.rfc1912.zones
zone "timinglee.org" in {
        type master;
        file "timinglee.org.zone";
        allow-update { none; };
        allow-transfer { 172.25.254.20; };    # 允许从 dns 同步
        also-notify { 172.25.254.20; };       # 数据变更时主动通知这个从 dns
};

4.6.2 修改区域文件并递增序列号

模拟一个变更——将 timinglee 的 a 记录从 172.25.254.254 改为 172.25.254.222

[root@node1 named]# vim /var/named/timinglee.org.zone
$ttl 1d
@       in soa  admin.timinglee.org.  root.timinglee.org. (
                                        2026071903      ; serial   ← 关键:每次修改都要递增这个数字!
                                        1d      ; refresh
                                        1h      ; retry
                                        1w      ; expire
                                        3h )    ; minimum
        ns      dns.timinglee.org.
dns                     a       172.25.254.10
timinglee               a       172.25.254.222       ; 从 254 改为 222
timinglee.org.          mx 5    172.25.254.10.

serial(序列号)为什么重要? 从 dns 通过比较序列号来判断数据是否更新。主 dns 序列号更大 → 从 dns 发起同步。改了记录但忘记递增序列号,从 dns 永远不会同步。

4.6.3 重启主 dns

[root@node1 named]# systemctl restart named

4.6.4 验证自动同步

在从 dns(node2)上再次查询,此刻从 dns 没有做任何操作,但数据已经刷新:

[root@node2 ~]# dig timinglee.timinglee.org @172.25.254.20

;; answer section:
timinglee.timinglee.org. 86400  in  a  172.25.254.222

ip 从原来的 172.25.254.254 更新成了 172.25.254.222also-notify 实时同步成功

五、知识点总结

dns 记录类型速查表

记录类型方向格式示例用途
a域名 → ipv4www.example.com. a 192.168.1.10网站访问基础
aaaa域名 → ipv6www.example.com. aaaa 2001:db8::1ipv6 访问
mx域名 → 邮件服务器example.com. mx 10 mail.example.com.邮件路由
ptrip → 域名10.1.168.192.in-addr.arpa. ptr www.example.com.反查验证
ns域名 → dns 服务器example.com. ns ns1.example.com.声明权威 dns
soa起始授权@ soa admin.example.com. root.example.com. (...)区域管理参数
cname域名 → 别名www.example.com. cname example.com.域名别名

主从 dns 同步流程

1. 管理员修改主 dns 区域文件
2. 递增 serial 序列号
3. 重启 named
4. also-notify 主动通知从 dns
5. 从 dns 比较序列号,发现更新
6. 从 dns 发起区域传输(axfr/ixfr)
7. 从 dns 数据同步完成

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com