DNS 服务器¶
本文你会学到:
- DNS 查询流程:本地缓存 → /etc/hosts → 递归解析器 → 迭代查询链
- 根服务器、顶级域服务器、权威 DNS 的角色
- DNS 记录类型(A、AAAA、CNAME、MX、NS、TXT 等)
- 递归查询与迭代查询的区别
- 在 Linux 上配置 DNS 客户端(/etc/resolv.conf)
nslookup和dig命令的使用与调试技巧- DNS 缓存的 TTL(生存时间)机制
- 在 BIND/dnsmasq 上部署 DNS 服务器的基础
- DNS 的安全问题与 DNSSEC 的简介
DNS 工作原理¶
域名解析流程¶
当你在浏览器输入 www.example.com 时,系统会按照以下优先级依次查找:
- 本地缓存:操作系统 DNS 缓存(TTL 未过期时直接命中)
/etc/hosts:静态映射文件,优先级高于 DNS- 递归查询:向
/etc/resolv.conf中配置的递归解析器发起查询 - 迭代查询链:递归解析器依次询问根服务器(
.)→ 顶级域服务器(.com)→ 权威 DNS,最终拿到 A 记录
sequenceDiagram
participant C as 客户端
participant H as /etc/hosts
participant R as 递归解析器
participant Root as 根服务器(.)
participant TLD as 顶级域(.com)
participant Auth as 权威 DNS
C->>H: 查本地 hosts 文件
H-->>C: 未命中
C->>R: 查询 www.example.com
Note over R: 检查本地缓存
R->>Root: www.example.com 的 IP?
Root-->>R: 不知道,去找 .com NS
R->>TLD: www.example.com 的 IP?
TLD-->>R: 不知道,去找 example.com NS
R->>Auth: www.example.com 的 IP?
Auth-->>R: 93.184.216.34 (A 记录)
R-->>C: 93.184.216.34
Note over R: 缓存结果(TTL 内有效)
graph LR
classDef step fill:transparent,stroke:#0288d1,color:#adbac7,stroke-width:1px
classDef cache fill:transparent,stroke:#388e3c,color:#adbac7,stroke-width:1px
classDef auth fill:transparent,stroke:#f57c00,color:#adbac7,stroke-width:2px
A[本地缓存]:::cache --> B[/etc/hosts]:::step
B --> C[递归解析器]:::step
C --> D[根服务器 .]:::auth
D --> E[TLD 服务器]:::auth
E --> F[权威 DNS]:::auth
F --> G[返回 IP]:::cache
TTL 决定缓存时长
每条 DNS 记录都有 TTL(Time to Live)字段,单位为秒。TTL 越大,缓存越持久,解析越快;TTL 越小,更改生效越快,但查询压力增大。修改 DNS 记录后,需等待旧 TTL 耗尽,全网才能完全生效。
DNS 记录类型¶
| 类型 | 全称 | 用途 |
|---|---|---|
A |
Address | 域名 → IPv4 地址 |
AAAA |
IPv6 Address | 域名 → IPv6 地址 |
CNAME |
Canonical Name | 域名别名(指向另一个域名) |
MX |
Mail eXchanger | 邮件交换服务器(带优先级) |
NS |
Name Server | 该区域由哪台 DNS 服务器管理 |
PTR |
Pointer | IP → 域名(反向解析) |
TXT |
Text | 任意文本,常用于 SPF/DKIM/域名验证 |
SOA |
Start of Authority | 区域权威信息(序列号、刷新时间等) |
CNAME 不能与其他记录共存于同名节点,根域(@)不能设 CNAME,这是常见的配置陷阱。
DNS 服务器分类¶
权威 DNS(Authoritative)¶
存储某个区域(Zone)完整数据库的服务器,能直接回答该区域内所有主机名的查询。例如 example.com 的 NS 记录指向的服务器就是其权威 DNS。
权威 DNS 又分为 主服务器(Master/Primary) 和 从服务器(Slave/Secondary):
Master:管理员手动编辑区域文件,是数据的权威来源Slave:从 Master 自动同步(Zone Transfer),提供冗余
递归解析器(Recursive Resolver)¶
接收客户端查询,代替客户端完成整个迭代查询链(根→TLD→权威),把最终结果缓存并返回。家用路由器的 DNS、8.8.8.8(Google)、1.1.1.1(Cloudflare)都是递归解析器。
转发器(Forwarder)¶
自身不进行完整递归查询,而是把所有请求转发给上游解析器处理。常用于公司内网:内网 DNS 负责解析内部域名,其余请求转发到互联网 DNS。
缓存 DNS(Caching-only)¶
不管理任何区域,只做递归查询和结果缓存。无需维护区域文件,适合用作本地 DNS 加速器(如 Unbound)。
BIND9 安装与基本配置¶
BIND(Berkeley Internet Name Domain)是使用最广泛的 DNS 服务器软件,支持权威和递归两种模式。
安装¶
主配置文件结构¶
BIND9 的主配置文件由若干配置块组成,注释使用 // 或 /* */,每个语句以 ; 结尾。
| /etc/bind/named.conf | |
|---|---|
实际选项写在 named.conf.options,自定义区域写在 named.conf.local。
options 块关键参数¶
正向解析区域文件¶
以下以 example.com 为例,配置一个完整的正向解析区域。
第一步:在主配置文件中声明区域
第二步:编写区域文件
| 创建区域文件目录 | |
|---|---|
区域文件格式陷阱
- 所有记录必须从**行首**开始,前面不能有空格(有空格代表续行)
- FQDN 末尾必须有
.(小数点),否则系统会自动追加区域名。例如ns1等价于ns1.example.com.,但ns1.example.com会变成ns1.example.com.example.com. - 每次修改区域文件后,必须**递增 Serial**,Slave 才会同步
反向解析区域文件¶
反向解析(PTR 记录)用于 IP → 域名查询。区域名需将 IP 网络段反转并加 .in-addr.arpa.,例如 203.0.113.0/24 对应区域名为 113.0.203.in-addr.arpa。
| /etc/bind/named.conf.local(追加) | |
|---|---|
| /etc/bind/zones/203.0.113.rev | |
|---|---|
在 /etc/named.conf 追加区域声明,区域文件写法与 Debian 相同,路径改为 /var/named/203.0.113.rev。
启动与验证¶
| 启动 BIND9 并验证 | |
|---|---|
| 测试本地 DNS 解析 | |
|---|---|
Unbound:轻量递归解析器¶
Unbound 是一款轻量、安全的递归解析器,专为缓存 DNS 场景设计,无法管理权威区域。它比 BIND9 配置更简单,资源占用更少,适合作为本地 DNS 缓存或家庭/办公室 DNS。
安装与配置¶
| 启动 Unbound | |
|---|---|
BIND9 vs Unbound:如何选择¶
| 场景 | 推荐 |
|---|---|
| 需要管理自有域名(权威 DNS) | BIND9 |
| 需要 Master/Slave 主从同步 | BIND9 |
| 仅需本地 DNS 缓存加速 | Unbound |
| 内网递归解析器 | Unbound |
| 资源受限的嵌入式/容器环境 | Unbound |
| 需要 DNSSEC 签名(而非仅验证) | BIND9 |
两者组合使用
企业常见方案:Unbound 作为前端递归缓存接收内网查询,内部域名转发给 BIND9 权威服务器,外部域名直接迭代解析或转发到公共 DNS。
DNS 调试工具¶
dig:最强诊断工具¶
dig(Domain Information Groper)是 DNS 调试的首选工具,输出详细且结构化。
| dig 基础用法 | |
|---|---|
| dig +trace:追踪完整解析链 | |
|---|---|
+trace 模式会显示从 .(根)→ .com(TLD)→ 权威 DNS 的每一跳,非常适合排查委派错误或 NS 配置问题。
| dig 输出精简控制 | |
|---|---|
dig 输出分为四个 Section:
QUESTION SECTION:提出的查询ANSWER SECTION:直接回答(命中缓存时带Non-authoritative answer标记)AUTHORITY SECTION:权威 DNS 服务器信息ADDITIONAL SECTION:辅助数据(如 NS 对应的 A 记录)
nslookup:交互式查询¶
nslookup 支持交互模式,适合临时调试:
| nslookup 交互模式 | |
|---|---|
systemd-resolve:systemd 环境诊断¶
在使用 systemd-resolved 的现代 Linux 系统上,用以下命令诊断:
| systemd-resolve 常用命令 | |
|---|---|
53 端口冲突排查
如果本机安装 BIND9 或 Unbound 后发现 53 端口被 systemd-resolved 占用,可通过 ss -ulnp sport 53 确认占用进程,然后在 /etc/systemd/resolved.conf 中设置 DNSStubListener=no 并重启 systemd-resolved。
DNS 安全¶
DNSSEC:数字签名验证¶
DNSSEC(DNS Security Extensions)通过公钥密码学为 DNS 记录添加数字签名,防止缓存投毒攻击。
工作原理:
- 区域管理员用私钥对区域中每条记录生成签名(
RRSIG) - 公钥发布为
DNSKEY记录,并由上级 DNS 的DS记录背书 - 递归解析器验证签名链:
DS(上级)→DNSKEY(本级)→RRSIG(记录签名) - 如果验证失败,解析器拒绝返回该结果(返回
SERVFAIL)
| 验证 DNSSEC 是否生效 | |
|---|---|
BIND9 开启 DNSSEC 验证只需在 options 中设置 dnssec-validation auto;(现代版本默认已开启)。
DNS over TLS(DoT)和 DNS over HTTPS(DoH)¶
传统 DNS 查询明文传输,中间人可以窃听或篡改。DoT 和 DoH 通过加密通道解决这个问题:
| DoT | DoH | |
|---|---|---|
| 端口 | 853(TCP) |
443(HTTPS) |
| 协议 | TLS | HTTPS(HTTP/2) |
| 隐私 | ✅ 加密 | ✅ 加密 |
| 可观测性 | ISP/防火墙可识别 | 混入 HTTPS 流量,难以过滤 |
| 标准 | RFC 7858 | RFC 8484 |
systemd-resolved 支持 DoT,在 /etc/systemd/resolved.conf 中启用:
| /etc/systemd/resolved.conf | |
|---|---|
Unbound 启用 DoT 上游转发:
| unbound.conf(DoT 上游) | |
|---|---|
常见攻击与防御¶
DNS 劫持(DNS Hijacking)
攻击者通过以下方式修改 DNS 解析结果:
- 控制用户路由器,篡改 DNS 设置
- 污染运营商 DNS 服务器
- 在中间人位置拦截 UDP 53 流量
防御:使用 DoT/DoH 加密传输 + DNSSEC 签名验证,双重保障。
缓存投毒(Cache Poisoning,DNS Spoofing)
攻击者向递归解析器发送伪造响应,使解析器缓存虚假记录,再将其他用户引导至恶意 IP。经典案例是 2008 年的 Kaminsky 漏洞。
防御措施:
- DNSSEC(记录签名验证)
- 随机化源端口(
0.0.0.0随机 UDP 源端口) - 现代 BIND9/Unbound 默认已启用随机化,保持软件更新即可
内网 DNS 安全基线
- 限制递归查询范围:
allow-recursion { 192.168.0.0/16; 127.0.0.0/8; };(避免成为开放递归服务器,可能被用于 DNS 放大攻击) - 限制区域传输:
allow-transfer { slave_ip; };,不向无关主机开放 - 定期检查
/var/log/named/或journalctl -u named,观察异常查询量