DNS 服务器搭建与配置转发完全指南
DNS 服务器搭建与配置转发完全指南
- 版本:v1.0 · 标准参考:RFC 1034 / RFC 1035 / RFC 5625 / RFC 7766
- 适用软件:BIND 9.18+ · Unbound 1.17+ · dnsmasq 2.89+ · Windows Server DNS
- 适用系统:CentOS/RHEL 8+ · Ubuntu 22.04+ · Debian 12+ · Windows Server 2019/2022
目录
- DNS 基础概念回顾
- 架构设计与选型
- BIND 9 权威 DNS 服务器
- BIND 9 递归解析与转发配置
- Unbound 递归解析服务器
- dnsmasq 轻量级 DNS 转发
- Windows Server DNS 配置
- DNS 转发策略详解
- DNS 安全加固(DNSSEC & DoT & DoH)
- 高可用与负载均衡
- 性能调优
- 监控与日志
- 故障排查
- 典型企业部署方案
1. DNS 基础概念回顾
1.1 核心角色
| 角色 | 说明 | 典型软件 |
|---|---|---|
| 权威 DNS 服务器 | 托管区域数据,对外应答该区域查询 | BIND、PowerDNS、NSD |
| 递归解析器 | 代替客户端完整查询链,返回最终结果 | BIND、Unbound、dnsmasq |
| 转发器(Forwarder) | 将请求转发给上游解析器,本地缓存结果 | BIND、dnsmasq、Unbound |
| 根服务器 | 全球 13 组,解析链的起点 | — |
1.2 查询流程
客户端
│
▼ 递归查询
本地 DNS(企业内网)
│ 命中缓存 → 直接返回
│ 未命中 ↓
├─ 转发模式 → 上游 DNS(如 114.114.114.114)
└─ 递归模式 → 根服务器 → TLD → 权威 → 返回
1.3 重要 DNS 记录类型
| 记录类型 | 用途 | 示例 |
|---|---|---|
A |
域名 → IPv4 | www 300 IN A 1.2.3.4 |
AAAA |
域名 → IPv6 | www 300 IN AAAA ::1 |
CNAME |
别名 → 规范名 | blog IN CNAME www |
MX |
邮件服务器 | @ 300 IN MX 10 mail |
NS |
区域名称服务器 | @ IN NS ns1.example.com. |
PTR |
IP → 域名(反向) | 4.3.2.1.in-addr.arpa. |
SOA |
区域权威信息 | 序列号、刷新时间等 |
TXT |
文本信息 | SPF、DKIM、验证记录 |
SRV |
服务定位 | _sip._tcp 100 443 proxy |
2. 架构设计与选型
2.1 常见部署模式对比
| 场景 | 推荐方案 | 说明 |
|---|---|---|
| 家庭 / 小型办公室 | dnsmasq | 轻量,配置简单,适合路由器部署 |
| 中型企业内网 | BIND 9(转发模式)+ Unbound | 内外网分离,缓存效率高 |
| 大型企业 / ISP | BIND 9 权威 + Unbound 递归 | 角色分离,性能与安全均优 |
| 私有云 / K8s | CoreDNS | 云原生,插件化,与 K8s 深度集成 |
| Windows 域环境 | Windows Server DNS | 与 AD 域深度集成 |
2.2 推荐企业 DNS 分层架构
┌─────────────────────────────────────────────┐
│ 外网区域 │
│ 权威 DNS(对外):ns1.example.com │
│ ns2.example.com │
└──────────────────┬──────────────────────────┘
│ 防火墙 (UDP/TCP 53)
┌──────────────────▼──────────────────────────┐
│ 内网区域 │
│ ┌─────────────┐ ┌─────────────────────┐ │
│ │ 递归解析器 │ │ 内部权威 DNS │ │
│ │ (Unbound) │ │ (BIND 内网区域) │ │
│ │ 192.168.1.53│ │ 192.168.1.54 │ │
│ └──────┬──────┘ └─────────────────────┘ │
│ │ 转发上游 │
│ ┌──────▼──────────────────────────────┐ │
│ │ 上游 DNS(加密): │ │
│ │ 1.1.1.1 (Cloudflare DoT) │ │
│ │ 8.8.8.8 (Google DoH) │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
3. BIND 9 权威 DNS 服务器
3.1 安装
RHEL / CentOS 8+:
dnf install -y bind bind-utils
systemctl enable --now named
firewall-cmd --permanent --add-service=dns
firewall-cmd --reload
Ubuntu / Debian:
apt update && apt install -y bind9 bind9-utils bind9-doc
systemctl enable --now named
ufw allow 53/tcp
ufw allow 53/udp
验证版本:
named -v
# BIND 9.18.x (Extended Support Version)
3.2 主配置文件 /etc/named.conf
// /etc/named.conf
// BIND 9 主配置 - 权威 + 内网递归示例
options {
version "unknown"; // 隐藏版本信息(安全建议)
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";
// 监听接口
listen-on port 53 { 127.0.0.1; 192.168.1.53; };
listen-on-v6 port 53 { ::1; };
// 允许查询的客户端
allow-query { localhost; 192.168.0.0/16; 10.0.0.0/8; };
// 允许递归的客户端(仅内网)
allow-recursion { localhost; 192.168.0.0/16; 10.0.0.0/8; };
// 区域传送限制
allow-transfer { none; };
// 转发配置(见第 4 章)
forwarders { 1.1.1.1; 8.8.8.8; };
forward first;
// 安全选项
recursion yes;
dnssec-validation auto;
// 性能优化
max-cache-size 256m;
max-cache-ttl 3600;
min-cache-ttl 30;
max-ncache-ttl 300;
};
// 日志配置
logging {
channel default_log {
file "/var/log/named/named.log" versions 5 size 20m;
print-time yes;
print-severity yes;
print-category yes;
severity info;
};
channel query_log {
file "/var/log/named/query.log" versions 3 size 50m;
print-time yes;
severity info;
};
category default { default_log; };
category queries { query_log; };
category security { default_log; };
};
// 根区域提示
zone "." IN {
type hint;
file "named.ca";
};
// 本地回环区域
zone "localhost" IN {
type master;
file "named.localhost";
allow-update { none; };
};
// 内部区域引用
include "/etc/named/named.conf.local";
3.3 创建正向区域文件
/etc/named/named.conf.local 中声明区域:
// 正向区域
zone "example.com" IN {
type master;
file "/var/named/zones/db.example.com";
allow-update { none; };
notify yes;
};
// 反向区域(192.168.1.0/24)
zone "1.168.192.in-addr.arpa" IN {
type master;
file "/var/named/zones/db.192.168.1";
allow-update { none; };
};
区域数据文件 /var/named/zones/db.example.com:
; /var/named/zones/db.example.com
; 区域文件 - example.com
; 最后更新:2026-04-14
$TTL 3600 ; 默认 TTL:1 小时
$ORIGIN example.com.
; SOA 记录(区域起始授权)
@ IN SOA ns1.example.com. admin.example.com. (
2026041401 ; Serial(年月日+序号,每次修改必须递增)
3600 ; Refresh(从服务器刷新间隔)
900 ; Retry(失败后重试间隔)
604800 ; Expire(区域过期时间)
300 ) ; Negative Cache TTL
; NS 记录
@ IN NS ns1.example.com.
@ IN NS ns2.example.com.
; A 记录
ns1 IN A 192.168.1.53
ns2 IN A 192.168.1.54
@ IN A 1.2.3.4
www IN A 1.2.3.4
mail IN A 1.2.3.5
api IN A 1.2.3.6
; AAAA 记录
www IN AAAA 2001:db8::1
; CNAME 记录
blog IN CNAME www.example.com.
ftp IN CNAME www.example.com.
; MX 记录
@ IN MX 10 mail.example.com.
@ IN MX 20 mail2.example.com.
; TXT 记录(SPF)
@ IN TXT "v=spf1 mx a ~all"
反向区域文件 /var/named/zones/db.192.168.1:
$TTL 3600
$ORIGIN 1.168.192.in-addr.arpa.
@ IN SOA ns1.example.com. admin.example.com. (
2026041401
3600
900
604800
300 )
@ IN NS ns1.example.com.
@ IN NS ns2.example.com.
; PTR 记录(IP 末位 → 域名)
53 IN PTR ns1.example.com.
54 IN PTR ns2.example.com.
100 IN PTR www.example.com.
101 IN PTR mail.example.com.
3.4 主从复制(Zone Transfer)
主服务器 named.conf.local 补充:
zone "example.com" IN {
type master;
file "/var/named/zones/db.example.com";
allow-transfer { 192.168.1.54; }; // 仅允许从服务器
notify yes;
also-notify { 192.168.1.54; };
};
从服务器配置:
zone "example.com" IN {
type slave;
file "/var/named/slaves/db.example.com";
masters { 192.168.1.53; };
};
3.5 配置检查与启动
# 检查主配置语法
named-checkconf /etc/named.conf
# 检查区域文件语法
named-checkzone example.com /var/named/zones/db.example.com
named-checkzone 1.168.192.in-addr.arpa /var/named/zones/db.192.168.1
# 重载配置(不中断服务)
rndc reload
# 查看服务状态
systemctl status named
# 查看运行日志
journalctl -u named -f
4. BIND 9 递归解析与转发配置
4.1 纯转发模式(Forwarder Only)
将所有无法解析的请求全部转发给上游:
options {
// ...其他配置...
forwarders {
114.114.114.114; // 114DNS
114.114.115.115;
1.1.1.1; // Cloudflare
8.8.8.8; // Google
};
forward only; // 仅转发,不自行递归
recursion yes;
};
forward onlyvsforward first
forward only:只转发,上游不可达时直接失败(适合严格控制出口流量的环境)forward first:先转发,上游失败后自行递归(适合有备用解析能力的场景)
4.2 条件转发(Split-DNS / 分离解析)
企业内外网域名走不同上游,是最常见的企业 DNS 策略:
// 内部域名走内网权威服务器
zone "internal.example.com" {
type forward;
forwarders { 192.168.1.200; 192.168.1.201; };
forward only;
};
// 阿里云域名走阿里云 DNS
zone "aliyuncs.com" {
type forward;
forwarders { 100.100.2.136; 100.100.2.138; };
forward only;
};
// 其他域名走公共 DNS(在 options 中配置)
options {
forwarders { 1.1.1.1; 8.8.8.8; };
forward first;
};
4.3 视图(View)实现内外网分离
同一 DNS 服务器对内网返回私有 IP,对外返回公网 IP:
acl "internal" {
192.168.0.0/16;
10.0.0.0/8;
127.0.0.0/8;
};
acl "external" {
any;
};
// 内网视图(优先匹配)
view "internal" {
match-clients { internal; };
recursion yes;
allow-query { internal; };
zone "example.com" {
type master;
file "/var/named/views/internal/db.example.com";
};
};
// 外网视图
view "external" {
match-clients { external; };
recursion no; // 外网禁止递归
allow-query { any; };
zone "example.com" {
type master;
file "/var/named/views/external/db.example.com";
};
};
5. Unbound 递归解析服务器
Unbound 专注于安全递归解析,性能优于 BIND 递归模式,推荐作为企业内网解析器。
5.1 安装
# RHEL/CentOS
dnf install -y unbound
# Ubuntu/Debian
apt install -y unbound
systemctl enable --now unbound
5.2 主配置 /etc/unbound/unbound.conf
server:
# 监听地址
interface: 0.0.0.0
interface: ::0
port: 53
# 访问控制
access-control: 0.0.0.0/0 refuse
access-control: 127.0.0.0/8 allow
access-control: 192.168.0.0/16 allow
access-control: 10.0.0.0/8 allow
access-control: ::1/128 allow
# 隐藏版本
hide-version: yes
hide-identity: yes
# 性能
num-threads: 4
msg-cache-size: 128m
rrset-cache-size: 256m
cache-min-ttl: 30
cache-max-ttl: 3600
prefetch: yes
prefetch-key: yes
# DNSSEC 验证
auto-trust-anchor-file: "/var/lib/unbound/root.key"
# 日志
logfile: "/var/log/unbound/unbound.log"
log-queries: yes
verbosity: 1
# 本地数据(内部域名)
local-zone: "internal.example.com." static
local-data: "gateway.internal.example.com. IN A 192.168.1.1"
local-data: "nas.internal.example.com. IN A 192.168.1.100"
# 转发配置(向上游转发外部域名)
forward-zone:
name: "."
forward-addr: 1.1.1.1@853#cloudflare-dns.com # Cloudflare DoT
forward-addr: 8.8.8.8@853#dns.google # Google DoT
forward-tls-upstream: yes
# 包含本地配置
include: "/etc/unbound/conf.d/*.conf"
5.3 配置验证与管理
# 语法检查
unbound-checkconf
# 重载配置
unbound-control reload
# 刷新缓存
unbound-control flush_zone example.com
# 查看统计
unbound-control stats_noreset
# 更新 DNSSEC 根信任锚
unbound-anchor -a /var/lib/unbound/root.key
6. dnsmasq 轻量级 DNS 转发
dnsmasq 适合嵌入式设备、路由器、小型局域网,兼具 DNS 转发与 DHCP 功能。
6.1 安装
# RHEL/CentOS
dnf install -y dnsmasq
# Ubuntu/Debian
apt install -y dnsmasq
# 停止 systemd-resolved(Ubuntu 下可能冲突)
systemctl disable --now systemd-resolved
6.2 配置文件 /etc/dnsmasq.conf
# /etc/dnsmasq.conf
# ── 基础设置 ──────────────────────────────────────────────
# 监听接口(不指定则监听所有)
interface=eth0
bind-interfaces
# 不读取 /etc/hosts(可选)
# no-hosts
# 缓存大小(条目数)
cache-size=10000
# 禁止转发不含点的域名(避免泄漏本地名称)
domain-needed
bogus-priv
# ── 上游 DNS 转发 ─────────────────────────────────────────
# 默认上游转发(注释 /etc/resolv.conf,使用此处配置)
no-resolv
server=114.114.114.114
server=114.114.115.115
server=1.1.1.1
server=8.8.8.8
# ── 条件转发 ──────────────────────────────────────────────
# 内部域名走内网 DNS
server=/internal.example.com/192.168.1.200
server=/corp.local/10.0.0.53
# 反向解析也走内网
server=/168.192.in-addr.arpa/192.168.1.200
# ── 本地静态 DNS 记录 ──────────────────────────────────────
address=/gateway.local/192.168.1.1
address=/nas.local/192.168.1.100
address=/printer.local/192.168.1.200
# ── 日志 ──────────────────────────────────────────────────
log-queries
log-facility=/var/log/dnsmasq.log
# ── DHCP(可选)──────────────────────────────────────────
# dhcp-range=192.168.1.100,192.168.1.200,12h
# dhcp-option=6,192.168.1.53 # 告知客户端使用本机 DNS
6.3 管理命令
# 语法检查
dnsmasq --test
# 重启服务
systemctl restart dnsmasq
# 清除缓存(发送 SIGHUP)
kill -HUP $(pidof dnsmasq)
# 查看日志
tail -f /var/log/dnsmasq.log
7. Windows Server DNS 配置
7.1 安装 DNS 服务器角色
# 安装 DNS 服务器角色(PowerShell,管理员)
Install-WindowsFeature -Name DNS -IncludeManagementTools
# 验证安装
Get-WindowsFeature DNS
7.2 创建正向查找区域
# 创建主要正向查找区域
Add-DnsServerPrimaryZone `
-Name "example.com" `
-ZoneFile "example.com.dns" `
-DynamicUpdate None
# 添加 A 记录
Add-DnsServerResourceRecordA `
-ZoneName "example.com" `
-Name "www" `
-IPv4Address "1.2.3.4" `
-TimeToLive "01:00:00"
# 添加 CNAME 记录
Add-DnsServerResourceRecordCName `
-ZoneName "example.com" `
-Name "blog" `
-HostNameAlias "www.example.com"
# 添加 MX 记录
Add-DnsServerResourceRecordMX `
-ZoneName "example.com" `
-Name "@" `
-MailExchange "mail.example.com" `
-Preference 10
7.3 配置 DNS 转发
# 设置全局转发器
Set-DnsServerForwarder `
-IPAddress "1.1.1.1","8.8.8.8" `
-UseRootHint $false
# 查看当前转发器
Get-DnsServerForwarder
# 添加条件转发(内部域)
Add-DnsServerConditionalForwarderZone `
-Name "internal.corp.com" `
-MasterServers "192.168.1.200","192.168.1.201"
# 查看所有条件转发
Get-DnsServerZone | Where-Object { $_.ZoneType -eq "Forwarder" }
7.4 配置区域传送(主从)
# 在主服务器上允许区域传送给从服务器
Set-DnsServerPrimaryZone `
-Name "example.com" `
-SecureSecondaries "TransferToSecureServers" `
-SecondaryServers "192.168.1.54"
# 在从服务器创建辅助区域
Add-DnsServerSecondaryZone `
-Name "example.com" `
-ZoneFile "example.com.dns" `
-MasterServers "192.168.1.53"
8. DNS 转发策略详解
8.1 转发类型对比
| 类型 | 配置方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| 全局转发 | forwarders { ... }; forward only; |
中小企业简单出口 | 配置简单 | 缺乏灵活性 |
| 条件转发 | zone "x.com" { type forward; } |
多域名分流 | 精细控制 | 需逐域名配置 |
| 分视图转发 | view + match-clients |
内外网 Split-DNS | 同一 IP 双结果 | 配置复杂 |
| 策略转发(RPZ) | response-policy zone |
安全过滤 | 可屏蔽恶意域名 | 需维护黑名单 |
8.2 国内常用公共上游 DNS
| 服务商 | IP | DoT / DoH | 说明 |
|---|---|---|---|
| DNSPod(腾讯) | 119.29.29.29 119.28.28.28 |
✅ | 国内速度最快之一 |
| 阿里 DNS | 223.5.5.5 223.6.6.6 |
✅ | 稳定可靠 |
| 114DNS | 114.114.114.114 114.114.115.115 |
❌ | 纯净版可屏蔽广告 |
| Cloudflare | 1.1.1.1 1.0.0.1 |
✅ #cloudflare-dns.com |
全球最快,隐私保护 |
8.8.8.8 8.8.4.4 |
✅ #dns.google |
全球权威 | |
| Quad9 | 9.9.9.9 |
✅ | 安全过滤,屏蔽恶意域名 |
8.3 转发链路优化建议
优先级建议(企业环境):
1. 内部 DNS 缓存(命中率 > 60% 时优先)
2. 条件转发(内网域走内网服务器)
3. 国内公共 DNS(114 / DNSPod / 阿里)
4. 国际 DNS 作为备用(Cloudflare DoT)
9. DNS 安全加固(DNSSEC & DoT & DoH)
9.1 DNSSEC 配置(BIND 9)
DNSSEC 为 DNS 应答添加数字签名,防止域名劫持。
# 生成 ZSK(区域签名密钥)
dnssec-keygen -a ECDSAP256SHA256 -n ZONE example.com
# 生成 KSK(密钥签名密钥)
dnssec-keygen -a ECDSAP256SHA256 -f KSK -n ZONE example.com
# 在区域文件末尾引入密钥
echo '$INCLUDE Kexample.com.+013+XXXXX.key' >> /var/named/zones/db.example.com
echo '$INCLUDE Kexample.com.+013+YYYYY.key' >> /var/named/zones/db.example.com
# 对区域文件签名
dnssec-signzone -A -3 $(head -c 1000 /dev/urandom | sha1sum | cut -b 1-16) \
-N increment -o example.com -t \
/var/named/zones/db.example.com
named.conf 开启 DNSSEC 验证:
options {
dnssec-validation auto;
};
9.2 DNS over TLS(DoT)— Unbound
# /etc/unbound/unbound.conf 补充
server:
tls-service-key: "/etc/ssl/private/dns.key"
tls-service-pem: "/etc/ssl/certs/dns.crt"
tls-port: 853
interface: 0.0.0.0@853
forward-zone:
name: "."
forward-addr: 1.1.1.1@853#cloudflare-dns.com
forward-addr: 8.8.8.8@853#dns.google
forward-tls-upstream: yes
9.3 DNS over HTTPS(DoH)— nginx 反代
# nginx.conf 片段
server {
listen 443 ssl http2;
server_name dns.example.com;
ssl_certificate /etc/ssl/certs/dns.crt;
ssl_certificate_key /etc/ssl/private/dns.key;
location /dns-query {
proxy_pass http://127.0.0.1:8053;
proxy_http_version 1.1;
proxy_set_header Host $host;
add_header Content-Type "application/dns-message";
}
}
9.4 安全加固清单
| 加固项 | BIND 9 配置 | 说明 |
|---|---|---|
| 隐藏版本 | version "unknown"; |
防止版本探测 |
| 禁止外网递归 | allow-recursion { internal; }; |
防止开放解析器滥用 |
| 限制区域传送 | allow-transfer { slave-ip; }; |
防止区域数据泄露 |
| 限制动态更新 | allow-update { none; }; |
防止未授权写入 |
| 速率限制(RRL) | rate-limit { responses-per-second 10; }; |
防 DNS 放大攻击 |
| 禁用 CHAOS 查询 | deny-answer-aliases { any; }; |
防信息探测 |
10. 高可用与负载均衡
10.1 主从 DNS 高可用
┌─────────────────┐
客户端 ─────┬──▶│ 主 DNS (Master) │
│ │ 192.168.1.53 │
│ └────────┬────────┘
│ │ 区域传送
│ ┌────────▼────────┐
└──▶│ 从 DNS (Slave) │
│ 192.168.1.54 │
└─────────────────┘
客户端同时配置两个 DNS 服务器,主不可达时自动切换从。
10.2 Keepalived VIP 漂移
# /etc/keepalived/keepalived.conf(主节点)
vrrp_script chk_dns {
script "dig @127.0.0.1 example.com +time=2 +tries=1 > /dev/null 2>&1"
interval 5
fall 2
rise 2
}
vrrp_instance DNS_VIP {
state MASTER
interface eth0
virtual_router_id 61
priority 200
advert_int 1
authentication {
auth_type PASS
auth_pass dns_vip_pass
}
virtual_ipaddress {
192.168.1.50/24 dev eth0 # 虚拟 IP(客户端使用此地址)
}
track_script {
chk_dns
}
}
10.3 多播 DNS Round-Robin
; 同一域名绑定多个 IP 实现简单负载均衡
www 60 IN A 1.2.3.4
www 60 IN A 1.2.3.5
www 60 IN A 1.2.3.6
注意:DNS Round-Robin 无健康检查,生产环境推荐配合 F5 / HAProxy / 阿里云 SLB 使用。
11. 性能调优
11.1 BIND 9 性能参数
options {
// 并发查询线程(建议 = CPU 核心数)
// BIND 9.16+ 自动调整,通常无需手动设置
// 缓存
max-cache-size 512m; // 缓存总大小
max-cache-ttl 86400; // 正解最大缓存时间
max-ncache-ttl 3600; // 负解(NXDOMAIN)最大缓存时间
min-cache-ttl 60; // 强制最小 TTL
// 连接
tcp-clients 1000;
recursive-clients 5000;
clients-per-query 100;
max-clients-per-query 500;
// 预取(即将过期的热点记录提前刷新)
prefetch 10 60; // 剩余 TTL < 10s 且访问超 60次/s 时预取
};
11.2 系统层面优化
# /etc/sysctl.conf 追加
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 1048576
net.core.wmem_default = 1048576
net.core.netdev_max_backlog = 65536
net.ipv4.udp_rmem_min = 8192
sysctl -p
# 文件描述符限制
echo "named soft nofile 65536" >> /etc/security/limits.conf
echo "named hard nofile 65536" >> /etc/security/limits.conf
11.3 TTL 设置建议
| 记录类型 | 建议 TTL | 说明 |
|---|---|---|
| 基础设施(NS/SOA) | 86400(24h) | 变动极少 |
| 邮件服务(MX) | 3600(1h) | 较稳定 |
| Web 服务(A/AAAA) | 300~3600 | 按变更频率定 |
| CDN / 负载均衡 | 60~300 | 可能频繁漂移 |
| 灰度发布期间 | 30~60 | 便于快速回滚 |
12. 监控与日志
12.1 BIND 9 统计监控(HTTP 接口)
// named.conf 开启统计通道
statistics-channels {
inet 127.0.0.1 port 8080 allow { 127.0.0.1; };
};
# 获取 XML 格式统计数据
curl http://127.0.0.1:8080/xml/v3/server
# 使用 rndc 命令行统计
rndc stats
cat /var/named/data/named_stats.txt
12.2 关键监控指标
| 指标 | 说明 | 告警阈值 |
|---|---|---|
| Query Rate (QPS) | 每秒查询数 | 突增 > 500% 告警 |
| Cache Hit Rate | 缓存命中率 | < 60% 告警 |
| Recursive Clients | 当前递归查询数 | > recursive-clients 的 80% |
| SERVFAIL Rate | 解析失败率 | > 1% 告警 |
| Zone Transfer Failures | 区域传送失败次数 | > 0 告警 |
12.3 Prometheus + Grafana 集成
# 安装 bind_exporter
wget https://github.com/prometheus-community/bind_exporter/releases/latest/download/bind_exporter-linux-amd64
chmod +x bind_exporter-linux-amd64
./bind_exporter-linux-amd64 --bind.stats-url="http://127.0.0.1:8080/"
# prometheus.yml 抓取配置
# - job_name: 'bind9'
# static_configs:
# - targets: ['localhost:9119']
12.4 日志分析常用命令
# 查看查询最多的域名 Top 20
grep "query:" /var/log/named/query.log \
| awk '{print $6}' \
| sort | uniq -c | sort -rn | head -20
# 查看 NXDOMAIN 记录(可能的恶意域名探测)
grep "NXDOMAIN" /var/log/named/query.log | awk '{print $6}' \
| sort | uniq -c | sort -rn | head -20
# 查看来源 IP Top 10
grep "query:" /var/log/named/query.log \
| awk '{print $5}' | cut -d'#' -f1 \
| sort | uniq -c | sort -rn | head -10
13. 故障排查
13.1 常用诊断工具
| 工具 | 用途 | 典型命令 |
|---|---|---|
dig |
最强 DNS 查询工具 | dig @dns-ip domain A +trace |
nslookup |
交互式查询 | nslookup domain dns-ip |
host |
简洁查询 | host domain dns-ip |
rndc |
BIND 管理 | rndc status / rndc flush |
tcpdump |
抓包分析 | tcpdump -i eth0 port 53 |
dnstracer |
追踪完整解析链 | dnstracer -s . domain |
13.2 常见问题排查
❶ 域名解析失败(SERVFAIL)
# 1. 检查 named 是否运行
systemctl status named
# 2. 检查配置语法
named-checkconf && named-checkzone example.com /var/named/zones/db.example.com
# 3. 测试上游转发
dig @1.1.1.1 example.com
# 4. 检查防火墙
firewall-cmd --list-all | grep 53
iptables -L -n | grep 53
# 5. 查看错误日志
journalctl -u named -p err --since "1 hour ago"
❷ 区域传送失败
# 在从服务器手动触发传送并查看详情
dig @192.168.1.53 example.com AXFR
# 检查主服务器 allow-transfer 配置
grep -A3 "allow-transfer" /etc/named/named.conf.local
# 查看 named 安全日志
grep "transfer" /var/log/named/named.log
❸ 缓存投毒/返回错误结果
# 立即清除全部缓存
rndc flush
# 清除指定域名缓存
rndc flushname example.com
# Unbound 清除缓存
unbound-control flush example.com
unbound-control flush_zone example.com
❹ DNS 解析延迟高
# 测量解析时间
dig @192.168.1.53 www.example.com | grep "Query time"
# 检查缓存命中率
rndc stats && grep "cache hits\|cache misses" /var/named/data/named_stats.txt
# 检查上游 DNS 响应时间
for dns in 114.114.114.114 1.1.1.1 8.8.8.8; do
echo -n "$dns: "
dig @$dns baidu.com +stats 2>&1 | grep "Query time"
done
13.3 故障排查流程图
客户端无法解析域名
│
▼
本机 DNS 设置是否正确?
cat /etc/resolv.conf
│ 正确
▼
ping DNS 服务器 IP 是否通?
│ 通
▼
dig @DNS-IP domain 是否有应答?
│
┌────┴────────────────────────┐
NXDOMAIN SERVFAIL/超时
│ │
域名记录不存在 DNS 服务故障
检查区域文件 检查 named 状态
检查转发配置
检查防火墙规则
14. 典型企业部署方案
方案一:中小企业(< 500 人)
架构:单台 BIND 9(转发模式) + dnsmasq 备用
┌────────────────────────────────┐
│ 内网 DNS 服务器 │
│ 192.168.1.53 │
│ ● BIND 9(转发模式) │
│ - 内部域 → 本地解析 │
│ - 外部域 → 114 / DNSPod │
│ ● dnsmasq(备用,端口 5353) │
└────────────────────────────────┘
关键配置要点:
forward first模式,上游用 114 + 阿里 DNS- 内网域名(
corp.local)配置本地 A 记录 - 客户端 DNS 填
192.168.1.53,备用填114.114.114.114
方案二:大中型企业(500~5000 人)
架构:Unbound 递归 + BIND 9 内部权威 + 主从高可用
外网
│
┌────▼──────────────────────────┐
│ Unbound 递归解析器(主/从) │
│ VIP: 192.168.1.50 │
│ 主: 192.168.1.51 │
│ 从: 192.168.1.52 │
│ ● 外部域 → DoT 加密转发 │
│ ● 内部域 → 条件转发至权威 │
└────────────────┬──────────────┘
│
┌────────────────▼──────────────┐
│ BIND 9 内部权威 DNS │
│ 主: 192.168.1.53 │
│ 从: 192.168.1.54 │
│ ● 管理 corp.local 等内网域 │
└───────────────────────────────┘
关键配置要点:
- Unbound + Keepalived VIP 确保高可用
- 外网 DNS 走 DoT(
853/tcp)加密 - BIND 9 内部权威与 AD 域集成
- 启用 RPZ 黑名单过滤恶意域名
方案三:隔离网络(Air-Gapped)
架构:BIND 9 纯本地权威,无外网转发
┌─────────────────────────────────┐
│ 全内网 BIND 9 DNS │
│ 主: 10.0.0.53 │
│ 从: 10.0.0.54 │
│ │
│ ● 管理所有内网域名 │
│ ● 无转发(forward none) │
│ ● 根区域指向内网镜像根服务器 │
└─────────────────────────────────┘
关键配置:
options {
// 禁止所有外部转发
forward none;
recursion yes;
allow-query { 10.0.0.0/8; };
allow-recursion { 10.0.0.0/8; };
// 使用内网镜像根服务器
root-delegation-only exclude { "LOCAL"; };
};
// 自定义根区域(指向内网镜像)
zone "." {
type hint;
file "/var/named/internal-root.hints";
};
附录
A. BIND 9 常用 rndc 命令速查
rndc status # 查看服务状态
rndc reload # 重载全部配置和区域
rndc reload zone # 仅重载指定区域
rndc flush # 清除全部缓存
rndc flushname name # 清除指定域名缓存
rndc stats # 输出统计信息
rndc dumpdb -cache # 导出缓存数据库
rndc retransfer zone # 立即重新传送指定区域
rndc freeze zone # 冻结动态更新(维护用)
rndc thaw zone # 解冻动态更新
B. dig 常用查询速查
# 基础查询
dig example.com # 默认 A 记录
dig example.com MX # MX 记录
dig example.com ANY # 所有记录
# 指定 DNS 服务器
dig @192.168.1.53 example.com A
# 追踪完整解析链
dig +trace example.com
# 简洁输出
dig +short example.com A
# 反向查询
dig -x 1.2.3.4
# DNSSEC 验证
dig +dnssec example.com A
# 批量查询(从文件)
dig -f domains.txt +short
# 查看 TCP 模式(调试)
dig +tcp @dns-ip example.com
C. 参考标准与文档
| 文档 | 说明 |
|---|---|
| RFC 1034 / RFC 1035 | DNS 核心规范(域名概念与实现) |
| RFC 2136 | DNS 动态更新(DDNS) |
| RFC 2181 | DNS 规范澄清 |
| RFC 3596 | DNS 的 IPv6 扩展(AAAA) |
| RFC 4033~4035 | DNSSEC 规范 |
| RFC 5625 | DNS 代理实现建议 |
| RFC 7766 | DNS over TCP 要求 |
| RFC 7858 | DNS over TLS(DoT) |
| RFC 8484 | DNS over HTTPS(DoH) |
| BIND 9 ARM | BIND 9 官方管理员参考手册 |
| Unbound 文档 | Unbound 官方文档 |
文档维护说明
本文档基于 BIND 9.18 LTS、Unbound 1.17、dnsmasq 2.89 编写,适用于 Linux(RHEL 8+ / Ubuntu 22.04+)及 Windows Server 2019/2022 环境。
如环境版本有差异,请参阅对应版本官方文档进行核对。