BIND 是什么
BIND(Berkeley Internet Name Domain) 是最广泛使用的 DNS 服务器软件,由 ISC(Internet Systems Consortium)维护,开源免费。
- BIND 9:长期主流版本(9.11/9.16/9.18/9.20 等),9.16 是长维护版本(LTS),9.18 支持 DNSSEC 自动化、DoT。
- 核心程序:
named(守护进程)、rndc(远程控制)、dig/named-checkconf/named-checkzone(诊断工具)。 - 典型用途:企业内网权威 DNS、外网权威 DNS、递归/转发缓存服务器、主从架构。
BIND 基本组件:
/etc/named.conf 主配置文件(或 /etc/bind/named.conf,Debian 系)
/var/named/ 区域数据文件目录(CentOS)
/etc/bind/ 配置目录(Debian/Ubuntu:named.conf + named.conf.local + named.conf.options)
/var/named/chroot/ chroot 沙箱目录(启用后所有路径都在其下)
/var/log/named/ 日志目录(常见自定义位置)安装 BIND
CentOS / RHEL / Rocky
yum install -y bind bind-utils
systemctl enable --now named
# 检查
named -v # 版本
systemctl status named
Debian / Ubuntu
apt update && apt install -y bind9 bind9utils bind9-doc
systemctl enable --now named
named -v
验证安装
# 默认监听与进程
ss -tlnp | grep 53
ps aux | grep named
# 语法检查工具可用性
named-checkconf -v
named-checkzone -v
安装后建议先做基础配置再启动,避免默认配置(全开放递归)直接暴露公网。
配置文件体系
BIND 9 主配置 named.conf 由三大顶级语句组成:
options { ... }; # 全局选项
logging { ... }; # 日志配置
zone "..." { ... }; # 区域声明(可多个)
CentOS 版结构(单文件):
/etc/named.conf # 主配置,include 下面两个
/etc/named.rfc1912.zones # 本地 zone 声明
/etc/named.root.key # 根密钥(DNSSEC)
/var/named/ # zone 数据文件
Debian 版结构(拆分为多个文件,默认在 /etc/bind/):
named.conf # 主配置(include 下面两个)
named.conf.options # options 段
named.conf.local # 本机 zone 声明
db.root # 根提示文件
db.127 / db.local # 回环 zone
include 机制:用 include "文件"; 拆分配置,便于管理。语法校验统一用 named-checkconf。
options 常用指令详解
options {
listen-on port 53 { any; }; # 监听接口(any=所有;可写 IP 列表)
listen-on-v6 port 53 { any; };
directory "/var/named"; # zone 文件默认目录
pid-file "/run/named/named.pid";
allow-query { any; }; # 谁能查询(any/localhost/内网段)
allow-recursion { 192.168.1.0/24; localhost; }; # 谁能递归
allow-transfer { none; }; # 谁能做区域传送(安全关键!)
recursion yes; # 是否提供递归(权威服设 no)
forwarders { 223.5.5.5; 119.29.29.29; }; # 转发到上游(如阿里/腾讯公共DNS)
forward only; # 只转发,不自己递归
dnssec-validation auto; # DNSSEC 自动校验
dnssec-enable yes;
max-cache-size 256m; # 递归缓存上限
max-cache-ttl 86400;
max-ncache-ttl 3600; # 负缓存上限
querylog yes; # 记录所有查询(生产建议配合日志配置用)
statistics-file "/var/named/named.stats";
version "not disclosed"; # 隐藏版本号(安全)
};
关键安全建议:
- 权威服务器:
recursion no;+allow-transfer { 从服务器IP; }(或 none) - 递归/转发服务器:
allow-recursion限制内网;转发器用国内公共 DNS 延迟低 - 不要把全开放递归暴露公网(易被利用做 DNS 放大攻击)
区域(zone)与区域文件
声明 zone
zone "example.com" IN {
type master; # 主权威
file "example.com.zone"; # 数据文件(相对 directory)
allow-transfer { 192.168.1.10; }; # 允许从服务器传送
notify yes; # 通知从服务器更新
};
正向区域文件示例 /var/named/example.com.zone
$TTL 3600
@ IN SOA ns1.example.com. admin.example.com. (
2026082501 ; Serial
7200 ; Refresh
3600 ; Retry
1209600 ; Expire
300 ) ; Negative TTL
; 权威服务器
IN NS ns1.example.com.
IN NS ns2.example.com.
; A 记录
ns1 IN A 192.168.1.10
ns2 IN A 192.168.1.11
www IN A 192.168.1.20
mail IN A 192.168.1.25
; 别名
blog IN CNAME www
; 邮件
IN MX 10 mail.example.com.
; TXT / SPF
IN TXT "v=spf1 mx -all"
书写要点:
- 未以点结尾的名字自动追加当前域名(
www=www.example.com.);完整域名要写末尾点。 @代表当前域名本身。- 每行记录 = 名字 + [TTL] + [IN] + 类型 + 数据。
- 修改后必须递增 Serial,否则从服务器/缓存不感知变更。
校验区域文件
named-checkzone example.com /var/named/example.com.zone
# zone example.com/IN: loaded serial 2026082501 ← 成功
named-checkconf # 主配置语法
systemctl reload named # 热重载(不中断服务)反向解析区域
反向解析把 IP 翻译成域名,用于邮件反垃圾、日志审计等。命名规则:IP 倒序 + in-addr.arpa。
声明
zone "1.168.192.in-addr.arpa" IN {
type master;
file "192.168.1.rev";
};
反向区域文件 /var/named/192.168.1.rev
$TTL 3600
@ IN SOA ns1.example.com. admin.example.com. (
2026082501 7200 3600 1209600 300 )
IN NS ns1.example.com.
IN NS ns2.example.com.
10 IN PTR ns1.example.com.
11 IN PTR ns2.example.com.
20 IN PTR www.example.com.
25 IN PTR mail.example.com.
校验
named-checkzone 1.168.192.in-addr.arpa /var/named/192.168.1.rev
# 查询测试
dig -x 192.168.1.20 @127.0.0.1
IPv6 反向使用 ip6.arpa,每 4 位十六进制为一段,较长,建议用脚本生成。
视图(view)—— 内外网分离解析
view 让同一服务器对不同来源返回不同结果(split-horizon DNS):
view "internal" {
match-clients { 192.168.0.0/16; localhost; }; # 内网客户端
recursion yes;
zone "example.com" IN {
type master;
file "example.com.internal.zone"; # 内网版(解析到内网 IP)
};
};
view "external" {
match-clients { any; }; # 外网客户端
recursion no;
zone "example.com" IN {
type master;
file "example.com.external.zone"; # 外网版(解析到公网 IP)
};
};
要点:
- 多个 view 是互斥匹配,第一个匹配的生效;顺序敏感(把更具体的放前面)。
- 所有 zone(含根提示、localhost)都要放在 view 内,否则会报
zone ... requires a view。 - 用
dig @服务器IP -b 内网IP模拟不同来源测试。
日志配置详解(重点)
BIND 日志由 logging 语句 控制,核心概念:channel(输出通道) + category(日志类别)。
基本结构
logging {
channel query_log {
file "/var/log/named/query.log" versions 5 size 50m;
severity info;
print-time yes;
print-severity yes;
print-category yes;
};
channel general_log {
file "/var/log/named/named.log" versions 3 size 20m;
severity info;
print-time yes;
};
category queries { query_log; };
category default { general_log; };
category query-errors { query_log; };
};
channel 指令详解
| 指令 | 说明 | 示例 |
|---|---|---|
file 路径 [versions N] [size 大小] | 输出到文件,支持版本轮转与大小切割 | file "q.log" versions 5 size 50m |
syslog 设施 | 输出到 syslog(如 daemon) | syslog daemon |
stderr / null | 输出到标准错误 / 丢弃 | null; |
severity 级别 | 过滤级别:critical/error/warning/notice/info/debug | severity info; |
print-time yes | 每条日志加时间戳 | print-time yes; |
print-category yes | 加日志类别名 | print-category yes; |
print-severity yes | 加级别名 | print-severity yes; |
category(类别)常用项
| 类别 | 记录内容 |
|---|---|
queries | 每一条收到的查询(解析日志主力) |
query-errors | 查询错误(如 refused、超时) |
update | 动态更新(nsupdate) |
transfer / xfer-in / xfer-out | 区域传送 |
notify | 主从通知 |
dnssec | DNSSEC 相关 |
default | 以上未列出的默认汇总 |
general | 常规运行信息 |
⚠️ query_log 收不到日志?逐项排查(高频坑)
- queries category 未绑定:只定义了 channel 没写
category queries { query_log; };—— channel 定义后必须在 category 中引用才会生效。 querylog yes未开启:部分版本/配置下需在 options 加querylog yes;(9.x 新版默认 queries 记录,但显式开启更稳)。- 文件权限/路径:named 以
named用户运行,日志目录必须chown named:named或chmod可写;/var/log/named创建后要授权:mkdir -p /var/log/named chown named:named /var/log/named - 目录不存在:
file "/var/log/named/query.log"但/var/log/named没创建 → 静默失败,日志丢失。 - chroot 环境:启用 chroot(
/var/named/chroot)后,配置里的路径是chroot 内的路径,真实文件在/var/named/chroot/var/log/named/,两边要一致。 - severity 过滤:queries 是 info 级别,若 channel 设了
severity warning会过滤掉。 - selinux 拦截(CentOS):named 写日志目录被 SELinux 拦截(
audit2why查看),执行:semanage fcontext -a -t named_log_t "/var/log/named(/.*)?" restorecon -Rv /var/log/named - syslog 转发链(结合 rsyslog 场景):
syslog daemon输出后由 rsyslog 转发,接收端没收到时查:rsyslog 是否加载了转发规则、目标端口(514 UDP)、防火墙、接收端 imudp 模块是否开启、以及logger -p daemon.info test打点验证链路。
改完日志配置后:named-checkconf && systemctl reload named(热生效)。
主从复制(区域传送)
架构:主服务器可写,从服务器只读副本,通过区域传送同步,保证高可用。
从服务器配置
zone "example.com" IN {
type slave;
file "slaves/example.com.zone"; # 存放传送来的副本
masters { 192.168.1.10; }; # 主服务器 IP
};
主服务器侧配合
zone "example.com" IN {
type master;
file "example.com.zone";
allow-transfer { 192.168.1.11; }; # 允许从服务器传送
notify yes; # 数据变化时通知从服务器
also-notify { 192.168.1.11; }; # 显式指定通知对象
};
校验主从同步
# 从服务器看传送日志
grep -i transfer /var/log/named/named.log
# 对比主从 Serial(必须一致才说明同步成功)
dig SOA example.com @主IP +short
dig SOA example.com @从IP +short
# 手动触发传送(主服务器上)
rndc notify example.com
关键规则:主服务器每次修改 zone 递增 Serial,从服务器检测到 Serial 变大才会拉取新数据 —— Serial 不增 = 永远不同步。
rndc 管理工具
rndc(Remote Name Daemon Control):远程控制 named 的命令行工具。
生成密钥与配置(rndc-confgen)
rndc-confgen -a -r /dev/urandom # 生成 /etc/rndc.key(自动)
systemctl restart named
常用命令
rndc status # 运行状态(版本/uptime/查询统计)
rndc reload # 重载配置与 zone(热生效)
rndc reload example.com # 重载单个 zone
rndc flush # 清空所有缓存
rndc flushname example.com # 清空某域名缓存
rndc notify example.com # 发送 notify
rndc stats # 输出统计到 statistics-file
rndc stop # 停止
rndc reconfig # 重新读取配置
rndc querylog # 开关查询日志(调试利器)安全加固
基础防护
options {
recursion no; # 权威服关递归
allow-query { any; }; # 查询范围按需收窄
allow-transfer { none; }; # 禁区域传送(防信息泄露)
allow-update { none; }; # 禁动态更新
version "not disclosed"; # 隐藏版本
};
防 DNS 放大攻击:确保递归只对内网(allow-recursion),公网请求全部 REFUSED。
限速(RRL,Response Rate Limiting):BIND 9.11+ 防反射/放大攻击:
options { rate-limit { responses-per-second 5; }; };
DNSSEC:为权威区签名(dnssec-signzone 或 9.18 的 dnssec-policy 自动化),让解析端可校验数据真实性:
# 生成密钥
dnssec-keygen -a ECDSAP256SHA256 -n ZONE example.com
# 签名(生成 .signed 文件)后 zone 指向签名文件
dnssec-signzone -o example.com example.com.zone Kexample.com.*.key
chroot 隔离(可选,Debian 默认 /var/named/chroot):named 运行在受限根目录,降低被攻破后影响。
防火墙:仅对公网开放 UDP/TCP 53(DNS),其他端口最小化;firewall-cmd/ufw 配置。
日志与监控:开启 queries 日志 + 定期分析(qlogstats、dnstop),异常查询量预警;配合 fail2ban 拦截扫描 IP。
故障排查与性能
配置/语法校验(每次改动必做)
named-checkconf # 主配置
named-checkzone example.com /var/named/example.com.zone # 区域文件
启动失败排查
journalctl -u named -n 50 # systemd 日志
named -g # 前台运行看输出(调试)
# 常见报错:
# - "could not open ... permission denied" → 权限/SELinux
# - "no longer listening on ..." → 端口被占用
# - "zone ... requires a view" → 根提示/localhost zone 没放 view 内
解析测试三板斧
dig www.example.com @127.0.0.1 # 本机权威
dig www.example.com @从服务器IP # 从服务器一致性
dig www.example.com +trace # 全链路
dig -x 192.168.1.20 @127.0.0.1 # 反向
性能关注点
- 查询量评估:
rndc stats看 QUERY 数、cache 命中率。 - worker 线程:
options { threads N; }(现代版自动)。 - 缓存命中:递归服缓存越大命中越高,
max-cache-size合理上调。 - 响应大小:EDNS0(
edns-udp-size)避免 TCP 回退。 - 监控:用
rndc status/dnstop/dnsperf观察吞吐;日志按天轮转防爆盘。
常见故障速查
| 现象 | 定位 |
|---|---|
rndc status 连接失败 | rndc.key 不匹配 / 控制端口 953 被防火墙拦 |
| 权威解析正常但外网慢 | 递归服缓存、上游递归链路、TTL 太短 |
从服务器日志报 transfer failed | allow-transfer 未放行 / 主服务器防火墙 / Serial 未变化 |
| queries 日志不输出 | 见第 8 章 logging 排查清单 |
| 修改 zone 后不生效 | Serial 未递增 / 未 reload / 缓存 TTL 未过期 |
实战建议:搭建一个「内网权威 + 递归转发」最小环境练手:一台主权威(view 分内外)、一台从服务器、一台递归缓存,配好 query 日志,跑通 dig/主从同步/日志分析全流程。