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
目录
- [DNS 简介](#DNS 简介)
- [DNS 解析原理](#DNS 解析原理)
- [DNS 服务器搭建 (BIND9)](#DNS 服务器搭建 (BIND9))
- [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/24→0.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
全部输出来自服务器实操,非模拟数据