DNS 域名解析服务(BIND)

本文合并自:04-DNS域名解析服务.md、12-DNS服务.md、1-10-DNS服务部署.md

适用环境:CentOS/RHEL 6(BIND 9.8)与 CentOS/RHEL 7(BIND 9.9)。两个版本在配置文件语法上基本一致,差异主要体现在服务管理命令与防火墙组件上,文中凡有差异处均并列给出并标注适用版本。

本章要点

  • 理解域名、DNS 的作用,以及正向解析与反向解析的区别。
  • 了解域名的分层(根域、顶级域、二级域、子域)与命名规则。
  • 理解递归查询与迭代查询的区别及一次完整的域名解析过程。
  • 能够安装 BIND(bind、bind-utils、bind-chroot 等),认识相关配置文件与工具。
  • 掌握主配置文件 /etc/named.conf、区域声明文件 /etc/named.rfc1912.zones 与区域数据库文件的写法。
  • 掌握 SOA、NS、A、AAAA、CNAME、MX、PTR、TXT/SPF、SRV 等资源记录,以及 $GENERATE、裸域、泛解析的写法。
  • 能够配置主 DNS、从 DNS(主从同步)、转发型域、缓存型 DNS、子域授权、视图(智能解析)。
  • 掌握 dig、host、nslookup、whois、rndc 等工具与常见排错方法。

一、DNS 概述与原理

1.1 什么是域名

域名(Domain Name)是网站在互联网上的地址标识,用于替代难以记忆的 IP 地址。通俗地说,域名相当于一个家庭的门牌号码,别人通过这个号码可以很容易地找到并访问到网站。域名具有全球唯一性,在全世界没有重复的域名,是用户访问网络资源的重要入口。域名在网络上被戏称为"玉米"。

1.2 什么是 DNS

DNS(Domain Name System,域名系统)负责在域名与 IP 地址之间进行转换,相当于互联网的"翻译器",在文字和 IP 之间担当翻译,免除人们强记号码的痛苦。例如把 www.baidu.com、www.taobao.com 这类容易记忆的名字翻译成实际通信要用的 IP 地址。

DNS 的特点:

  1. 是一个分布式数据库(数据分散存放在全球无数台服务器上,没有任何一台服务器保存全部数据);
  2. 解决数据不一致问题,避免名字冲突(每个域的数据由该域的权威服务器负责);
  3. 有缓存机制,提高性能和可靠性;
  4. 采用分层(树状)结构,理论上最多 127 层。

1.3 正向解析与反向解析

类型 说明 示例
正向解析 将域名解析为 IP 地址 www.example.com → 192.168.1.10
反向解析 将 IP 地址解析为域名 192.168.1.10 → www.example.com

反向解析常用于邮件服务器的身份校验(例如判断邮件是否真的来自其声称的域),也用于日志审计、访问控制等场景。

1.4 主机名与域名的区别

概念 范围 说明
主机名(Hostname) 私有网络内部 局域网内识别某台主机的名称,如 web-server
域名(Domain Name) 全球互联网 在互联网上全局唯一,如 www.example.com

两者可以完全不同,但很多软件(如 postfix)默认认为它们是一致的,因此生产环境中通常会把主机名设置成与域名相符的形式。

1.5 域名的结构与分层

DNS 是一棵倒置的树,从右向左逐级细分:

                        .  (根域 root)
        ┌───────────────┼───────────────┐
      com              cn              org      ← 顶级域 TLD
        │           ┌───┴───┐
      baidu       com     edu                   ← 二级域
        │           │       │
   ┌────┴────┐    icbc    pku
  www    zhidao                                 ← 主机名 / 子域
              │
             abc                                ← 三级子域

1.5.1 根域

  • 根域用一个点 . 表示,位于域名空间的最顶层。
  • 全球共有 13 组根域服务器(编号 a~m),它们的地址被固化在 BIND 的 /var/named/named.ca 文件中(称为"根提示"文件)。
  • 根服务器本身不保存具体主机记录,只负责告诉查询者"某个顶级域该找谁"。

1.5.2 顶级域(TLD)

国际顶级域名(gTLD,generic Top-Level Domain;早期资料也称 iTDs,international top-level domain-names),使用最早也最广泛:

后缀 用途/含义
.com 商业机构
.net 网络服务提供商、通讯
.org 非营利性组织
.edu 教育机构
.gov 政府机构
.mil 军事机构
.info 信息服务

国家/地区顶级域名(ccTLD,country code Top-Level Domain;早期资料也称 nTLDs,national top-level domain-names),目前 200 多个国家和地区按 ISO 3166 国家代码分配:

后缀 国家/地区
.cn 中国
.us 美国
.jp 日本
.tw 台湾
.hk 香港
.la 老挝
.ca 加拿大
.co 哥伦比亚
.it 意大利
.tt 特立尼达和多巴哥
.kr 韩国
.in 印度

在实际使用和功能上,国际域名与国内域名没有任何区别,都是互联网上具有唯一性的标识,只是最终管理机构不同:

  • 国际域名由美国商业部授权的 ICANN(The Internet Corporation for Assigned Names and Numbers,互联网名称与数字地址分配机构)负责注册和管理。
  • 国内域名由 CNNIC(China Internet Network Information Center,中国互联网络信息中心)负责注册和管理。

1.5.3 域名级别

级别 说明 示例
顶级域(TLD) 域名最右侧部分 .com、.cn
二级域 在顶级域前再加一级,常用于国内组合域名 com.cn、net.us、edu.cn、gov.cn、icbc.com.cn、www.net.cn、www.gov.cn、www.pku.edu.cn
子域 在二级域前继续细分 www.baidu.com、zhidao.baidu.com
三级子域 继续向下细分 abc.zhidao.baidu.com

示例解读:

  • baidu.com:顶级域为 .com,baidu 为二级域(在很多资料中也把 baidu.com 整体称为"顶级域名",即用户注册得到的那一级)。
  • www.baidu.com:www 为主机名,整体是 baidu.com 的子域名。
  • abc.zhidao.baidu.com:abc 为三级子域。

1.5.4 FQDN 与末尾的点

FQDN(Fully Qualified Domain Name,完全限定域名)是从主机名一直写到根的完整名称,末尾必须带一个点,例如:

www.cluster.com.
└─ 主机名 ─┘└─域─┘└─ 根

在区域文件中书写记录时这一点非常关键:

  • 写 www.cluster.com.(带点)→ 表示这是一个 FQDN,按字面解析。
  • 写 www.cluster.com(不带点)→ BIND 会自动在其后补上当前区域名($ORIGIN),变成 www.cluster.com.cluster.com.,这是最常见的配置错误之一。
  • 写 www(相对名)→ 自动补全为 www.cluster.com.,这是推荐的简写方式。

结论:要么写纯相对名(如 www),要么写完整 FQDN 并带上结尾的点,不要写"半截"名字。

1.6 域名的命名规则

  1. 可用字符:
    • 26 个英文字母(a~z),不区分大小写;
    • 数字 0~9;
    • 中横线/连字符 -。
  2. 组合规则:
    • 英文字母不区分大小写;
    • 域名长度有一定限制(单个标签最长 63 字符,整个 FQDN 最长 255 字符);
    • 一些特定/保留词汇不能注册;
    • 注册有年限,到期需续费。
  3. 好域名具备的特点:
    • 短小、简短易记;
    • 不易混淆、不易拼写错误;
    • 与公司名称或核心业务相关;
    • 尽量不与文化相冲突。

1.7 DNS 查询的类型

DNS 查询分为递归查询和迭代查询:

查询类型 发起方 特点
递归查询(Recursive) DNS 客户端 → DNS 服务器 客户端只发一次请求,服务器负责把事情办到底:要么返回最终的资源记录,要么返回"资源不存在"的错误信息,不会把中间的 referral(下一级服务器地址)丢回给客户端。
迭代查询(Iterative) DNS 服务器 → 其他 DNS 服务器 允许被查询的服务器返回它所能给出的最好答案:如果没有恰好匹配的资源,就回复另外一个(下一级)DNS 服务器的地址,由查询方再向这个新服务器发起新的查询,逐级追问。

典型场景:客户端向本地 DNS 服务器发起递归查询;本地 DNS 服务器为了完成这个递归请求,依次向根域、顶级域、权威域服务器发起迭代查询,最终获得结果后返回给客户端。

1.8 一次完整的域名解析全过程

以下以解析 mail.google.com 为例,说明完整的递归/迭代查询过程(不考虑缓存):

                        迭代查询
                           |
                           |
                     ______|______
                    /             \
    +-------------+                 +-------------+
    |             | ------ 2 ---->  |    root(.)  |
    |             | <----- 3 -----  | Name Server |
    |             |                 +-------------+
    |             |                 +-------------+
    |     NS1     | ------ 4 ---->  |    com      |
    |             | <----- 5 -----  | Name Server |
    |             |                 +-------------+
    |             |                 +-------------+
    |             | ------ 6 ---->  |   google    |
    |             | <----- 7 -----  | Name Server |
    +-------------+                 +-------------+
         ^  |     \
         |  |      |
         1  8      |--- 递归查询
         |  |      |
         |  v     /
    +-------------+
    |             |
    |   Resolver  |
    |             |
    +-------------+

步骤说明:

  1. 客户端(Resolver)向本地 DNS 服务器 NS1 发起递归查询,请求 mail.google.com 的 IP 地址,NS1 必须回复答案或错误信息。
  2. NS1 没有相关记录(也没有缓存),于是联系根域服务器查询,使用迭代查询。
  3. 根域服务器没有相关主机记录,向 NS1 回复 com 域服务器的联系方式(NS 记录 + 对应的 A 记录,即"胶水记录")。
  4. NS1 联系 com 域服务器查询,使用迭代查询。
  5. com 域服务器没有相关记录,向 NS1 回复 google.com 域服务器的联系方式。
  6. NS1 联系 google.com 域服务器查询,使用迭代查询。
  7. google.com 域服务器是该域的权威服务器,有相关记录,向 NS1 回复 mail.google.com 的 IP 地址(权威回答)。
  8. NS1 把 mail.google.com 的 IP 地址返回给客户端 Resolver,同时把结果按 TTL 存入自己的缓存。

从客户端视角看只有第 1、8 两步;中间 2~7 步全部由本地 DNS 服务器代劳,这就是递归与迭代的分工。

1.9 DNS 使用的端口与协议

协议端口 用途
UDP 53 客户端查询 DNS 记录(绝大多数普通查询走 UDP,开销小、速度快)
TCP 53 主从 DNS 服务器之间的区域传送(zone transfer,同步区域数据);当应答报文超过 512 字节被截断(TC 标志置位)时,客户端也会改用 TCP 重试

因此在防火墙上放行 DNS 时,UDP 53 与 TCP 53 都要放行,否则会出现"普通查询正常但主从同步失败"或"大应答查询失败"的现象。

1.10 缓存与 TTL

  • DNS 服务器与客户端都会缓存查询结果,缓存的有效期由记录的 TTL(Time To Live,生存时间)决定,单位为秒。
  • 区域文件开头的 $TTL 指令为本区域所有记录设置默认 TTL;单条记录也可以在名字后单独指定 TTL 覆盖默认值。
  • TTL 设置的权衡:
    • TTL 越大 → 缓存命中率越高、上游查询压力越小,但记录变更后生效越慢;
    • TTL 越小 → 变更生效快(适合准备迁移 IP 时提前调小),但查询压力大。
  • 计划变更记录时的常规做法:提前 1~2 天把该记录的 TTL 调小(如 60 秒),变更完成并稳定后再调回正常值(如 3600 或 86400)。
  • 清空 BIND 自身的缓存:
rndc flush              # 清空全部缓存
rndc flushname www.abc.com   # 只清空某个名字的缓存(BIND 9.6+)
  • 客户端侧的缓存:Windows 用 ipconfig /flushdns;Linux 上如果运行了 nscd 或 systemd-resolved,需分别用 nscd -i hosts 或 systemd-resolve --flush-caches 清理。

1.11 hosts 文件与 DNS 的优先级

Linux 系统中名称解析的顺序由 /etc/nsswitch.conf 控制:

hosts:      files dns
  • files 表示 /etc/hosts 文件;
  • dns 表示通过 /etc/resolv.conf 中指定的 DNS 服务器查询。

上面的默认配置表示:先查 /etc/hosts,查不到再查 DNS。因此本机 /etc/hosts 中的记录优先级高于 DNS,可以用它做临时的、只对本机生效的解析覆盖(测试、临时切流量非常常用)。

/etc/hosts 格式:

127.0.0.1   localhost localhost.localdomain
192.168.0.183  dns.abc.com dns
192.168.0.222  web.abc.com web

如果把顺序改成 hosts: dns files,则会先查 DNS 再查 hosts,一般不建议改动。

1.12 客户端 DNS 配置:/etc/resolv.conf

Linux 系统里客户端使用的 DNS 服务器写在 /etc/resolv.conf 中,最多可以写三个(超过 3 条的 nameserver 不生效):

vim /etc/resolv.conf
nameserver 8.8.8.8
nameserver 223.5.5.5
nameserver 192.168.0.1
search abc.com          # 可选:搜索域,输入短名时自动补全该后缀
options timeout:2 attempts:2   # 可选:单个服务器超时秒数与重试次数

工作方式:默认使用第一个 nameserver;只有当第一个服务器无响应(超时)时才依次尝试后面的服务器。注意——如果第一个服务器有响应但答复"无此记录"(NXDOMAIN),解析器不会再去问第二个服务器。

常用公共/运营商 DNS 参考:

地址 说明
8.8.8.8 / 8.8.4.4 Google Public DNS
223.5.5.5 / 223.6.6.6 阿里公共 DNS
114.114.114.114 114DNS
202.96.134.133 深圳电信首选 DNS
202.96.128.86 深圳电信备选 DNS

提示:在 CentOS 6/7 上,如果网卡配置文件 /etc/sysconfig/network-scripts/ifcfg-ethX 中写了 DNS1=、DNS2=,或启用了 NetworkManager/dhclient,重启网络后 /etc/resolv.conf 可能被自动覆盖。要固定手写内容,可在网卡配置中设置 PEERDNS=no,或直接把 DNS 写进网卡配置文件。


二、DNS 服务器类型与 BIND 安装配置

2.1 DNS 服务器的角色类型

类型 区域 type 作用与应用场景
主 DNS(master / primary) master 主要负责 DNS 域名解析的服务器,区域数据由管理员手动维护,是该域数据的唯一源头
从 DNS(slave / secondary) slave 主 DNS 的备份,区域数据被动从主服务器同步(区域传送),主挂掉后接替提供解析,避免单点故障,同时分担查询压力
缓存 DNS(caching-only) 无本域区域 不维护任何权威区域,只把经常解析的域名缓存起来,实现快速解析、节约网络带宽,适合企业局域网
转发 DNS(forwarding) forward 当本服务器没有需要解析的域名数据时,把请求转发给其他 DNS 服务器进行解析,可对单个域转发,也可全局转发
根提示(hint) hint 不是一种独立部署角色,而是每台递归服务器都需要的"根线索"区域,指向 named.ca 中的 13 组根服务器,用于开始迭代查询

主从关系示意:

10.0.0.2 (主)  --------  10.0.0.61 (从)
type master             type slave
手动维护 zone 文件       被动从主同步 zone 文件

2.2 BIND 简介

BIND(Berkeley Internet Name Domain)是 Linux/UNIX 上最常用的 DNS 服务软件,由 ISC 维护,其守护进程名为 named。

2.3 安装 BIND

安装 BIND 及相关组件:

# 精确安装(推荐)
sudo yum install bind-libs bind-utils bind bind-chroot -y

# 或者一次性装全(RHEL 6 教学环境常用写法)
yum install bind* -y
包名 说明
bind BIND DNS 服务器主程序(提供 named)
bind-libs BIND 运行所需的库文件
bind-utils DNS 测试与调试工具(dig、host、nslookup、nsupdate)
bind-chroot 提供 chroot(牢笼)环境,把 named 关进 /var/named/chroot,增强服务安全性
bind-dyndb-ldap 将区域数据存放到 LDAP 的后端插件(可选)

查看已安装的包:

rpm -qa | grep ^bind-
# bind-utils-9.8.2-0.10.rc1.el6.x86_64
# bind-chroot-9.8.2-0.10.rc1.el6.x86_64
# bind-libs-9.8.2-0.10.rc1.el6.x86_64
# bind-9.8.2-0.10.rc1.el6.x86_64
# bind-dyndb-ldap-1.1.0-0.9.b1.el6.x86_64

bind-utils 包含的常用工具:

rpm -ql bind-utils
工具路径 说明
/usr/bin/dig 最常用的 DNS 服务器测试工具,输出信息最详细
/usr/bin/host 轻量级 DNS 测试工具
/usr/bin/nslookup DNS 查询工具,交互/非交互均可,众多平台都有实现(Windows 上也有)
/usr/bin/nsupdate 动态更新 DNS 记录的工具

2.4 BIND 的主要配置文件

rpm -qc bind
文件路径 说明
/etc/named.conf BIND 主配置文件
/etc/named.rfc1912.zones 区域声明文件,通过主配置文件中的 include 指令被引用;自定义区域通常写在这里
/etc/named.root.key 根区域的 DNSSEC 事务签名密钥文件
/etc/rndc.conf rndc(远程名称服务器控制器)配置文件
/etc/rndc.key rndc 加密密钥
/etc/sysconfig/named named 服务的启动环境变量配置(sysconfig)
/etc/logrotate.d/named 日志轮转配置
/var/named/ 区域数据文件默认存放目录(directory 指定)
/var/named/named.ca 13 组根 DNS 服务器列表(根提示文件)
/var/named/named.empty 空区域文件模板
/var/named/named.localhost localhost 正向区域文件模板
/var/named/named.loopback loopback(回环地址)反向区域文件模板
/var/named/data/ 主区域数据文件、缓存转储与统计文件目录
/var/named/slaves/ 从服务器自动生成的区域文件存放目录
/var/named/dynamic/ 动态更新与托管密钥目录
/usr/share/doc/bind-9.8.2/、/usr/share/doc/bind*/sample/ 官方配置样例目录

2.5 chroot 环境说明

安装 bind-chroot 后,named 会被"关进笼子",其根目录变为 /var/named/chroot/:

是否安装 bind-chroot 主配置文件 数据文件目录
未安装 /etc/named.conf /var/named/
已安装 /var/named/chroot/etc/named.conf(默认为空) /var/named/chroot/var/named/
ls /var/named/chroot/etc/
# localtime  rndc.key

ls /var/named/chroot/var/named/
# data  slaves

ls /var/named/chroot/var/named/data/     # 存放主 zone 文件
ls /var/named/chroot/var/named/slaves/   # 存放从 zone 文件

重要:在 RHEL 6/7 中,仍然按常规路径编辑 /etc/named.conf 和 /var/named/ 下的文件即可,重启服务时启动脚本会自动把这些文件硬链接/挂载到 chroot 对应位置。不要直接去改 chroot 里的空文件。配置模板可参考 /etc/named.conf 自带注释或 /usr/share/doc/bind-9.8.2/。

chroot 的意义:即使 named 进程被攻破,攻击者也只能看到 /var/named/chroot 这个"假根"下的内容,无法访问真实根文件系统,从而降低危害。

2.6 主配置文件 /etc/named.conf 详解

CentOS 6/7 的默认配置(语法相同):

//
// named.conf
//
options {
    listen-on port 53 { any; };                    // 监听的 IPv4 地址与端口
    listen-on-v6 port 53 { ::1; };                 // 监听的 IPv6 地址与端口
    directory       "/var/named";                  // 工作目录(后续相对路径的基准)
    dump-file       "/var/named/data/cache_dump.db";      // rndc dumpdb 缓存转储文件
    statistics-file "/var/named/data/named_stats.txt";    // rndc stats 统计输出文件
    memstatistics-file "/var/named/data/named_mem_stats.txt";  // 内存统计文件
    allow-query     { any; };                      // 允许查询的客户端
    recursion yes;                                 // 是否开启递归查询

    dnssec-enable yes;                             // 是否启用 DNSSEC
    dnssec-validation yes;                         // 是否对上游应答做 DNSSEC 验证

    bindkeys-file "/etc/named.iscdlv.key";         // ISC DLV key 路径
    managed-keys-directory "/var/named/dynamic";   // 自动管理的密钥目录
};

logging {
    channel default_debug {
        file "data/named.run";                     // 相对 directory,即 /var/named/data/named.run
        severity dynamic;                          // 日志级别随 rndc trace 动态变化
    };
};

zone "." IN {                                      // 根提示区域
    type hint;
    file "named.ca";
};

include "/etc/named.rfc1912.zones";                // 引入区域声明文件
include "/etc/named.root.key";                     // 引入根密钥

2.6.1 options 段常用配置项

配置项 说明
listen-on port 53 { ... }; 指定 named 监听的本机 IPv4 地址。默认只有 127.0.0.1,必须改为 any(或写具体网卡 IP)才能对外提供服务
listen-on-v6 port 53 { ... }; 指定监听的 IPv6 地址;不使用 IPv6 时可写 { ::1; } 或整行注释
directory "/var/named"; 工作目录,file、dump-file 等相对路径都以此为基准
dump-file 执行 rndc dumpdb 时缓存内容转储到的文件
statistics-file 执行 rndc stats 时统计信息输出的文件
memstatistics-file 退出时内存使用统计输出的文件
allow-query { any; }; 允许哪些客户端向本服务器查询。默认 localhost,需改为 any 或具体网段(如 { 192.168.0.0/24; localhost; })
allow-transfer { ... }; 允许哪些主机做区域传送(把整个区域数据拉走)。默认允许所有,生产环境必须限制为从服务器 IP,否则整个域的主机清单会被外人一次性拖走
allow-recursion { ... }; 允许哪些客户端使用递归查询。对外提供权威解析的服务器应限制为内网网段,防止成为 DNS 放大攻击的反射器
allow-update { none; }; 允许哪些主机动态更新区域数据(DDNS)。不用则设为 none
recursion yes\|no; 是否为客户端提供递归服务。纯权威服务器建议 no,内网解析服务器需要 yes
forwarders { IP; IP; }; 全局转发器列表,本机查不到的记录转发给这些服务器,多个用分号分隔
forward only; 只转发,转发器无响应也不自己去问根(纯转发/缓存服务器用)
forward first; 先转发,转发器无响应时再自己向根做迭代查询(默认行为)
dnssec-enable yes\|no; 是否启用 DNSSEC 支持
dnssec-validation yes\|no; 是否验证上游应答的 DNSSEC 签名。实验环境/内网自建域常需设为 no,否则转发、递归可能因验证失败而返回 SERVFAIL
version "none"; 隐藏 BIND 版本号(安全加固,避免被针对性攻击)
max-cache-size、max-cache-ttl 限制缓存大小与缓存最长时间

2.6.2 logging 段

logging {
    channel default_debug {
        file "data/named.run";
        severity dynamic;
    };
    // 单独记录查询日志的通道
    channel query_log {
        file "data/query.log" versions 3 size 20m;   // 保留 3 个历史文件,单个最大 20MB
        severity info;
        print-time yes;                              // 打印时间戳
        print-category yes;                          // 打印日志类别
    };
    category queries { query_log; };                 // 把 queries 类别写入上面的通道
};
  • channel 定义"日志往哪写、写多详细";category 定义"哪类日志走哪个通道"。
  • 常用 category:default、general、queries(查询日志)、security、xfer-in / xfer-out(区域传送)、notify、lame-servers。
  • severity 由低到高:debug < info < notice < warning < error < critical;dynamic 表示跟随 rndc trace 的调试级别变化。

2.6.3 zone 段

zone "cluster.com" IN {
    type master;                            // master / slave / forward / hint / stub
    file "data/master.cluster.com.zone";    // 区域数据文件(相对 directory)
    allow-transfer { 10.0.0.61; };          // 只允许指定从服务器传送本区域
    allow-update { none; };                 // 不允许动态更新
    notify yes;                             // 数据变更后主动通知从服务器
    also-notify { 10.0.0.61; };             // 除 NS 记录中的从服务器外,额外通知的地址
};

zone "cluster.com" IN {
    type slave;                             // 从服务器上的写法
    file "slaves/slave.cluster.com.zone";   // 同步下来的文件自动生成在此
    masters { 10.0.0.2; };                  // 指明从哪个主服务器同步
};
配置项 说明
type master 本机是该区域的主服务器,数据文件手工维护
type slave 本机是该区域的从服务器,需配合 masters
type forward 该区域的查询转发给 forwarders 指定的服务器
type hint 根提示区域,仅用于 zone "."
type stub 只同步对方区域的 NS 记录(少用)
file 区域数据文件路径,相对于 directory
masters { IP; }; 从区域的数据来源(主服务器地址)
allow-update 允许动态更新的主机
allow-transfer 允许区域传送的主机
notify yes\|no; 主服务器区域数据变化时是否立刻通知从服务器

2.6.4 include 与 /etc/named.rfc1912.zones

主配置文件末尾用 include 引入其他文件,使配置模块化:

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

/etc/named.rfc1912.zones 中预置了 RFC 1912 建议的本地区域(localhost、localhost.localdomain、1.0.0.127.in-addr.arpa 等),自定义的正向/反向区域一般追加在这个文件末尾(也可以直接写在 named.conf 里,效果相同)。

2.7 语法检查:named-checkconf

修改配置后先检查再重启,这是避免服务起不来的最有效习惯:

named-checkconf                      # 检查 /etc/named.conf(无输出即语法正确)
named-checkconf /etc/named.rfc1912.zones   # 检查指定文件
named-checkconf -z                   # 同时加载并检查所有主区域文件

常见语法错误:缺少行尾分号 ;、括号不匹配、注释符写错(//、#、/* */ 都合法,但不能用 --)。


三、区域文件详解与主 DNS 服务器搭建

3.1 区域文件位置与模板

  • 区域数据文件默认放在 directory 指定的 /var/named/ 下;教学与生产中常用两个子目录:
    • /var/named/data/:存放主区域(master)数据文件;
    • /var/named/slaves/:存放从区域(slave)自动同步下来的文件。
  • 可用的模板文件:
    • /var/named/named.localhost:正向区域模板;
    • /var/named/named.loopback:反向区域模板;
    • /var/named/named.empty:空区域模板。

复制模板时必须用 cp -p(或 cp -a)保留权限与属主,否则 named 可能读不到文件:

cd /var/named
cp -p named.localhost data/master.abc.com.zone
cp -p named.loopback  data/master.0.168.192.in-addr.arpa.zone

3.2 区域文件的组成

一个区域文件由指令(以 $ 开头)和资源记录(RR,Resource Record)组成。

资源记录的通用格式:

[name]   [TTL]   IN   <TYPE>   <VALUE>
  • name:记录名。写相对名(如 www)会自动补上 $ORIGIN;写 FQDN 必须以 . 结尾;留空表示沿用上一条记录的名字。
  • TTL:可选,缺省使用 $TTL 的值。
  • IN:类别(Internet),几乎总是 IN。
  • TYPE:记录类型(SOA/NS/A/CNAME/MX/PTR/TXT/SRV…)。
  • VALUE:记录值。
  • ; 之后为注释。

3.2.1 $TTL

$TTL 3600        ; 本区域所有记录的默认生存时间(秒),即一条记录在别处缓存的最长有效时间

也可写成带单位的形式:$TTL 1D(1 天)、$TTL 1H、$TTL 1W。

3.2.2 $ORIGIN

$ORIGIN cluster.com.     ; 定义当前区域原点,之后所有相对名都补这个后缀

如果没有显式写 $ORIGIN,BIND 会默认使用 named.conf 中 zone 声明的区域名作为原点。因此绝大多数区域文件不写 $ORIGIN 也能正常工作。

3.2.3 @ 符号

@ 是当前 $ORIGIN(即区域名)的简写。例如在 cluster.com 区域中:

@   IN  SOA ...     ; 等价于  cluster.com.  IN  SOA ...
@   IN  A   192.168.0.1   ; 等价于对裸域 cluster.com 做 A 解析

3.2.4 $GENERATE

批量生成一段连续范围的资源记录,$ 代表当前循环值:

$GENERATE 201-254 host$  IN  A   192.168.1.$      ; 生成 host201→192.168.1.201 ... host254→192.168.1.254
$GENERATE 100-180  $     IN  PTR host$.abc.com.   ; 反向:100→host100.abc.com. ... 180→host180.abc.com.

3.3 资源记录类型逐项详解

记录 全称 作用
SOA Start of Authority 起始授权记录,声明主 DNS、管理员邮箱及主从同步参数,每个区域文件的第一条记录且只能有一条
NS Name Server 域名服务器记录,指定本域的权威 DNS 服务器,可写多条
A Address 域名 → IPv4 地址
AAAA IPv6 Address 域名 → IPv6 地址
CNAME Canonical Name 别名记录,把一个域名重定向到另一个域名
MX Mail Exchange 邮件交换记录,指定本域的邮件服务器及优先级
PTR Pointer IP → 域名(反向解析专用)
TXT Text 文本记录,常用于 SPF、DKIM、域名所有权验证
SRV Service 服务记录,声明某服务所在的主机与端口
$GENERATE — 指令(非记录类型),批量生成连续范围的资源记录
@ — 代表当前区域原点(即裸域名,如 abc.com)
* — 通配符,匹配所有未明确定义的名字(泛解析)

3.3.1 SOA 记录及其七个字段

@   IN  SOA    ns.cluster.com.   root.cluster.com. (
            2013050801   ; ① serial   序列号(版本号)
            30           ; ② refresh  刷新间隔
            60           ; ③ retry    重试间隔
            90           ; ④ expire   过期时间
            3600 )       ; ⑤ minimum  最小 TTL / 否定回答缓存时间

前两个字段写在 SOA 之后、括号之前:

字段 示例 作用
主域名服务器 ns.cluster.com. 本区域的主(primary)DNS 服务器的 FQDN,必须以点结尾
管理员邮箱 root.cluster.com. 管理员邮箱地址。因为 @ 在区域文件中有特殊含义,所以把 root@cluster.com 写成 root.cluster.com.

括号中的五个数字(单位:秒,也可写 1D、3H 等):

序号 字段 作用
① serial(序列号/版本号) 区域数据的版本标识。从服务器靠比较序列号判断主服务器数据是否更新:主服务器序列号变大则触发区域传送。每次修改区域文件都必须手动递增该值,否则从服务器不会同步。通常用日期+序号格式 YYYYMMDDnn,如 2018051901
② refresh(刷新间隔) 从服务器主动联系主服务器检查序列号的时间间隔
③ retry(重试间隔) 从服务器联系主服务器失败后,重试的时间间隔(应小于 refresh)
④ expire(过期时间) 从服务器持续联系不上主服务器时,多久之后停止对外提供本区域的解析(认为数据彻底失效)
⑤ minimum(最小 TTL) 对否定回答(NXDOMAIN)的缓存时间;在旧版 BIND 中还作为未显式指定 TTL 记录的默认值

教学环境为了快速看到主从同步效果,常把 refresh 写成 10~60 秒;生产环境典型取值:refresh 1H~3H、retry 15M、expire 1W、minimum 1D。

3.3.2 NS 记录

@   IN  NS      ns.cluster.com.        ; 完整写法
    IN  NS      ns2.cluster.com.       ; name 留空表示沿用上一条的 @
  • 一个区域可以有多条 NS 记录(一主多从)。
  • 从服务器必须被列入主区域的 NS 记录中,否则主服务器的 notify 不会通知它,客户端也不会知道可以向它查询。
  • NS 记录的值必须是主机名(FQDN),不能直接写 IP;该主机名还需要有对应的 A 记录(即"胶水记录")。

3.3.3 A 记录

ns      IN  A   10.0.0.2          ; ns.cluster.com. → 10.0.0.2
mail    IN  A   192.168.0.220
host1   IN  A   192.168.0.221
@       IN  A   192.168.0.1       ; 裸域 cluster.com → 192.168.0.1

同一名字写多条 A 记录即可实现 DNS 轮询(见 4.3 节)。

3.3.4 AAAA 记录

www     IN  AAAA  2001:db8::10          ; 域名 → IPv6 地址
ipv6    IN  AAAA  fe80::20c:29ff:fe12:3456

3.3.5 CNAME 记录与别名链

web     IN  A     192.168.0.222
earth   IN  CNAME web            ; earth 是 web 的别名
mars    IN  CNAME earth          ; 可以链式重定向
www     IN  CNAME mars
  • CNAME 实现"一个 IP/主机对应多个域名"的别名机制,支持多级别名链。
  • 注意:裸域(@)不建议使用 CNAME(与 SOA/NS 记录冲突,违反 RFC);MX、NS 记录的值也不应指向 CNAME。

3.3.6 MX 记录与优先级

@       IN  MX  10  mail.cluster.com.      ; 优先级 10,主邮件服务器
@       IN  MX  20  mail2.cluster.com.     ; 优先级 20,备用
mail    IN  A   192.168.0.220
mail2   IN  A   192.168.0.221
  • MX 后面的数字是优先级(preference),数值越小优先级越高,投递方优先尝试数值小的服务器。
  • MX 的值必须是有 A 记录的主机名(FQDN),不能写 IP,也不应指向 CNAME。

3.3.7 PTR 记录

只出现在反向区域文件中:

10   IN  PTR   www.cluster.com.      ; 192.168.1.10 → www.cluster.com
183  IN  PTR   dns.abc.com.
  • 左侧写主机位数字(相对名,会自动补 .1.168.192.in-addr.arpa.),右侧必须是以点结尾的 FQDN。
  • 一个 IP 通常只配置一条 PTR 记录。

3.3.8 TXT 记录与 SPF

@       IN  TXT   "v=spf1 a mx ip4:192.168.0.220 -all"    ; SPF 反垃圾邮件策略
_dmarc  IN  TXT   "v=DMARC1; p=none; rua=mailto:postmaster@cluster.com"
verify  IN  TXT   "google-site-verification=abcd1234"     ; 域名所有权验证
  • SPF 现在统一使用 TXT 记录承载(早期有独立的 SPF 类型,已废弃)。
  • 值必须用双引号包围;单条字符串最长 255 字符,超长需拆成多段字符串。

3.3.9 SRV 记录

格式:_服务._协议 IN SRV 优先级 权重 端口 目标主机.

_ldap._tcp    IN  SRV  0 5 389  dc1.cluster.com.
_sip._udp     IN  SRV  10 60 5060 sip.cluster.com.
_xmpp-server._tcp IN SRV 5 0 5269 im.cluster.com.

四个值依次为:优先级(越小越优先)、权重(同优先级内按权重分配流量)、服务端口、提供服务的主机 FQDN。

3.4 实验:搭建主 DNS 服务器(正向 + 反向)

目标:域名 abc.com,DNS 服务器 IP 192.168.0.183。

步骤 1:编辑主配置文件 /etc/named.conf

options {
    listen-on port 53 { any; };     // 改为 any,监听所有本地 IP 地址
    listen-on-v6 port 53 { ::1; };
    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";
    allow-query     { any; };       // 允许任何人查询
    recursion yes;

    dnssec-enable no;               // 实验环境关闭 DNSSEC,避免验证失败
    dnssec-validation no;

    /* Path to ISC DLV key */
    bindkeys-file "/etc/named.iscdlv.key";

    managed-keys-directory "/var/named/dynamic";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "." IN {
    type hint;
    file "named.ca";
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

步骤 2:配置区域声明文件 /etc/named.rfc1912.zones

添加一个正向域及其反向解析域:

zone "abc.com" IN {
        type master;                        // 类型:主服务器
        file "data/master.abc.com.zone";    // 对应正向解析的文件名
};
zone "0.168.192.in-addr.arpa" IN {
        type master;
        file "data/master.0.168.192.in-addr.arpa.zone"; // 对应反向解析的文件名
};

反向区域命名规则:把网络号反序书写再加上 .in-addr.arpa。

  • 192.168.0.x(24 位掩码)→ 区域名 0.168.192.in-addr.arpa
  • 192.168.1.x → 1.168.192.in-addr.arpa
  • 10.0.0.x → 0.0.10.in-addr.arpa
  • 整个 B 类 172.16.0.0/16 → 16.172.in-addr.arpa

反向区域名必须与本网段一致,否则 PTR 查询不会命中该区域(常见错误:网段是 192.168.0.x 却写成 2.168.192.in-addr.arpa)。

步骤 3:编写正向区域数据文件

/var/named/data/master.abc.com.zone:

$TTL 3600           ; 一条记录的最长有效时间
@   IN  SOA dns.abc.com.  root.abc.com. (
            2018051901      ; 版本号(序列号)
            30              ; refresh:slave 主动联系 master 的间隔
            60              ; retry:slave 从 master 更新失败的重试间隔
            90              ; expire:无法联系 master 时,slave 多久停止服务
            3600 )          ; minimum:对否定回答的缓存时间
        IN  NS  dns.abc.com.   ; 指定本域中权威 DNS 服务器
dns     IN  A   192.168.0.183  ; dns 服务器的地址
mail    IN  A   192.168.0.183  ; A 记录就是主机的 IP 地址(Address)
host1   IN  A   192.168.0.223

一个更完整的正向区域示例(涵盖 CNAME、裸域、泛解析、$GENERATE、MX、TXT、AAAA):

$TTL 3600
$ORIGIN abc.com.
@   IN  SOA dns.abc.com.  root.abc.com. (
            2018051902
            30
            60
            90
            3600 )
        IN  NS    dns.abc.com.       ; 指定本域中权威 DNS 服务器
        IN  MX 10 mail.abc.com.      ; 邮件交换记录,优先级 10
dns     IN  A     192.168.0.183      ; dns 服务器的地址
mail    IN  A     192.168.0.220      ; A 记录就是主机的 IP 地址(Address)
host1   IN  A     192.168.0.221
web     IN  A     192.168.0.222
web     IN  AAAA  2001:db8::222      ; IPv6 地址
earth   IN  CNAME web                ; CNAME 记录
mars    IN  CNAME earth              ; 重定向到后面的记录
www     IN  CNAME mars
@       IN  A     192.168.0.1        ; 对裸域的解析(这里的裸域名是 abc.com)
*       IN  A     192.168.0.1        ; 对其他所有未定义名字的解析(泛解析)
@       IN  TXT   "v=spf1 a mx -all"
_ldap._tcp IN SRV 0 5 389 dns.abc.com.
$GENERATE 201-254 host$  IN  A   192.168.1.$   ; 定义一个范围的解析

步骤 4:编写反向区域数据文件

/var/named/data/master.0.168.192.in-addr.arpa.zone:

$TTL 86400
@   IN  SOA dns.abc.com.  root.abc.com. (
            2018051901
            30
            60
            90
            3600 )
         IN  NS    dns.abc.com.    ; 指定本域中权威 DNS 服务器
183      IN  PTR   host1.abc.com.

完整的反向区域示例:

$TTL 86400
@   IN  SOA dns.abc.com.  root.abc.com. (
            2018051902
            30
            60
            90
            3600 )
          IN  NS    dns.abc.com.
183       IN  PTR   dns.abc.com.
220       IN  PTR   mail.abc.com.
221       IN  PTR   host1.abc.com.
222       IN  PTR   web.abc.com.
223       IN  PTR   earth.abc.com.
224       IN  PTR   mars.abc.com.
225       IN  PTR   www.abc.com.
1         IN  PTR   abc.com.        ; 192.168.0.1 被解析为 abc.com
$GENERATE 100-180  $   IN  PTR   host$.abc.com.   ; 定义一个范围的解析

另一种反向区域写法(RHEL 6 教材风格,SOA/NS 直接用 IP 形式的名字,仅作示例,规范做法仍应使用 FQDN 主机名):

$TTL 86400
@   IN  SOA   192.168.1.  root. (
                201601281422
                30
                40
                50
                86400 )
    IN  NS    192.168.1.1.
10  IN  PTR   www.cluster.com.     ; 192.168.1.10 -> www.cluster.com
11  IN  PTR   news.cluster.com.    ; 192.168.1.11 -> news.cluster.com
12  IN  PTR   tech.cluster.com.    ; 192.168.1.12 -> tech.cluster.com

步骤 5:区域文件权限与属组要求

named 以 named 用户身份运行,必须能读取区域文件:

ls -l /var/named/data/
chown root:named /var/named/data/master.abc.com.zone
chmod 640 /var/named/data/master.abc.com.zone     # 属主 root 可写、属组 named 可读
# 若为从服务器或需要动态更新,目录必须对 named 可写:
chown named:named /var/named/slaves /var/named/dynamic
chmod 770 /var/named/slaves

用 cp -p 从模板复制可以直接继承正确的 root:named 640 权限,这是最省事的做法。如果是 vim 新建的文件(默认 root:root 644),虽然 644 也可读,但建议统一改为 root:named 640;而 slaves 目录必须让 named 有写权限,否则从服务器无法落盘区域文件。

步骤 6:区域文件语法检查 named-checkzone

named-checkzone abc.com /var/named/data/master.abc.com.zone
# zone abc.com/IN: loaded serial 2018051901
# OK

named-checkzone 0.168.192.in-addr.arpa /var/named/data/master.0.168.192.in-addr.arpa.zone
# zone 0.168.192.in-addr.arpa/IN: loaded serial 2018051901
# OK

输出 OK 且能看到 loaded serial 才算通过。常见报错:

报错 原因
has no address records (A or AAAA) NS 记录指向的主机名没有对应的 A 记录
not at top of zone SOA 记录不是第一条,或写了多条 SOA
CNAME and other data 同一个名字既有 CNAME 又有其他类型记录
unknown RR type 记录类型拼写错误
record with no TTL 缺少 $TTL 指令

步骤 7:启动服务与开机自启

CentOS/RHEL 6:

/etc/init.d/named start
/etc/init.d/named restart
/etc/init.d/named reload      # 只重载配置,不中断服务
/etc/init.d/named status
service named restart         # 等效写法
chkconfig named on            # 开机自启
chkconfig --list named

CentOS/RHEL 7:

sudo systemctl start named
sudo systemctl restart named
sudo systemctl reload named
sudo systemctl status named
sudo systemctl enable named   # 开机自启
sudo systemctl is-enabled named

首次启动很慢或卡住的处理:第一次启动服务时需要生成 /etc/rndc.key,因熵不足可能卡在 Generating /etc/rndc.key: 数分钟。两种解决办法:

# 方法一:手动用 urandom 生成 rndc key(推荐)
rndc-confgen -r /dev/urandom -a
# wrote key file "/etc/rndc.key"
/etc/init.d/named restart

# 方法二:临时把 /dev/random 替换成 /dev/urandom
mv /dev/random /dev/random.orig       # 备份原来的 random 文件
cp -a /dev/urandom /dev/random        # 用 urandom 代替 random
service named restart                 # 再次启动 DNS 服务器,会很快完成
mv -f /dev/random.orig /dev/random    # 恢复 random

步骤 8:防火墙与 SELinux 放行

CentOS/RHEL 6(iptables):

iptables -L                                  # 查看现有规则
iptables -I INPUT -p udp --dport 53 -j ACCEPT
iptables -I INPUT -p tcp --dport 53 -j ACCEPT
service iptables save
# 教学环境可直接清空并关闭
iptables -F
chkconfig iptables off

CentOS/RHEL 7(firewalld):

sudo firewall-cmd --permanent --add-service=dns
# 或按端口放行
sudo firewall-cmd --permanent --add-port=53/udp
sudo firewall-cmd --permanent --add-port=53/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
# 教学环境可直接关闭
sudo systemctl stop firewalld
sudo systemctl disable firewalld

SELinux:

getenforce                       # 查看当前模式(Enforcing/Permissive/Disabled)
ls /selinux/                     # RHEL 6:有数据表示 SELinux 开启
setenforce 0                     # 临时切换为 Permissive(警告模式,不拒绝操作)
vim /etc/selinux/config
# SELINUX=disabled               # 永久关闭,需重启(reboot)生效

# 保持 SELinux 开启时的正确做法:修复区域文件的安全上下文
restorecon -Rv /var/named/
semanage fcontext -a -t named_zone_t "/var/named/data(/.*)?"
setsebool -P named_write_master_zones on     # 允许 named 写主区域文件(DDNS 场景)

实验课为简化难度可先关闭防火墙和 SELinux:

sudo iptables -F
sudo systemctl disable firewalld
sudo systemctl stop firewalld
setenforce 0

步骤 9:客户端配置与验证

把系统的域名服务器改为刚创建的域名服务器:

vim /etc/resolv.conf
nameserver 192.168.0.183

测试自建 DNS 时,应把该文件中原有的记录注释或删除,避免与原有配置混淆导致结果不可信。如果 DNS 服务器就是本机,也可以写 nameserver 127.0.0.1。

验证解析:

nslookup dns.abc.com
nslookup mail.abc.com
nslookup 192.168.0.183           # 反向解析
dig www.abc.com                  # 查看完整应答报文
host web.abc.com                 # 快速查看解析结果
ping www.abc.com                 # 验证解析后网络是否可达

RHEL 6 教材中 cluster.com 的验证输出示例:

nslookup mail.cluster.com
# Server:   192.168.1.12
# Address:  192.168.1.12#53
# Name:     mail.cluster.com
# Address:  192.168.1.1

nslookup bbs.cluster.com

dig bbs.cluster.com          # 查询 NS、A、MX 等详细信息
host bbs.cluster.com         # 测试域名解析是否正常

反向解析验证输出示例:

nslookup 192.168.1.12
# 12.1.168.192.in-addr.arpa  name = tech.cluster.com.

nslookup 192.168.1.11
# 11.1.168.192.in-addr.arpa  name = news.cluster.com.

3.5 参考:cluster.com 区域文件(RHEL 6 教材完整示例)

/etc/named.rfc1912.zones 中声明:

zone "cluster.com" IN {
    type master;
    file "data/master.cluster.com.zone";
};

zone "1.168.192.in-addr.arpa" IN {
    type master;
    file "data/master.1.168.192.in-addr.arpa.zone";
};

/var/named/data/master.cluster.com.zone:

$TTL 3600
@   IN  SOA    ns.cluster.com.  root.cluster.com. (
            2013050801   ; 版本号(序列号),主从同步时需递增
            30           ; refresh
            60           ; retry
            90           ; expire
            3600 )       ; minimum
@   IN  NS      ns.cluster.com.
ns  IN  A       10.0.0.2       ; DNS 服务器 IP,可写多条 NS
mail IN A       1.1.1.1
dns  IN A       10.0.0.2
bbs  IN A       1.1.1.1

配置完成后重启服务:

/etc/init.d/named restart      # CentOS 6
sudo systemctl restart named   # CentOS 7

四、进阶部署

4.1 主从复制(辅助 DNS 服务器)

从 DNS 作为主 DNS 的备份,主挂掉后由从继续提供解析,同时也能分担查询压力。

10.0.0.2 (主)  --------  10.0.0.61 (从)
type master             type slave
手动维护 zone 文件       被动从主同步 zone 文件

4.1.1 从服务器的准备工作

与主服务器一致:

  1. 设置主机名;
  2. 时间同步(区域传送对时间敏感,建议配置 ntpd/chronyd);
  3. 关闭或放行 iptables/firewalld,关闭或正确配置 SELinux:
iptables -L              # 查看规则
iptables -F              # 清空规则
chkconfig iptables off   # CentOS 6

ls /selinux/             # 有数据表示 SELinux 开启
vim /etc/selinux/config
# SELINUX=disabled
reboot                   # 完全关闭需重启
# 临时切换为警告模式(不拒绝操作):
setenforce 0
  1. 配置好 yum 源,安装 BIND:
yum install bind* -y

4.1.2 主服务器侧配置

  1. 区域文件中必须把从服务器列入 NS 记录,并为其配置 A 记录:
$TTL 60
@   IN  SOA dns.abc.com.  root.abc.com. (
            2018110615      ; 序列号行,主从同步以此判断是否更新
            10              ; refresh
            30              ; retry
            40              ; expire
            60 )            ; minimum
        IN  NS  dns1.abc.com.   ; 本域的域名服务器
        IN  NS  dns2.abc.com.   ; 必须把从服务器列在这里
dns1    IN  A   192.168.0.183
dns2    IN  A   192.168.0.220   ; 从服务器的 IP
@       IN  A   10.10.10.10
www     IN  A   10.1.1.30
  1. 在区域声明中限制允许区域传送的对象(安全加固):
zone "cluster.com" IN {
    type master;
    file "data/master.cluster.com.zone";
    allow-transfer { 10.0.0.61; };   // 只允许 61 作为该域的从 DNS
    notify yes;                      // 数据变更立即通知从服务器
};

allow-transfer 非常重要:默认允许任意主机做区域传送,意味着任何人都能用 dig axfr 一次性拖走你整个域的主机清单(内网拓扑泄露)。生产环境必须限制为从服务器 IP,或在 options 中全局设置 allow-transfer { none; }; 再在需要的区域单独开放。

  1. 重启服务:
/etc/init.d/named restart       # CentOS 6
sudo systemctl restart named    # CentOS 7

4.1.3 从服务器侧配置

  1. named.conf 的 options 段配置与主服务器相同(listen-on、allow-query 均改为 any),并确保 DNSSEC 关闭:
dnssec-enable no;
dnssec-validation no;
  1. 编辑从服务器的区域声明文件 /etc/named.rfc1912.zones,添加与主服务器相同的域,但类型为 slave:
zone "abc.com" IN {
        type slave;                              // slave 表示是从服务器
        file "slaves/slave.abc.com.zone";        // 数据文件存放位置
        masters { 192.168.0.183; };              // 指明从哪个服务器同步数据
};

RHEL 6 教材中的等价写法:

zone "cluster.com" IN {
    type slave;
    file "slaves/slave.cluster.com.zone";   // 建议放到 slaves 目录
    masters { 10.0.0.2; };                  // 指定主 DNS 服务器 IP
};
  1. 启动/重启从服务器的 named 服务:
/etc/init.d/named start         # CentOS 6
sudo systemctl restart named    # CentOS 7
  1. 验证 zone 文件已从主服务器自动同步生成:
ls /var/named/slaves/
# slave.cluster.com.zone
# slave.abc.com.zone

# 安装了 bind-chroot 时也可查看
ls /var/named/chroot/var/named/slaves/

注意:从服务器的区域文件不需要也不应该手工创建,它由 named 从主服务器拉取后自动生成在 slaves/ 目录。因此该目录必须对 named 用户可写。

4.1.4 区域传送:AXFR 与 IXFR

类型 全称 说明
AXFR Full Zone Transfer 全量传送:把整个区域的所有记录一次性传给从服务器。首次同步、或增量不可用时使用
IXFR Incremental Zone Transfer 增量传送:只传送自从服务器当前序列号以来发生变化的记录,节省带宽,要求主服务器支持并维护变更日志(journal 文件 .jnl)

区域传送走 TCP 53。可以手动用 dig 验证传送是否被允许:

dig @192.168.0.183 abc.com axfr        # 请求全量传送(被 allow-transfer 拒绝时返回 Transfer failed)
dig @192.168.0.183 abc.com ixfr=2018110615

4.1.5 序列号递增与 notify 机制

同步被触发有两条路径:

  1. 被动(refresh 轮询):从服务器每隔 refresh 秒主动向主服务器查询 SOA,比较序列号;主服务器的 serial 大于自己保存的 serial 时才发起区域传送。
  2. 主动(notify 通知):主服务器区域数据重新加载后,立即向区域内所有 NS 记录列出的服务器(以及 also-notify 指定的地址)发送 NOTIFY 报文,从服务器收到后立即来查询 SOA 并同步——这条路径快得多。

因此每次修改主服务器区域文件后,必须手动把 serial 改大,否则无论怎么重启,从服务器都不会更新(这是最高频的"主从不同步"原因)。

4.1.6 验证主从同步

  1. 在主服务器上修改区域文件,添加新记录或修改现有记录,并增大版本号(序列号);教学时建议把 refresh 时间改小(如 10~60 秒)以便快速观察。
  2. 重启(或重载)主服务器服务:
/etc/init.d/named restart       # CentOS 6
sudo systemctl restart named    # CentOS 7
rndc reload abc.com             # 只重载指定区域,更优雅
  1. 在从服务器上观察同步:
# 方式一:删除已同步的文件后重启服务,看是否被重新拉取
rm -f /var/named/slaves/slave.cluster.com.zone
rm -f /var/named/chroot/var/named/slaves/slave.cluster.com.zone
service named restart
ls -l /var/named/slaves/

# 方式二:实时观察日志
watch tail /var/log/messages
tail -f /var/log/messages
journalctl -fu named            # CentOS 7
  1. 直接向从服务器查询新记录,确认能查到:
nslookup www.abc.com 192.168.0.220
dig @192.168.0.220 www.abc.com
dig @192.168.0.220 abc.com soa +short    # 对比主从的 serial 是否一致

若从服务器无法下载区域文件,检查:网络连通性(ping)、iptables/firewalld 是否放行 TCP 53、SELinux、时间是否同步、主服务器 allow-transfer 是否放行本机、slaves 目录权限,并查看日志:

tail /var/log/messages

局限性说明:BIND 自带的 refresh 同步机制相对较慢。若主服务器更新大量记录后立即崩溃,可能造成主从数据不一致。生产中可通过 notify/also-notify 缩短延迟,或借助脚本、配置管理程序、共享存储实现更快更可靠的同步。

4.2 缓存 DNS 与转发器

4.2.1 缓存 DNS 服务器的原理

如果内网用户把 DNS 指向你的内网 DNS 服务器去查询 baidu.com、youku.com 等外部域名,会出现三种情况:

  • 情况一:DNS 服务器有能访问外网的默认网关 → 内网用户可以查到非本域的域名(服务器自己去做迭代查询);
  • 情况二:没有网关则无法查询。但删除网关之前查过的域名仍可解析,因为结果还在缓存中(在 TTL 内);
route del default gw 10.0.0.1    # 删除默认网关
route add default gw 10.0.0.1    # 添加默认网关
  • 情况三:配置转发服务器,把请求转发给外网 DNS 或有外网网关的 DNS。

清除 DNS 缓存:

rndc flush

构建 only-cache(纯缓存)DNS 服务器:一台 DNS 服务器管理一个域(或不管理任何域),加上一个能访问外网的网关或上游转发器即可。它不维护自己的权威区域数据,而是将客户端的递归查询转发/迭代到上游 DNS 服务器,并将返回结果缓存,后续相同查询可直接从缓存应答,提升解析效率、节约出口带宽。

4.2.2 实验:配置缓存型 DNS 服务器

把所有请求转发到上游 DNS 服务器并缓存结果(上游 IP 假设为 192.168.0.183)。

  1. 确保主配置文件中以下两行设置为 no:
dnssec-enable no;
dnssec-validation no;
  1. 编辑主配置文件 /etc/named.conf:
options {
    listen-on port 53 { any; };
    listen-on-v6 port 53 { ::1; };
    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";
    allow-query     { any; };
    recursion yes;

    forward only;
    forwarders { 192.168.0.183; };     // 把请求转发给上游服务器,然后把结果缓存起来

    dnssec-enable no;
    dnssec-validation no;

    /* Path to ISC DLV key */
    bindkeys-file "/etc/named.iscdlv.key";

    managed-keys-directory "/var/named/dynamic";
};
  1. 重启服务器:
sudo systemctl restart named    # CentOS 7
/etc/init.d/named restart       # CentOS 6

4.2.3 转发服务器

只配置本域区域文件时,服务器只能解析自己管理的域(如 cluster.com)。若要解析其他域,有两种方式:

  • 方法一:在 named.conf / named.rfc1912.zones 中再声明一个域并配置对应 zone 文件,重启服务(自己成为该域的权威);
  • 方法二:配置转发。

单域转发(转发型域):

zone "man.com" IN {
    type forward;
    forward only;                       // 只转发,不自己迭代(可选)
    forwarders { 10.0.0.127; };
};

同时需要在 options 中关闭 DNSSEC 验证,否则可能因验证失败返回 SERVFAIL:

options {
    dnssec-validation no;
};
/etc/init.d/named restart

测试:

nslookup station171.man.com
# Server:  10.0.0.45
# Non-authoritative answer:
# Name:    station171.man.com
# Address: 10.0.0.171

结果为"非权威回答"(Non-authoritative answer),因为这是转发到 10.0.0.127 的 DNS 查询后返回的结果,本机并非该域的权威服务器。

实验:配置转发型域 abc.com(本机 DNS 192.168.0.183,把请求转发给上游 192.168.2.182):

zone "abc.com" IN {
        type forward;
        forward only;
        forwarders { 192.168.2.182; };      # 上游 DNS 服务器 IP
};

测试步骤:

vi /etc/resolv.conf
# nameserver 127.0.0.1

dig @192.168.0.183 mail.abc.com
nslookup mail.abc.com

完全转发(全局转发):在 options 中配置 forwarders,本机 zone 文件查不到的记录全部转发给指定 DNS:

options {
    dnssec-validation no;
    forwarders { 10.0.0.1; };
};

可指定多个转发服务器,用分号分隔:

options {
    forwarders { 10.0.0.127; 10.0.0.199; };
    forward first;      // 转发器都无响应时,自己向根做迭代查询
};
指令 行为
forward only; 只转发。所有转发器都不响应时直接返回失败,不会自己去问根服务器
forward first; 先转发。转发器都不响应时回退到自行迭代查询(默认值)

4.3 DNS 轮询(round-robin)实现简单负载均衡

一个域名对应多个 IP,客户端每次查询得到的记录顺序不同,从而把请求分散到多台服务器。

4.3.1 架构

          client
            |
        DNS 服务器
            |
       www.cluster.com
       /      |       \
   web1     web2     web3
192.168.1.11  .12    .13
            rsync
       共享存储,保证数据一致

4.3.2 配置

在正向区域文件中为同一主机名添加多条 A 记录:

$TTL 3600
@   IN  SOA   cluster.com.  root. (
            201601281143
            30
            60
            90
            3600 )
    IN  NS    192.168.1.12.
www IN  A     192.168.1.11
www IN  A     192.168.1.12
www IN  A     192.168.1.13
/etc/init.d/named reload

4.3.3 测试

nslookup www.cluster.com
# Name:  www.cluster.com
# Address: 192.168.1.13
# Name:  www.cluster.com
# Address: 192.168.1.11
# Name:  www.cluster.com
# Address: 192.168.1.12

多次查询会看到返回的 IP 顺序在轮换。

4.3.4 优缺点

  • 优点:配置极其简单,零成本,天然支持跨机房分流。
  • 缺点:
    • 没有后台健康检查——某台服务器宕机后,DNS 仍会把用户分到这台机器上;
    • 调度算法单一(只是轮转,无法按权重、连接数、响应时间调度);
    • 由于各级 DNS 缓存的存在,修改记录后生效很慢(受 TTL 影响)。

4.4 CNAME 别名链完整示例

$TTL 86400
@   IN  SOA   192.168.1.12.  daniel. (
            2013011101
            10
            20
            30
            86400 )
    IN  NS    192.168.1.12.
www IN  CNAME venus
venus IN CNAME mars
mars IN CNAME earth
earth IN CNAME web
web IN A     192.168.1.10
web IN A     192.168.1.11
web IN A     192.168.1.12
mail IN A    192.168.1.13
/etc/init.d/named reload

测试:

nslookup www.cluster.com
# www.cluster.com    canonical name = venus.cluster.com.
# venus.cluster.com  canonical name = mars.cluster.com.
# mars.cluster.com   canonical name = earth.cluster.com.
# earth.cluster.com  canonical name = web.cluster.com.
# Name: web.cluster.com
# Address: 192.168.1.10 / .11 / .12

可以看到 CNAME 链被逐级展开,最终落到 web 的三条 A 记录(同时体现了轮询)。

4.5 直接解析域(裸域)与泛域名解析

4.5.1 直接解析域(裸域)

不写主机名,直接对 cluster.com 本身做解析:

$TTL 86400
@   IN  SOA   192.168.1.145.  root. (
            201601281422
            30
            40
            50
            86400 )
    IN  NS    192.168.1.145.
cluster.com. IN A 192.168.1.73

也可以用 @ 简写:@ IN A 192.168.1.73。

nslookup cluster.com
# Name:    cluster.com
# Address: 3.3.3.3

4.5.2 泛域名解析(通配符)

*   IN  A   4.4.4.4

任意未明确定义的子域名都会解析到 4.4.4.4:

nslookup sdfasfsasdfsad.cluster.com
# Name:    sdfasfsasdfsad.cluster.com
# Address: 4.4.4.4

用途:多用户/多租户站点(user1.example.com、user2.example.com 全部指向同一台服务器,由 Web 服务器按 Host 头分发),或防止用户输错子域名时报错。

注意:泛解析会让所有拼写错误的子域都返回结果,使 NXDOMAIN 永不出现,可能掩盖配置问题,也可能被滥用做垃圾站点,生产中需谨慎。

4.6 子域授权与委派

域名可以分层委派,把子域的管理权交给下级 DNS 服务器:

baidu.com
├── news.baidu.com
│   ├── us.news.baidu.com
│   └── cn.news.baidu.com
└── tieba.baidu.com
    ├── sports.tieba.baidu.com
    └── military.tieba.baidu.com

在父域(cluster.com)的区域文件中授权子域 news.cluster.com:

$TTL 3600
@   IN  SOA   ns.cluster.com.  root.cluster.com. (
            2018060101
            3H
            15M
            1W
            1D )
@       IN  NS     ns.cluster.com.
ns      IN  A      10.0.0.2

; ---- 把 news 子域委派给 10.0.0.100 ----
news    IN  NS     ns.news.cluster.com.        ; 子域的 NS 记录(授权)
ns.news IN  A      10.0.0.100                  ; 胶水记录(glue record),必须提供

在子域服务器(10.0.0.100)上建立独立区域:

zone "news.cluster.com" IN {
    type master;
    file "data/master.news.cluster.com.zone";
};
$TTL 3600
@   IN  SOA   ns.news.cluster.com.  root.news.cluster.com. (
            2018060101
            3H
            15M
            1W
            1D )
@       IN  NS    ns.news.cluster.com.
ns      IN  A     10.0.0.100
us      IN  A     10.0.0.101       ; us.news.cluster.com
cn      IN  A     10.0.0.102       ; cn.news.cluster.com
www     IN  A     10.0.0.103

要点:

  • 父域只保留子域的 NS 记录 + 胶水 A 记录,不再保存子域内的具体主机记录;
  • 胶水记录必不可少:否则查询方拿到 NS 主机名却无法得知其 IP,形成死循环;
  • 验证委派是否正确:
dig @10.0.0.2 news.cluster.com NS          # 父域应返回 referral(AUTHORITY 段)
dig www.news.cluster.com +trace            # 观察从父域跳到子域的过程

4.7 视图(view)实现智能解析

视图可以让同一台 DNS 服务器根据客户端来源 IP 返回不同的解析结果,这就是"智能 DNS"/"分线路解析"的实现方式(例如电信用户返回电信机房 IP、联通用户返回联通机房 IP、内网用户返回内网 IP)。

规则:一旦使用了 view,所有的 zone 声明都必须写在某个 view 内部,不能有游离在 view 之外的 zone。

/etc/named.conf 完整配置示例:

options {
    listen-on port 53 { any; };
    directory       "/var/named";
    allow-query     { any; };
    recursion yes;
    dnssec-enable no;
    dnssec-validation no;
};

logging {
    channel default_debug {
        file "data/named.run";
        severity dynamic;
    };
};

// ---- 定义客户端来源分组(ACL 必须写在 view 之前)----
acl "lan"      { 192.168.0.0/24; 127.0.0.1; };
acl "telecom"  { 202.96.0.0/16; 61.139.0.0/16; };
acl "unicom"   { 221.5.0.0/16; 123.125.0.0/16; };

// ---- 视图一:内网客户端 ----
view "lan_view" {
    match-clients { lan; };
    recursion yes;

    zone "." IN {
        type hint;
        file "named.ca";
    };

    zone "abc.com" IN {
        type master;
        file "view/lan.abc.com.zone";      // 内网专用区域文件
    };
};

// ---- 视图二:电信客户端 ----
view "telecom_view" {
    match-clients { telecom; };
    recursion no;

    zone "abc.com" IN {
        type master;
        file "view/telecom.abc.com.zone";
    };
};

// ---- 视图三:联通客户端 ----
view "unicom_view" {
    match-clients { unicom; };
    recursion no;

    zone "abc.com" IN {
        type master;
        file "view/unicom.abc.com.zone";
    };
};

// ---- 视图四:其他所有客户端(必须放在最后,作为兜底)----
view "any_view" {
    match-clients { any; };
    recursion no;

    zone "." IN {
        type hint;
        file "named.ca";
    };

    zone "abc.com" IN {
        type master;
        file "view/any.abc.com.zone";
    };
};

对应的三份区域文件(放在 /var/named/view/ 下,同一域名解析到不同 IP):

; /var/named/view/lan.abc.com.zone —— 内网视图
$TTL 600
@   IN  SOA  dns.abc.com.  root.abc.com. ( 2018060101 1H 15M 1W 1D )
@       IN  NS   dns.abc.com.
dns     IN  A    192.168.0.183
www     IN  A    192.168.0.222      ; 内网用户走内网地址
; /var/named/view/telecom.abc.com.zone —— 电信视图
$TTL 600
@   IN  SOA  dns.abc.com.  root.abc.com. ( 2018060101 1H 15M 1W 1D )
@       IN  NS   dns.abc.com.
dns     IN  A    202.96.134.133
www     IN  A    202.96.134.200     ; 电信用户走电信机房
; /var/named/view/unicom.abc.com.zone —— 联通视图
$TTL 600
@   IN  SOA  dns.abc.com.  root.abc.com. ( 2018060101 1H 15M 1W 1D )
@       IN  NS   dns.abc.com.
dns     IN  A    221.5.88.88
www     IN  A    221.5.88.200       ; 联通用户走联通机房

配置要点与验证:

  • match-clients 按从上到下的顺序匹配,第一个命中的 view 生效,因此 match-clients { any; } 的兜底视图必须放在最后;
  • acl 定义必须出现在使用它的 view 之前;
  • 每个 view 内可以各自设置 recursion、allow-query 等选项;
  • 需要根提示的 view(提供递归的那些)要各自包含 zone "." { type hint; ... };
  • 检查与验证:
named-checkconf
mkdir -p /var/named/view && chown root:named /var/named/view && chmod 750 /var/named/view
rndc reload

# 从不同来源地址测试(-b 指定源地址)
dig @192.168.0.183 www.abc.com -b 192.168.0.10
dig @192.168.0.183 www.abc.com -b 202.96.134.5

4.8 DNS 与虚拟主机配合

DNS 解析只负责把不同域名指向服务器 IP,真正区分"同一 IP 上多个站点"的工作由 Web 服务器的虚拟主机(基于域名的 VirtualHost)完成:先用 DNS 把 www.abc.com、bbs.abc.com 都解析到同一 IP,再由 Apache/Nginx 按请求头中的 Host 分发到不同站点目录。

详见 10-01-Apache服务.md


五、查询工具与排错

常用的 DNS 调试工具包括 nslookup、dig、host、ping,以及管理工具 rndc。

工具 特点 常用场景
dig 输出详细,功能强大 故障排查、查看完整响应报文
host 简洁轻量 快速查看解析结果
nslookup 交互/非交互均可,跨平台(Windows 也有) 通用 DNS 查询
ping 验证解析后网络是否可达 连通性测试
whois 查询域名注册信息 确认域名归属、注册商、权威 NS
rndc 本地/远程控制 named 重载配置、清缓存、查状态、开查询日志

可通过 @ 指定 DNS 服务器的 IP,也可通过修改 /etc/resolv.conf 设定默认 DNS 服务器:

dig @192.168.0.183 www.abc.com
nslookup www.abc.com
host www.abc.com
ping www.abc.com

5.1 nslookup

非交互式用法:

nslookup www.abc.com                  # 使用 /etc/resolv.conf 中的默认 DNS 查询
nslookup www.abc.com 192.168.0.183    # 指定 DNS 服务器查询(服务器写在域名之后)
nslookup 192.168.0.183                # 反向解析
nslookup -type=mx abc.com             # 查询 MX 记录
nslookup -type=ns abc.com             # 查询 NS 记录
nslookup -type=soa abc.com            # 查询 SOA 记录
nslookup -type=cname www.abc.com      # 查询 CNAME
nslookup -type=txt abc.com            # 查询 TXT
nslookup -type=any abc.com            # 查询所有类型
nslookup -debug www.abc.com           # 显示详细调试信息

典型输出解读:

Server:   192.168.1.12        ← 应答本次查询的 DNS 服务器
Address:  192.168.1.12#53     ← 服务器地址与端口
Name:     mail.cluster.com    ← 查询的名字
Address:  192.168.1.1         ← 解析结果

如果结果前出现 Non-authoritative answer:,说明这是非权威回答(来自缓存或转发结果);没有这一行则为权威服务器直接给出的权威回答。

交互式用法:

nslookup
> server 192.168.0.183         # 切换要查询的 DNS 服务器
> set type=mx                  # 设置查询的记录类型
> set type=a
> set type=ptr
> set all                      # 显示当前所有设置
> set debug                    # 打开调试
> set port=53                  # 指定端口
> set timeout=5                # 设置超时
> www.abc.com                  # 直接输入域名进行查询
> 192.168.0.183                # 输入 IP 进行反向查询
> exit                         # 退出(也可用 Ctrl+D)

5.2 dig

dig(Domain Information Groper)是最推荐的排错工具,输出的是接近原始报文的结构化信息。

基本语法:

dig [@服务器] <域名> [记录类型] [+选项]

常用命令:

dig www.abc.com                     # 查询 A 记录(默认)
dig @192.168.0.183 www.abc.com      # 指定 DNS 服务器查询
dig abc.com MX                      # 查询 MX 记录
dig abc.com NS                      # 查询 NS 记录
dig abc.com SOA                     # 查询 SOA 记录
dig www.abc.com CNAME               # 查询 CNAME
dig abc.com TXT                     # 查询 TXT/SPF
dig www.abc.com AAAA                # 查询 IPv6 记录
dig abc.com ANY                     # 查询所有记录类型
dig abc.com AXFR                    # 请求区域传送(测试 allow-transfer)
dig -x 192.168.0.183                # 反向查询(自动转换成 in-addr.arpa)
dig -p 5353 @127.0.0.1 abc.com      # 指定端口
dig -t ns abc.com                   # -t 显式指定类型
dig -f names.txt                    # 批量查询文件中的域名

常用 + 选项:

选项 说明
+short 只输出最精简的结果(通常只有 IP),适合脚本
+noall +answer 只显示 ANSWER 段,最常用的"干净输出"组合
+trace 从根开始逐级追踪整个迭代查询过程,排查委派问题的利器
+nocmd 不显示开头的命令行版本信息
+nocomments 不显示注释行
+stats / +nostats 显示/隐藏统计段(查询耗时、服务器、报文大小)
+multiline 多行、易读地展示记录(尤其是 SOA)
+norecurse 不请求递归(RD 位置 0),用于测试服务器是否为权威
+tcp 强制使用 TCP 查询
+dnssec 请求返回 DNSSEC 相关记录
+time=N 超时秒数
+tries=N 重试次数

示例:

dig +short www.abc.com
# 192.168.0.222

dig +noall +answer www.abc.com
# www.abc.com.  3600  IN  CNAME  mars.abc.com.
# mars.abc.com. 3600  IN  CNAME  earth.abc.com.
# earth.abc.com. 3600 IN  CNAME  web.abc.com.
# web.abc.com.  3600  IN  A      192.168.0.222

dig +trace www.baidu.com            # 观察 . → com → baidu.com 的完整迭代链
dig +multiline abc.com soa          # 逐行展示 SOA 的七个字段

dig 输出各段解读:

; <<>> DiG 9.9.4 <<>> www.abc.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12345
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1

;; QUESTION SECTION:            ← ① 问题段:本次查询的名字、类别、类型
;www.abc.com.            IN  A

;; ANSWER SECTION:              ← ② 应答段:查询的答案(记录名 TTL 类别 类型 值)
www.abc.com.     3600   IN  A   192.168.0.222

;; AUTHORITY SECTION:           ← ③ 授权段:该域的权威 NS 服务器
abc.com.         3600   IN  NS  dns.abc.com.

;; ADDITIONAL SECTION:          ← ④ 附加段:上面 NS 主机名对应的 A 记录(胶水记录)
dns.abc.com.     3600   IN  A   192.168.0.183

;; Query time: 1 msec           ← ⑤ 统计段
;; SERVER: 192.168.0.183#53(192.168.0.183)   ← 实际应答的服务器
;; WHEN: Wed May 19 10:00:00 CST 2018
;; MSG SIZE  rcvd: 98

HEADER 中的关键字段:

字段 含义
status: NOERROR 查询成功;其他常见值见 5.7 节(NXDOMAIN、SERVFAIL、REFUSED)
flags: qr QR:这是一个响应报文
flags: aa Authoritative Answer,权威回答——应答来自该域的权威服务器
flags: rd Recursion Desired,客户端请求递归
flags: ra Recursion Available,服务器支持递归(没有 ra 说明服务器拒绝提供递归)
flags: tc TrunCated,应答被截断,需改用 TCP
ANSWER: 0 应答段记录数为 0,说明没查到记录

练习:根据 dig 结果反推架构

dig www.sina.com 的结果:

;; ANSWER SECTION:
www.sina.com.cn.      35  IN  CNAME  us.sina.com.cn.
us.sina.com.cn.        2  IN  CNAME  news.sina.com.cn.
news.sina.com.cn.      2  IN  CNAME  jupiter.sina.com.cn.
jupiter.sina.com.cn.  59  IN  CNAME  libra.sina.com.cn.
libra.sina.com.cn.   182  IN  A      202.108.33.98
libra.sina.com.cn.   182  IN  A      202.108.33.99
libra.sina.com.cn.   182  IN  A      202.108.33.70
... (多个 A 记录)
libra.sina.com.cn.   182  IN  A      202.108.33.97

;; AUTHORITY SECTION:
sina.com.cn.  18423  IN  NS  ns3.sina.com.cn.
sina.com.cn.  18423  IN  NS  ns1.sina.com.cn.
sina.com.cn.  18423  IN  NS  ns2.sina.com.cn.
sina.com.cn.  18423  IN  NS  ns4.sina.com.cn.

;; ADDITIONAL SECTION:
ns1.sina.com.cn.  24775  IN  A  202.106.184.166
ns2.sina.com.cn.  24775  IN  A  61.172.201.254
ns3.sina.com.cn.  24775  IN  A  202.108.44.55
ns4.sina.com.cn.  24775  IN  A  121.14.1.22

可以读出:sina.com.cn 有 4 台权威 NS 服务器;www.sina.com 通过 CNAME 链最终落到 libra.sina.com.cn 的一组 A 记录(DNS 轮询)。对应的还原配置见 5.9 节练习 4 的参考答案。

5.3 host

host www.abc.com                      # 查询 A/AAAA/MX 的简要结果
host www.abc.com 192.168.0.183        # 指定 DNS 服务器
host -t mx abc.com                    # 指定记录类型
host -t ns abc.com
host -t soa abc.com
host -a abc.com                       # 等价于 -t ANY -v,显示全部信息
host -v www.abc.com                   # 详细模式(类似 dig 的分段输出)
host 192.168.0.183                    # 反向解析(自动识别 IP)
host -l abc.com 192.168.0.183         # 列出该域全部主机(需要区域传送权限)
host -C abc.com                       # 比较所有权威服务器上的 SOA(查主从是否一致)
host -W 3 www.abc.com                 # 等待超时秒数

5.4 whois

查询域名的注册信息(注册商、注册人、注册/到期时间、权威 NS):

yum install jwhois -y          # CentOS 6
yum install whois -y           # CentOS 7

whois example.com
whois baidu.com
whois -h whois.cnnic.cn baidu.cn      # 指定 whois 服务器
whois 202.108.33.98                   # 查询 IP 归属(所属 AS、机构)

主要用途:确认域名归属与到期时间、找到域名真正的权威 NS 服务器(与自己配置的对比)、排查域名被劫持或过期问题。

5.5 rndc 管理

rndc(Remote Name Daemon Control)通过 TCP 953 端口以密钥认证的方式控制 named。

密钥配置:安装后首次启动会自动生成 /etc/rndc.key,named 默认会读取它,通常无需额外配置。若需手动生成:

rndc-confgen -r /dev/urandom -a        # 只生成 /etc/rndc.key
rndc-confgen -r /dev/urandom           # 输出完整配置片段(供 rndc.conf 与 named.conf 使用)

手动配置示例——/etc/rndc.key(或 /etc/rndc.conf):

key "rndc-key" {
        algorithm hmac-md5;
        secret "aBcDeFgHiJkLmNoPqRsTuV==";
};

在 /etc/named.conf 中声明控制通道:

include "/etc/rndc.key";

controls {
        inet 127.0.0.1 port 953
                allow { 127.0.0.1; } keys { "rndc-key"; };
};

常用 rndc 子命令:

命令 说明
rndc status 查看 named 运行状态(版本、区域数、是否开启递归、查询日志开关等)
rndc reload 重载配置文件和所有区域文件(不中断服务)
rndc reload abc.com 只重载指定区域
rndc reconfig 只重读 named.conf 并加载新增的区域(比 reload 更轻)
rndc flush 清空服务器全部缓存
rndc flushname www.abc.com 只清空指定名字的缓存
rndc querylog 开启/关闭查询日志(开关式,再执行一次即关闭)
rndc dumpdb -cache 把缓存内容转储到 dump-file(/var/named/data/cache_dump.db)
rndc stats 把统计信息写入 statistics-file
rndc notify abc.com 手动向从服务器发送 NOTIFY
rndc refresh abc.com (从服务器上)立即向主服务器检查更新
rndc retransfer abc.com (从服务器上)强制全量重新传送该区域
rndc freeze abc.com / thaw 冻结/解冻区域,手工编辑动态更新过的区域文件前后使用
rndc trace / rndc trace 3 / rndc notrace 提高/设置/关闭调试级别
rndc stop / rndc halt 保存后停止 / 立即停止 named

5.6 日志与查询日志

# CentOS 6:主要日志在 messages
tail -f /var/log/messages
grep named /var/log/messages

# CentOS 7:systemd 日志
sudo journalctl -xe
sudo journalctl -u named -f

# BIND 自身的运行日志(logging 段中 default_debug 通道指定)
tail -f /var/named/data/named.run

开启查询日志(记录每一次客户端查询,排查"客户端到底查了什么、有没有到达服务器"):

rndc querylog          # 立即开启(再执行一次关闭),日志写入 named.run / messages
tail -f /var/named/data/named.run

或在 named.conf 的 logging 段中永久配置独立的查询日志文件(见 2.6.2 节示例),然后:

touch /var/named/data/query.log
chown named:named /var/named/data/query.log
rndc reload

查询日志的一行示例:

client 192.168.0.10#52341 (www.abc.com): query: www.abc.com IN A + (192.168.0.183)

依次为:客户端 IP#源端口、查询的名字、查询类型、+ 表示请求递归、应答的本机地址。

5.7 排错清单

5.7.1 服务起不来(配置语法错误)

排查命令:

named-checkconf                    # 先查主配置语法
named-checkconf -z                 # 连区域文件一起加载检查
named-checkzone abc.com /var/named/data/master.abc.com.zone

/etc/init.d/named restart          # CentOS 6
tail -50 /var/log/messages

sudo systemctl restart named       # CentOS 7
sudo systemctl status named -l
sudo journalctl -xe
sudo journalctl -u named --since "5 min ago"

常见原因:

现象/报错 原因与处理
/etc/named.conf:25: missing ';' before '}' 漏写行尾分号或括号不匹配
zone abc.com/IN: loading from master file ... failed: file not found file 指定的路径与实际文件不一致;注意路径是相对 directory(/var/named)的
permission denied 区域文件属主/权限不对(应为 root:named 640),或 SELinux 上下文错误
Address already in use / 端口冲突 53 端口被 dnsmasq 等占用:ss -tulnp | grep :53,停掉冲突服务
卡在 Generating /etc/rndc.key 熵不足,用 rndc-confgen -r /dev/urandom -a 生成
not at top of zone SOA 不在区域文件首条,或写了多条 SOA
has no address records NS/MX 指向的主机名缺少 A 记录

排错原则:named-checkconf + named-checkzone 通过后再重启;启动失败一定先看日志,不要盲猜。

5.7.2 SERVFAIL 与 NXDOMAIN 的区别与定位

status 含义 典型原因 定位方法
NOERROR + ANSWER: 0 域名存在,但没有你要的那个类型的记录 查了 A 但只配了 CNAME/MX;名字写错了大小写无关但拼写有关 dig 域名 ANY 看有哪些类型
NXDOMAIN 域名不存在(权威服务器明确回答"没这个名字") 区域文件里确实没有这条记录;记录名多补了一次域名(www.abc.com.abc.com);查询的域名拼写错误;区域文件改了但没重载 在服务器上 grep 区域文件确认记录存在;dig @本机 域名 与 dig @权威 域名 对比
SERVFAIL 服务器故障/无法完成解析 ① 区域文件加载失败(语法错),该区域根本没载入;② 上游转发器不可达;③ DNSSEC 验证失败(需 dnssec-validation no);④ 递归时无法访问根服务器(无网关/防火墙拦截) rndc status 看区域数;named-checkzone;日志中找 loading from master file failed;临时关闭 DNSSEC 验证测试
REFUSED 服务器拒绝服务 allow-query 未放行该客户端;recursion no 或 allow-recursion 不含该客户端却请求了递归;allow-transfer 拒绝区域传送 检查 ACL 配置;dig 结果中看是否缺少 ra 标志

一个快速判断口诀:NXDOMAIN 是"我确定没有",SERVFAIL 是"我办不到",REFUSED 是"我不给你办"。

5.7.3 正向能解析、反向不行

按顺序检查:

  1. named.rfc1912.zones 中是否声明了反向区域;
  2. 反向区域名是否与网段匹配(192.168.0.x → 0.168.192.in-addr.arpa,注意反序、注意不要写成别的网段);
  3. 反向区域文件是否存在、file 路径是否与声明一致、权限是否正确;
  4. named-checkzone 0.168.192.in-addr.arpa /var/named/data/master.0.168.192.in-addr.arpa.zone 是否 OK;
  5. PTR 记录左侧是否写的是主机位数字(相对名),右侧是否为以点结尾的 FQDN;
  6. 序列号是否递增、服务是否重载;
  7. 验证:dig -x 192.168.0.183 / nslookup 192.168.0.183。

补充:反向解析在公网上由 IP 地址的持有者(运营商/云厂商)配置,自建 DNS 无法为不属于自己的公网 IP 提供有效的公网反向解析。

5.7.4 从服务器不同步

检查清单:

  1. 主服务器 SOA 的 serial 是否递增(最常见原因,没改大就绝对不会同步);
  2. 主服务器 allow-transfer 是否放行了从服务器 IP;
  3. 从服务器区域 type slave + masters { 主IP; }; 是否正确;
  4. 防火墙是否放行 TCP 53(区域传送走 TCP,只放 UDP 会导致"能查询但不能同步");
  5. /var/named/slaves/ 目录对 named 用户是否可写(chown named:named,chmod 770),SELinux 是否允许(setsebool -P named_write_master_zones on 或 setenforce 0);
  6. 主从时间是否同步;
  7. 主区域的 NS 记录中是否包含从服务器(影响 notify);
  8. 手工强制同步与观察:
# 从服务器上
rndc refresh abc.com          # 立即检查更新
rndc retransfer abc.com       # 强制全量重传
dig @主服务器IP abc.com axfr   # 直接测试区域传送是否被允许
tail -f /var/log/messages     # 看 transfer of 'abc.com/IN' from ... 的结果
journalctl -u named -f        # CentOS 7

# 对比主从 serial
dig @192.168.0.183 abc.com soa +short
dig @192.168.0.220 abc.com soa +short

5.7.5 递归被拒绝(REFUSED)

现象:客户端查询外部域名返回 REFUSED,或 dig 结果中 flags 缺少 ra。

处理:

options {
    recursion yes;                                  // 开启递归
    allow-recursion { 192.168.0.0/24; localhost; };  // 放行内网客户端
    allow-query    { any; };                        // 放行查询
};

同时确认:服务器本身能访问外网(有默认网关,或配置了可用的 forwarders)、/var/named/named.ca 存在且未损坏。

安全提醒:面向公网提供服务的权威 DNS 应设置 recursion no,或严格限制 allow-recursion,否则会成为开放递归解析器,被利用发起 DNS 放大 DDoS 攻击。

5.7.6 SELinux 导致区域文件读不到

现象:文件明明存在、权限也是 640 root:named,日志仍报 permission denied 或 file not found。

getenforce                                  # 若为 Enforcing 则高度怀疑
ls -Z /var/named/data/master.abc.com.zone   # 查看安全上下文,应为 named_zone_t 或 named_conf_t
ausearch -m avc -ts recent                  # 查看 AVC 拒绝记录
grep named /var/log/audit/audit.log

# 修复
restorecon -Rv /var/named/
semanage fcontext -a -t named_zone_t "/var/named/data(/.*)?"
restorecon -Rv /var/named/data
setsebool -P named_write_master_zones on    # 允许写主区域(DDNS / slaves)

# 或临时/永久关闭(教学环境)
setenforce 0
vim /etc/selinux/config   # SELINUX=disabled,重启生效

特别提示:用 mv 从其他目录移动文件到 /var/named/ 不会更新安全上下文(cp 会继承目标目录上下文)。所以移动文件后一定要 restorecon。

5.7.7 修改区域文件后不生效

按下面顺序逐项排除:

  1. 忘记递增 serial——影响从服务器同步(主服务器自身重载通常仍会生效,但从服务器不会);
  2. 忘记重载服务——执行 rndc reload 或 systemctl reload named / service named reload;
  3. 缓存未过期——记录的旧值还在缓存里:
    • 本机 named 缓存:rndc flush 或 rndc flushname www.abc.com;
    • 客户端/中间递归服务器缓存:只能等 TTL 到期,或直接向权威服务器查询绕过缓存:dig @权威IP www.abc.com;
    • 系统级缓存:nscd -i hosts、systemd-resolve --flush-caches;Windows 用 ipconfig /flushdns;
  4. 改错了文件——安装 bind-chroot 后误改了 /var/named/chroot/... 下的副本,或 file 指向的其实是另一个文件;用 rndc status、named-checkconf -z 确认实际加载的是哪个文件;
  5. 被 /etc/hosts 覆盖——/etc/nsswitch.conf 中 files 在 dns 之前,本机 hosts 里有同名条目;
  6. 客户端问的不是这台服务器——检查 /etc/resolv.conf,或用 dig 输出末尾的 ;; SERVER: 行确认实际应答者;
  7. 动态更新过的区域——存在 .jnl 文件时手工编辑无效,需 rndc freeze abc.com → 编辑 → rndc thaw abc.com。

5.7.8 其他易错点

  1. /etc/resolv.conf 配置问题:该文件记录本机程序默认联系的 DNS 服务器,ping www.gnu.org 这类命令都依赖它。配置好自己的 DNS 服务器后测试时,应在此文件中写上自己的服务器 IP 地址;为防止冲突混淆,应把文件中原有的记录注释或删除。
  2. 数据库文件中的映射关系不被校验:DNS 数据库文件中的"名字"和"IP 地址"表示的仅是从名字到 IP 的映射关系,该 IP 地址是否真实存在、主机是否在线,DNS 服务器并不关心也不会校验。只需保证记录格式正确,解析即可生效。
  3. 区域声明文件路径与实际路径不一致:区域声明文件中所使用的数据库文件路径,必须与数据库文件的真实路径一致。directory 指令指定相对路径的基准目录(默认为 /var/named),并注意文件权限与 SELinux 上下文。
  4. FQDN 忘记加末尾的点:会被自动补上当前域名,产生 www.abc.com.abc.com. 这样的错误记录。
  5. /etc/resolv.conf 中 nameserver 最多 3 条生效,多写无效。

5.8 命令速查表

命令 说明
sudo yum install bind-libs bind-utils bind bind-chroot -y 安装 BIND 及配套组件
yum install bind* -y 一次性安装全部 bind 相关包
rpm -qa \| grep ^bind- 查看已安装的 bind 包
rpm -ql bind-utils 查看 bind-utils 包含的文件
rpm -qc bind 查看 BIND 相关配置文件
named-checkconf / named-checkconf -z 检查主配置语法 / 连区域一起检查
named-checkzone <区域> <文件> 检查区域文件语法
service named start\|restart\|reload\|status(CentOS 6) 管理 BIND 服务
/etc/init.d/named restart(CentOS 6) 重启 BIND 服务
chkconfig named on(CentOS 6) 设置开机自启
sudo systemctl start\|restart\|reload\|status named(CentOS 7) 管理 BIND 服务
sudo systemctl enable named(CentOS 7) 设置开机自启
rndc status 查看 named 运行状态
rndc reload [区域] 重载配置/区域
rndc flush 清空 DNS 缓存
rndc querylog 开启/关闭查询日志
rndc-confgen -r /dev/urandom -a 生成 /etc/rndc.key
dig www.example.com 查询域名 A 记录
dig @192.168.0.183 www.abc.com 指定 DNS 服务器查询
dig +short www.abc.com 只输出精简结果
dig +noall +answer www.abc.com 只显示 ANSWER 段
dig +trace www.abc.com 从根开始追踪解析过程
dig -x 192.168.0.183 反向查询
dig abc.com axfr 测试区域传送
host www.example.com 轻量域名解析
host -t mx abc.com 查询指定类型记录
nslookup www.example.com 交互式/非交互式 DNS 查询
nslookup -type=mx abc.com 查询 MX 记录
whois example.com 查询域名注册信息
ping www.example.com 测试域名解析及网络连通性
sudo journalctl -xe / journalctl -u named -f 查看系统日志,排查启动失败原因(CentOS 7)
tail -f /var/log/messages 查看日志(CentOS 6)
restorecon -Rv /var/named/ 修复 SELinux 上下文

5.9 注意事项汇总

  1. DNS 服务器最多 3 个:/etc/resolv.conf 中 nameserver 条目最多生效 3 条。
  2. 递归与迭代查询角色:客户端对本地 DNS 通常使用递归查询;本地 DNS 向上级服务器使用迭代查询。
  3. 文件路径一致性:区域声明中的 file 路径必须与实际数据库文件路径一致(相对 directory)。
  4. 记录仅为映射关系:DNS 不验证 IP 地址对应主机是否真实存在。
  5. 测试前修改 /etc/resolv.conf:验证自建 DNS 时,先将客户端 DNS 指向自建服务器,避免与原有配置混淆。
  6. 查看日志定位问题:服务启动失败时,优先使用 journalctl -xe(CentOS 7)或 tail /var/log/messages(CentOS 6)获取详细报错。
  7. 改区域文件必递增 serial:这是主从同步的唯一依据。
  8. UDP 53 与 TCP 53 都要放行。
  9. allow-transfer 必须限制,防止区域数据被整体拖走。
  10. 对外服务的权威 DNS 关闭递归,避免成为 DNS 放大攻击的反射器。

六、练习与参考答案

以下实验前,为简化难度请先关闭防火墙和 SELinux:

# CentOS 7
sudo iptables -F
sudo systemctl stop firewalld
sudo systemctl disable firewalld
setenforce 0

# CentOS 6
iptables -F
service iptables stop
chkconfig iptables off
setenforce 0

练习 1:浏览器访问 www.baidu.com 的完整过程

简述通过浏览器访问 www.baidu.com 的完整过程(域名查找、DNS 访问、网络访问过程)。

涉及文件:/etc/nsswitch.conf、/etc/hosts、/etc/resolv.conf。

参考答案要点:

  1. 浏览器/系统解析器先查浏览器自身 DNS 缓存与系统缓存(nscd/systemd-resolved);
  2. 按 /etc/nsswitch.conf 中 hosts: files dns 的顺序,先查 /etc/hosts,命中则直接使用;
  3. 未命中则读取 /etc/resolv.conf,向第一个 nameserver 发起递归查询;
  4. 本地 DNS 服务器若有缓存则直接返回(非权威回答);否则依据 named.ca 向根服务器发起迭代查询;
  5. 根返回 .com 顶级域服务器地址 → 查询 .com → 返回 baidu.com 权威服务器地址 → 查询 baidu.com 权威服务器 → 得到 www.baidu.com 的 A 记录(可能先经过 CNAME 链);
  6. 本地 DNS 把结果返回客户端并按 TTL 缓存;
  7. 浏览器拿到 IP 后与其建立 TCP 连接(三次握手,80/443 端口),必要时完成 TLS 握手;
  8. 发送 HTTP 请求(Host 头为 www.baidu.com),服务器按虚拟主机分发并返回响应;
  9. 浏览器渲染页面,页面中的其他资源域名重复上述解析过程。

练习 2:是否需要搭建 DNS 服务器

作为公司技术人员,是否需要搭建 DNS 服务器?什么情况下需要搭建?

参考答案:视公司服务器或电脑数量而定。当内网拥有大量服务器或电脑(IP 数量较多)时,搭建 DNS 可以通过域名方便记忆与访问;此外,需要做内部域名统一管理、内外网不同解析(智能解析/视图)、加速外网解析(缓存 DNS)、为邮件服务提供 MX 与反向解析时,也需要自建 DNS。若规模很小、IP 极少,用 /etc/hosts 维护即可,无需搭建。

练习 3:四类 DNS 服务器的区别及应用

简述主 DNS、从 DNS、缓存 DNS、转发 DNS 的区别及应用。

参考答案:

类型 作用
主 DNS 主要负责 DNS 域名解析的服务器,区域数据手工维护,是数据源头
从 DNS 主 DNS 的备份,主挂掉后接替提供解析,避免单点故障,同时分担查询压力
缓存 DNS 将经常解析的域名缓存起来,实现快速解析、节约网络资源,适合企业局域网
转发 DNS 当本服务器没有需要解析的域名时,转发到其他 DNS 服务器进行解析

练习 4:根据 dig 结果还原 sina 的 DNS 架构与配置

根据 5.2 节 dig www.sina.com 的结果画出 sina 的 DNS 架构图,并写出配置。

参考答案:

/etc/named.rfc1912.zones:

zone "sina.com.cn" IN {
    type master;
    file "data/master.sina.com.cn.zone";
};

zone "sina.com" IN {
    type master;
    file "data/master.sina.com.zone";
};

/var/named/data/master.sina.com.cn.zone:

$TTL 3600
@   IN  SOA   fsdfsafsa.  sdfasd. (
            2013071202
            10
            20
            30
            3600 )
    IN  NS    ns1.sina.com.cn.
    IN  NS    ns2.sina.com.cn.
    IN  NS    ns3.sina.com.cn.
    IN  NS    ns4.sina.com.cn.
ns1 IN  A     202.106.184.166
ns2 IN  A     61.172.201.254
ns3 IN  A     202.108.44.55
ns4 IN  A     121.14.1.22
libra IN A    202.108.33.98
libra IN A    202.108.33.99
libra IN A    202.108.33.70
libra IN A    202.108.33.71
libra IN A    202.108.33.72
libra IN A    202.108.33.74
libra IN A    202.108.33.75
libra IN A    202.108.33.76
libra IN A    202.108.33.77
libra IN A    202.108.33.78
libra IN A    202.108.33.79
libra IN A    202.108.33.80
libra IN A    202.108.33.81
libra IN A    202.108.33.95
libra IN A    202.108.33.96
libra IN A    202.108.33.97
jupiter IN CNAME libra
news    IN CNAME jupiter
us      IN CNAME news

可用 awk 批量追加 A 记录:

cat 1.txt | awk -F"." '{print $1,$5"."$6"."$7"."$8}' | awk '{print $1"\t"$3"\t"$4"\t"$5}' >> /var/named/data/master.sina.com.cn.zone

/var/named/data/master.sina.com.zone:

$TTL 3600
@   IN  SOA   fsdfsafsa.  sdfasd. (
            2013071202
            10
            20
            30
            3600 )
    IN  NS    ns1.sina.com.cn.
    IN  NS    ns2.sina.com.cn.
    IN  NS    ns3.sina.com.cn.
    IN  NS    ns4.sina.com.cn.
ns1 IN  A     202.106.184.166
ns2 IN  A     61.172.201.254
ns3 IN  A     202.108.44.55
ns4 IN  A     121.14.1.22
www IN  CNAME us.sina.com.cn.

架构要点:sina.com.cn 由 4 台权威 NS(ns1~ns4)负责;www.sina.com 用 CNAME 指向 us.sina.com.cn,再经 news → jupiter → libra 的多级 CNAME,最终由 libra 的十余条 A 记录做 DNS 轮询分担流量。

练习 5:配置基本 DNS 服务器(正向 + 反向)

域名:abc.com,服务器 IP:192.168.0.183。

步骤:见 3.4 节的完整实验(步骤 1~9)。要求完成后能够:

nslookup dns.abc.com          # 正向解析成功
nslookup 192.168.0.183        # 反向解析成功
dig @192.168.0.183 mail.abc.com

练习 6:CNAME、裸域、泛解析与连续范围域名

在练习 5 的基础上,修改区域数据库文件,实现:

  • web 主机的 A 记录;
  • earth → web、mars → earth、www → mars 的多级 CNAME;
  • 裸域 abc.com 的 A 记录;
  • 泛解析 *;
  • 用 $GENERATE 生成 host201~host254 的正向记录和 100~180 的 PTR 记录。

正向区域文件与反向区域文件的完整内容见 3.4 节步骤 3、步骤 4 的"完整示例"。修改后重启:

sudo systemctl restart named       # CentOS 7
/etc/init.d/named restart          # CentOS 6

验证:

dig +short www.abc.com             # 应经 CNAME 链得到 192.168.0.222
dig +short abc.com                 # 裸域 → 192.168.0.1
dig +short anything.abc.com        # 泛解析 → 192.168.0.1
dig +short host210.abc.com         # $GENERATE → 192.168.1.210
dig -x 192.168.0.222 +short        # 反向 → web.abc.com.

练习 7:配置从 DNS 服务器

假设主服务器 IP 为 192.168.0.183,从服务器 IP 为 192.168.0.220。

主服务器:按 4.1.2 节修改 /var/named/data/master.abc.com.zone(NS 中列出 dns1、dns2,并为 dns2 配置 A 记录),重启服务。

从服务器:

  1. 确保主配置文件中 dnssec-enable no;、dnssec-validation no;;
  2. 在 /etc/named.rfc1912.zones 中添加 type slave 的 abc.com 区域,masters { 192.168.0.183; };;
  3. 重启 named:sudo systemctl restart named;
  4. 测试:在主服务器上添加新记录或修改现有记录并增大序列号,重载主服务器;然后用 nslookup/dig 验证能在从服务器(@192.168.0.220)上查到新添加的记录,并确认 /var/named/slaves/slave.abc.com.zone 已自动生成。

练习 8:配置转发型域

配置一个名为 abc.com 的转发型域,本机 DNS 服务器 IP 192.168.0.183,把请求转发给上游(老师的)DNS 服务器 192.168.2.182。

配置与测试步骤见 4.2.3 节。要点:type forward; + forward only; + forwarders { 192.168.2.182; };,并关闭 DNSSEC 验证;客户端把 /etc/resolv.conf 指向 127.0.0.1 后用 dig/nslookup 验证,结果应为 Non-authoritative answer。

练习 9:配置缓存型 DNS 服务器

把所有请求转发到上游 DNS 服务器(192.168.0.183)并缓存结果。配置见 4.2.2 节,要点是在 options 中写 forward only; 与 forwarders,不声明任何本地权威区域。

验证缓存生效:连续两次执行同一查询,观察 dig 输出中 ;; Query time 明显下降、且 TTL 递减;用 rndc flush 清空缓存后 Query time 恢复。

练习 10:视图智能解析

在一台 DNS 服务器上配置两个视图,使内网客户端(192.168.0.0/24)查询 www.abc.com 得到 192.168.0.222,其他客户端得到公网地址。完整配置见 4.7 节。

验证:

dig @192.168.0.183 www.abc.com -b 192.168.0.10   # 内网视图结果
dig @192.168.0.183 www.abc.com                   # 兜底视图结果

附:常见问题

  1. 自己搭的 DNS 服务器如何与运营商联系起来,让全球能访问到自己域的解析? 需要在域名注册商/运营商处将该域的 NS 记录指向自己的 DNS 服务器(填写 NS 主机名与对应的公网 IP,即注册"DNS 主机记录/glue"),由上级域完成委派,全球查询才会被引导到你的服务器。同时你的服务器必须有固定公网 IP、放行 UDP/TCP 53,并建议至少部署两台(主 + 从)。

  2. 自己的 DNS 里能否写上 qq.com 的域和 IP 对应? 技术上可以配置(本机会成为该域的"权威"并给出权威回答),但这只对把 DNS 指向你服务器的客户端生效,属于内部解析/DNS 劫持行为,不会影响全球 DNS;而且一旦对方真实 IP 变更就会导致访问异常,破坏正常解析,不应在生产环境中随意使用。合法场景仅限于内网测试、灰度引流等受控环境(此时更推荐用 /etc/hosts 或专门的内部域名)。

  3. 为什么修改了区域文件,别人还是解析到旧 IP? 因为各级递归服务器与客户端都按 TTL 缓存了旧记录。做法:变更前提前把该记录 TTL 调小(如 60 秒),等旧 TTL 过期后再变更;变更后可用 dig @权威IP 直接向权威服务器验证,绕过缓存。

  4. 一台服务器可以同时是 A 域的主服务器和 B 域的从服务器吗? 可以。type 是按区域配置的,同一台 named 上不同 zone 可以分别是 master、slave、forward,互不影响。

  5. allow-query 和 allow-recursion 有什么区别? allow-query 控制"谁可以向我提问"(包括查询本机权威区域);allow-recursion 控制"谁可以让我去替他递归查询外部域名"。对外提供权威解析时通常 allow-query { any; } 但 allow-recursion 只放行内网。

最后修改:2026 年 09 月 20 日
如果觉得我的文章对你有用,请随意赞赏