Linux 搭建及配置 DNS 服务器 — 实操指南

Linux 搭建及配置 DNS 服务器 --- 实操指南

集群 : ecs-57c4-0004 (华为云香港 FlexusX) | OS : Ubuntu 24.04.4 LTS

BIND : 9.18.39-ESV | 域名 : lab.local | IP : 192.168.0.114

日期 : 2026-06-17 | 实操环境: 8vCPU / 16GiB


目录

  1. [DNS 简介](#DNS 简介)
  2. [DNS 解析原理](#DNS 解析原理)
  3. [DNS 服务器搭建 (BIND9)](#DNS 服务器搭建 (BIND9))
  4. [DNS 验证与测试](#DNS 验证与测试)

1. DNS 简介

1.1 什么是 DNS

DNS (Domain Name System) 是互联网的"电话簿",负责将人类可读的域名(如 www.baidu.com)转换为机器可读的 IP 地址(如 110.242.70.57)。

复制代码
域名 → DNS 解析 → IP 地址
www.baidu.com → DNS 服务器 → 110.242.70.57

1.2 系统 DNS 配置查阅

bash 复制代码
# /etc/resolv.conf --- 系统 DNS 解析器配置
$ cat /etc/resolv.conf
nameserver 127.0.0.53
options edns0 trust-ad
search openstacklocal

# /etc/hosts --- 本地静态解析 (优先级高于 DNS)
$ head -5 /etc/hosts
127.0.0.1       localhost

# /etc/nsswitch.conf --- 名称解析顺序
$ grep "^hosts:" /etc/nsswitch.conf
hosts:          files dns
# ↑ 先查 /etc/hosts (files), 再查 DNS

解析优先级: 应用程序 → nsswitch.conf → /etc/hosts → DNS 服务器 → 根服务器

1.3 DNS 记录类型

类型 全称 用途 示例
A Address 域名 → IPv4 www → 192.168.0.114
AAAA IPv6 Address 域名 → IPv6 ---
CNAME Canonical Name 别名 → 规范名 web → www.lab.local.
MX Mail Exchanger 邮件服务器优先级 MX 10 mail.lab.local.
NS Name Server 权威 DNS 服务器 ns1.lab.local.
SOA Start of Authority DNS 区域授权起点 Serial / Refresh / Retry / Expire
PTR Pointer IP → 域名 (反向解析) 114 → ns1.lab.local.
TXT Text SPF / DKIM / 验证 "v=spf1 include:... -all"
SRV Service 服务定位 _sip._tcp 5060
CAA Cert Authority 证书颁发授权 0 issue "letsencrypt.org"

1.4 查询实战

bash 复制代码
# A 记录查询
$ dig +short www.baidu.com A
www.a.shifen.com.
110.242.70.57
110.242.69.21

# NS 记录 --- 谁是这个域名的权威 DNS?
$ dig +short baidu.com NS
ns2.baidu.com.
ns3.baidu.com.
ns4.baidu.com.
dns.baidu.com.
ns7.baidu.com.

# MX 记录 --- 邮件服务器
$ nslookup -type=MX qq.com
qq.com  mail exchanger = 30 mx1.qq.com.
qq.com  mail exchanger = 20 mx2.qq.com.

# TXT 记录 --- SPF 发件策略
$ dig +short baidu.com TXT | head -1
"v=spf1 include:spf1.baidu.com include:spf2.baidu.com ... -all"

# PTR 反向解析
$ dig +short -x 114.114.114.114
public1.114dns.com.

2. DNS 解析原理

2.1 架构图

复制代码
                    ① www.baidu.com?
用户 ────────────────────────────────────────────────── 本地 DNS 服务器
      ⑧ 110.242.70.57                                    │
                                                        │ ② www.baidu.com?
                                                        ▼
                  ┌─ 根服务器 (.) ──────────────────────────┐
                  │ .  →  com. NS  a.gtld-servers.net.     │
                  │    ③ .com 权威服务器地址                 │
                  └─────────────────────────────────────────┘
                                                        │
                                                        │ ④ www.baidu.com?
                                                        ▼
                  ┌─ .com TLD 服务器 ───────────────────────┐
                  │ com. → baidu.com. NS ns2.baidu.com.    │
                  │    ⑤ baidu.com 权威服务器地址            │
                  └─────────────────────────────────────────┘
                                                        │
                                                        │ ⑥ www.baidu.com?
                                                        ▼
                  ┌─ baidu.com 权威 DNS ────────────────────┐
                  │ www.baidu.com → 110.242.70.57          │
                  │    ⑦ A 记录返回                         │
                  └─────────────────────────────────────────┘

2.2 全球 13 组根服务器

bash 复制代码
$ dig +short . NS
a.root-servers.net.    # VeriSign (美国)
b.root-servers.net.    # USC-ISI (美国)
c.root-servers.net.    # Cogent (美国)
d.root-servers.net.    # UMD (美国)
e.root-servers.net.    # NASA (美国)
f.root-servers.net.    # ISC (美国)
g.root-servers.net.    # DISA (美国)
h.root-servers.net.    # ARL (美国)
i.root-servers.net.    # Netnod (瑞典)
j.root-servers.net.    # VeriSign (美国)
k.root-servers.net.    # RIPE NCC (荷兰)
l.root-servers.net.    # ICANN (美国)
m.root-servers.net.    # WIDE Project (日本)

13 个根域名服务器使用 Anycast 技术,实际全球分布超过 1500 个节点。

2.3 递归解析追踪

bash 复制代码
$ dig +trace +nodnssec www.baidu.com A

# 步骤1: 从根服务器获取 .com 权威列表
.    7199 IN NS  a.root-servers.net.
.    7199 IN NS  b.root-servers.net.
... (13个根服务器)
;; Received 239 bytes from 127.0.0.53#53 in 0 ms

# 步骤2: 从 .com TLD 获取 baidu.com 权威列表
com. 172800 IN NS  a.gtld-servers.net.
com. 172800 IN NS  b.gtld-servers.net.
... (13个 .com TLD 服务器)
baidu.com.  172800  IN  NS  ns2.baidu.com.
;; Received 838 bytes from 192.203.230.10#53(e.root-servers.net) in 191 ms

2.4 DNS 缓存效果

bash 复制代码
# 首次查询 --- 走完整递归链路
$ time dig +noall +answer www.zhihu.com A
real    0m0.019s

# 第二次查询 --- 命中本地 DNS 缓存 (TLL=7197s)
$ time dig +noall +answer www.zhihu.com A
real    0m0.008s
# ↑ 缓存命中后查询速度提升 2 倍以上

2.5 不同 DNS 服务器性能对比

bash 复制代码
# 114DNS (国内)
$ time dig +noall +answer @114.114.114.114 www.baidu.com A
real    0m0.034s

# 阿里DNS (国内)
$ time dig +noall +answer @223.5.5.5 www.baidu.com A
real    0m0.013s

# Google DNS (海外)
$ time dig +noall +answer @8.8.8.8 www.baidu.com A
real    0m0.210s
# ↑ 香港 ECS 到 Google DNS 210ms vs 阿里 13ms

2.6 TTL 生命周期

bash 复制代码
# baidu.com SOA --- TTL 约 2 小时
$ dig +noall +answer baidu.com SOA
baidu.com. 7197 IN SOA dns.baidu.com. sa.baidu.com. (
        2012151130  ; Serial
        300         ; Refresh (5分钟)
        300         ; Retry
        2592000     ; Expire (30天)
        600 )       ; Negative Cache TTL

# qq.com SOA --- TTL 仅 60 秒 (快速切换)
$ dig +noall +answer qq.com SOA
qq.com. 60 IN SOA ns1.qq.com. webmaster.qq.com. (
        1330914143 3600 300 86400 300 )

3. DNS 服务器搭建 (BIND9)

3.1 环境与安装

bash 复制代码
# 环境信息
$ hostname && named -v
ecs-57c4-0004
BIND 9.18.39-0ubuntu0.24.04.5-Ubuntu (Extended Support Version)

# 安装
sudo apt-get install -y bind9 bind9utils bind9-doc dnsutils

BIND 配置文件目录:

bash 复制代码
$ ls /etc/bind/
bind.keys            named.conf                # 主配置
db.0                 named.conf.default-zones  # 默认区域
db.127               named.conf.local          # 自定义区域
db.255               named.conf.options        # 全局选项
db.empty             rndc.key                  # 管理密钥
db.local             zones.rfc1918             # RFC1918 反向

3.2 实验拓扑

复制代码
┌─────────────────────────────────────────────────┐
│            lab.local (DNS 实验域)                 │
│                                                   │
│   ns1 (192.168.0.114)  ←─ Master DNS             │
│   ns2 (192.168.0.29)   ←─ Slave DNS (待同步)     │
│   www (192.168.0.114)                             │
│   mail (192.168.0.114)  MX 10                     │
│   ftp (192.168.0.74)                              │
│   db  (192.168.0.186)                             │
│   *.lab.local → 192.168.0.114  (泛域名)           │
│                                                   │
│   服务器: ecs-57c4-0004 / BIND 9.18.39            │
└─────────────────────────────────────────────────┘

3.3 正向解析区域文件

创建 /etc/bind/db.lab.local

bind 复制代码
$TTL    604800
@       IN      SOA     ns1.lab.local. admin.lab.local. (
                  2026061701   ; Serial (YYYYMMDDNN)
                       604800   ; Refresh   (7 days)
                        86400   ; Retry     (1 day)
                      2419200   ; Expire    (28 days)
                       604800 ) ; Negative Cache TTL (7 days)
;
@       IN      NS      ns1.lab.local.
@       IN      NS      ns2.lab.local.
@       IN      MX 10   mail.lab.local.
;
ns1     IN      A       192.168.0.114
ns2     IN      A       192.168.0.29
mail    IN      A       192.168.0.114
;
www     IN      A       192.168.0.114
web     IN      CNAME   www
ftp     IN      A       192.168.0.74
db      IN      A       192.168.0.186
@       IN      A       192.168.0.114
;
; 泛域名解析
*       IN      A       192.168.0.114

SOA 字段说明

字段 含义 常规值
Serial 序列号,从服务器判断是否更新 YYYYMMDDNN
Refresh 从服务器同步间隔 3600-86400
Retry 同步失败重试间隔 600-3600
Expire 从服务器数据过期时间 604800-2419200
Negative TTL 否定答案缓存时间 300-86400

3.4 反向解析区域文件

创建 /etc/bind/db.192.168.0

bind 复制代码
$TTL    604800
@       IN      SOA     ns1.lab.local. admin.lab.local. (
                  2026061701   ; Serial
                       604800   ; Refresh
                        86400   ; Retry
                      2419200   ; Expire
                       604800 ) ; Negative Cache TTL
;
@       IN      NS      ns1.lab.local.
@       IN      NS      ns2.lab.local.
;
114     IN      PTR     ns1.lab.local.
114     IN      PTR     www.lab.local.
114     IN      PTR     mail.lab.local.
29      IN      PTR     ns2.lab.local.
74      IN      PTR     ftp.lab.local.
186     IN      PTR     db.lab.local.

反向区域命名规则 : 192.168.0.0/240.168.192.in-addr.arpa (IP 倒序 + .in-addr.arpa)

3.5 主配置文件

named.conf.local --- 区域声明:

bind 复制代码
// 正向解析区域
zone "lab.local" {
    type master;
    file "/etc/bind/db.lab.local";
    allow-transfer { 192.168.0.29; };   // 允许从 ns2 同步
    also-notify   { 192.168.0.29; };    // 主动通知 ns2
};

// 反向解析区域
zone "0.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/db.192.168.0";
    allow-transfer { 192.168.0.29; };
    also-notify   { 192.168.0.29; };
};

named.conf.options --- 全局选项:

bind 复制代码
options {
    directory "/var/cache/bind";

    // 允许内网递归查询
    allow-query     { 192.168.0.0/24; 127.0.0.0/8; };
    allow-recursion { 192.168.0.0/24; 127.0.0.0/8; };
    allow-transfer  { 192.168.0.29; };

    // 上游 DNS 转发器
    forwarders {
        114.114.114.114;
        223.5.5.5;
    };
    forward only;

    // DNSSEC 验证
    dnssec-validation auto;

    // 监听所有接口
    listen-on { any; };
    listen-on-v6 { any; };
};

3.6 配置语法检查

bash 复制代码
# 检查所有配置文件
$ named-checkconf -z
zone lab.local/IN: loaded serial 2026061701
zone 0.168.192.in-addr.arpa/IN: loaded serial 2026061701
zone localhost/IN: loaded serial 2
zone 127.in-addr.arpa/IN: loaded serial 1
zone 0.in-addr.arpa/IN: loaded serial 1
zone 255.in-addr.arpa/IN: loaded serial 1

# 单独检查区域文件
$ named-checkzone lab.local /etc/bind/db.lab.local
zone lab.local/IN: loaded serial 2026061701
OK

$ named-checkzone 0.168.192.in-addr.arpa /etc/bind/db.192.168.0
zone 0.168.192.in-addr.arpa/IN: loaded serial 2026061701
OK

3.7 启动服务

bash 复制代码
# 重启 BIND9
$ systemctl restart named

# 查看运行状态
$ systemctl status named
● named.service - BIND Domain Name Server
   Active: active (running) since Wed 2026-06-17 22:49:13 CST
   Main PID: 15204 (named)
   Status: "running"
   Tasks: 18 (limit: 18060)
   Memory: 25.8M (peak: 26.7M)

3.8 端口监听验证

bash 复制代码
$ ss -tlnp | grep named
LISTEN  127.0.0.1:53             # localhost IPv4 (8 worker threads)
LISTEN  192.168.0.114:53         # 内网 IPv4 (8 worker threads)
LISTEN  [::1]:53                 # localhost IPv6 (8 worker threads)
LISTEN  [fe80::...%eth0]:53     # 内网 IPv6 (8 worker threads)
LISTEN  127.0.0.1:953            # RNDC 管理接口
端口 协议 用途
53 UDP/TCP DNS 查询 (UDP 为主, TCP 用于大响应/区域传输)
953 TCP RNDC 远程管理控制

4. DNS 验证与测试

4.1 正向解析 (A 记录)

bash 复制代码
$ for host in ns1 ns2 www mail ftp db lab.local; do
    dig +short @127.0.0.1 $host.lab.local A
done

ns1.lab.local   → 192.168.0.114
ns2.lab.local   → 192.168.0.29
www.lab.local   → 192.168.0.114
mail.lab.local  → 192.168.0.114
ftp.lab.local   → 192.168.0.74
db.lab.local    → 192.168.0.186
lab.local       → 192.168.0.114

4.2 CNAME 别名

bash 复制代码
$ dig +short @127.0.0.1 web.lab.local CNAME
www.lab.local.          # web 是 www 的别名

$ dig +short @127.0.0.1 web.lab.local A
192.168.0.114           # 最终解析到 www 的 IP

4.3 泛域名解析

bash 复制代码
$ for host in api.lab.local test.lab.local dev.lab.local; do
    dig +short @127.0.0.1 $host A
done

api.lab.local   → 192.168.0.114
test.lab.local  → 192.168.0.114
dev.lab.local   → 192.168.0.114
# ↑ 所有未定义的子域名全部指向 192.168.0.114

4.4 MX / NS / SOA 记录

bash 复制代码
# MX 邮件记录
$ dig @127.0.0.1 lab.local MX +noall +answer
lab.local.  604800  IN  MX  10 mail.lab.local.

# NS 权威服务器
$ dig @127.0.0.1 lab.local NS +noall +answer
lab.local.  604800  IN  NS  ns1.lab.local.
lab.local.  604800  IN  NS  ns2.lab.local.

# SOA 授权记录
$ dig @127.0.0.1 lab.local SOA +noall +answer
lab.local.  604800  IN  SOA  ns1.lab.local. admin.lab.local. (
        2026061701 604800 86400 2419200 604800 )

4.5 反向解析 (PTR)

bash 复制代码
$ dig +short @127.0.0.1 -x 192.168.0.114
mail.lab.local.
www.lab.local.
ns1.lab.local.

$ dig +short @127.0.0.1 -x 192.168.0.29
ns2.lab.local.

$ dig +short @127.0.0.1 -x 192.168.0.74
ftp.lab.local.

$ dig +short @127.0.0.1 -x 192.168.0.186
db.lab.local.

4.6 nslookup 交互测试

bash 复制代码
# A 记录查询
$ nslookup www.lab.local 127.0.0.1
Server:  127.0.0.1
Address: 127.0.0.1#53

Name:    www.lab.local
Address: 192.168.0.114

# MX 记录查询
$ nslookup -type=MX lab.local 127.0.0.1
Server:  127.0.0.1
Address: 127.0.0.1#53

lab.local  mail exchanger = 10 mail.lab.local.

# PTR 反向查询
$ nslookup -type=PTR 192.168.0.114 127.0.0.1
Server:  127.0.0.1
Address: 127.0.0.1#53

114.0.168.192.in-addr.arpa  name = ns1.lab.local.
114.0.168.192.in-addr.arpa  name = www.lab.local.
114.0.168.192.in-addr.arpa  name = mail.lab.local.

4.7 dig 权威应答分析

bash 复制代码
$ dig @127.0.0.1 www.lab.local A

; <<>> DiG 9.18.39-0ubuntu0.24.04.5-Ubuntu <<>> @127.0.0.1 www.lab.local A
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33396
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; QUESTION SECTION:
;www.lab.local.                 IN      A

;; ANSWER SECTION:
www.lab.local.          604800  IN      A       192.168.0.114

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

flag 字段解读

flag 含义 说明
qr Query Response 这是响应 (非查询)
aa Authoritative Answer 权威应答 --- 我们自己的 DNS 服务器直接回答
rd Recursion Desired 客户端请求了递归查询
ra Recursion Available 服务器支持递归

没有 aa 标志 = 非权威应答 (来自缓存或上游转发)

4.8 性能测试

bash 复制代码
$ time for i in $(seq 1 100); do
    dig +short @127.0.0.1 www.lab.local A > /dev/null 2>&1; done

# 100 次本地 DNS 查询仅需 1301ms,平均 13.01ms/次

5. 进阶配置速查

5.1 主从复制 (Master-Slave)

Master (已配置 allow-transfer + also-notify):

bind 复制代码
zone "lab.local" {
    type master;
    file "/etc/bind/db.lab.local";
    allow-transfer { 192.168.0.29; };
    also-notify   { 192.168.0.29; };
};

Slave (ns2, 192.168.0.29):

bind 复制代码
zone "lab.local" {
    type slave;
    file "/var/cache/bind/db.lab.local";
    masters { 192.168.0.114; };
};

5.2 子域委派

bind 复制代码
; 在 lab.local 区域中委派 dev.lab.local
dev     IN      NS      ns-dev.lab.local.
ns-dev  IN      A       192.168.0.99

5.3 视图 (View) --- 智能 DNS

bind 复制代码
// 内网用户 → 内网 IP
view "internal" {
    match-clients { 192.168.0.0/24; };
    zone "lab.local" {
        type master; file "/etc/bind/db.lab.internal";
    };
};

// 外网用户 → 公网 IP
view "external" {
    match-clients { any; };
    zone "lab.local" {
        type master; file "/etc/bind/db.lab.external";
    };
};

5.4 TSIG 密钥认证

bash 复制代码
# 生成共享密钥
$ tsig-keygen -a hmac-sha256 master-slave-key
key "master-slave-key" {
    algorithm hmac-sha256;
    secret "base64-encoded-secret==";
};

5.5 常见安全加固

措施 配置 说明
限制递归 allow-recursion { 内网; }; 防止被用作 DDoS 放大器
限制查询 allow-query { 内网; }; 拒绝外网随机查询
限制传输 allow-transfer { slaves; }; 仅允许从服务器同步
禁用 ANY minimal-responses yes; 减少反射放大攻击
速率限制 rate-limit { responses-per-second 5; }; 限速保护
隐藏版本 version "Not Available"; 不暴露 BIND 版本

6. 故障排查

6.1 常见问题诊断

bash 复制代码
# 检查配置文件语法
named-checkconf /etc/bind/named.conf

# 检查区域文件
named-checkzone lab.local /etc/bind/db.lab.local

# 查看 BIND 日志
journalctl -u named -f

# 测试解析
dig @127.0.0.1 www.lab.local A

# 查看查询统计
rndc stats && cat /var/cache/bind/named.stats

6.2 常见错误

症状 原因 解决
SERVFAIL 区域文件语法错误 / 无法递归 named-checkzone + 检查 forwarders
NXDOMAIN 域名未定义 检查区域文件中是否有该记录
REFUSED ACL 限制了查询来源 检查 allow-query
connection timed out 防火墙 / BIND 未监听正确 IP `ss -tlnp
Serial 不增加 主从不同步 修改区域文件后递增 Serial

7. 常用命令速查

命令 用途
dig @server domain A 查询 A 记录
dig +short domain NS 查询权威 DNS
dig +trace domain 追踪完整解析链路
dig -x IP 反向解析
nslookup domain server 交互/非交互查询
host domain 快速查询
named-checkconf 检查配置文件
named-checkzone zone file 检查区域文件
rndc reload 重新加载配置
rndc stats 导出统计
rndc flush 清空缓存
systemctl restart named 重启 BIND

文档版本 : v1.0 | 创建日期 : 2026-06-17

集群 : ecs-57c4 (华为云香港 FlexusX) | BIND : 9.18.39-ESV

实验域名 : lab.local | Master DNS : 192.168.0.114

全部输出来自服务器实操,非模拟数据