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/debugseverity 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主从通知
dnssecDNSSEC 相关
default以上未列出的默认汇总
general常规运行信息

⚠️ query_log 收不到日志?逐项排查(高频坑)

  1. queries category 未绑定:只定义了 channel 没写 category queries { query_log; }; —— channel 定义后必须在 category 中引用才会生效。
  2. querylog yes 未开启:部分版本/配置下需在 options 加 querylog yes;(9.x 新版默认 queries 记录,但显式开启更稳)。
  3. 文件权限/路径:named 以 named 用户运行,日志目录必须 chown named:namedchmod 可写;/var/log/named 创建后要授权:
       mkdir -p /var/log/named
       chown named:named /var/log/named
  4. 目录不存在file "/var/log/named/query.log"/var/log/named 没创建 → 静默失败,日志丢失。
  5. chroot 环境:启用 chroot(/var/named/chroot)后,配置里的路径是chroot 内的路径,真实文件在 /var/named/chroot/var/log/named/,两边要一致。
  6. severity 过滤:queries 是 info 级别,若 channel 设了 severity warning 会过滤掉。
  7. selinux 拦截(CentOS):named 写日志目录被 SELinux 拦截(audit2why 查看),执行:
       semanage fcontext -a -t named_log_t "/var/log/named(/.*)?"
       restorecon -Rv /var/log/named
  8. 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 failedallow-transfer 未放行 / 主服务器防火墙 / Serial 未变化
queries 日志不输出见第 8 章 logging 排查清单
修改 zone 后不生效Serial 未递增 / 未 reload / 缓存 TTL 未过期

实战建议:搭建一个「内网权威 + 递归转发」最小环境练手:一台主权威(view 分内外)、一台从服务器、一台递归缓存,配好 query 日志,跑通 dig/主从同步/日志分析全流程。

第 1 / 12 节