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 的特点:
- 是一个分布式数据库(数据分散存放在全球无数台服务器上,没有任何一台服务器保存全部数据);
- 解决数据不一致问题,避免名字冲突(每个域的数据由该域的权威服务器负责);
- 有缓存机制,提高性能和可靠性;
- 采用分层(树状)结构,理论上最多 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 域名的命名规则
- 可用字符:
- 26 个英文字母(
a~z),不区分大小写; - 数字
0~9; - 中横线/连字符
-。
- 26 个英文字母(
- 组合规则:
- 英文字母不区分大小写;
- 域名长度有一定限制(单个标签最长 63 字符,整个 FQDN 最长 255 字符);
- 一些特定/保留词汇不能注册;
- 注册有年限,到期需续费。
- 好域名具备的特点:
- 短小、简短易记;
- 不易混淆、不易拼写错误;
- 与公司名称或核心业务相关;
- 尽量不与文化相冲突。
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 |
| |
+-------------+
步骤说明:
- 客户端(Resolver)向本地 DNS 服务器 NS1 发起递归查询,请求
mail.google.com的 IP 地址,NS1 必须回复答案或错误信息。 - NS1 没有相关记录(也没有缓存),于是联系根域服务器查询,使用迭代查询。
- 根域服务器没有相关主机记录,向 NS1 回复
com域服务器的联系方式(NS 记录 + 对应的 A 记录,即"胶水记录")。 - NS1 联系
com域服务器查询,使用迭代查询。 com域服务器没有相关记录,向 NS1 回复google.com域服务器的联系方式。- NS1 联系
google.com域服务器查询,使用迭代查询。 google.com域服务器是该域的权威服务器,有相关记录,向 NS1 回复mail.google.com的 IP 地址(权威回答)。- 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、retry15M、expire1W、minimum1D。
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.arpa192.168.1.x→1.168.192.in-addr.arpa10.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 从服务器的准备工作
与主服务器一致:
- 设置主机名;
- 时间同步(区域传送对时间敏感,建议配置 ntpd/chronyd);
- 关闭或放行 iptables/firewalld,关闭或正确配置 SELinux:
iptables -L # 查看规则
iptables -F # 清空规则
chkconfig iptables off # CentOS 6
ls /selinux/ # 有数据表示 SELinux 开启
vim /etc/selinux/config
# SELINUX=disabled
reboot # 完全关闭需重启
# 临时切换为警告模式(不拒绝操作):
setenforce 0
- 配置好 yum 源,安装 BIND:
yum install bind* -y
4.1.2 主服务器侧配置
- 区域文件中必须把从服务器列入 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
- 在区域声明中限制允许区域传送的对象(安全加固):
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; };再在需要的区域单独开放。
- 重启服务:
/etc/init.d/named restart # CentOS 6
sudo systemctl restart named # CentOS 7
4.1.3 从服务器侧配置
named.conf的options段配置与主服务器相同(listen-on、allow-query均改为any),并确保 DNSSEC 关闭:
dnssec-enable no;
dnssec-validation no;
- 编辑从服务器的区域声明文件
/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
};
- 启动/重启从服务器的 named 服务:
/etc/init.d/named start # CentOS 6
sudo systemctl restart named # CentOS 7
- 验证 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 机制
同步被触发有两条路径:
- 被动(refresh 轮询):从服务器每隔
refresh秒主动向主服务器查询 SOA,比较序列号;主服务器的 serial 大于自己保存的 serial 时才发起区域传送。 - 主动(notify 通知):主服务器区域数据重新加载后,立即向区域内所有 NS 记录列出的服务器(以及
also-notify指定的地址)发送 NOTIFY 报文,从服务器收到后立即来查询 SOA 并同步——这条路径快得多。
因此每次修改主服务器区域文件后,必须手动把 serial 改大,否则无论怎么重启,从服务器都不会更新(这是最高频的"主从不同步"原因)。
4.1.6 验证主从同步
- 在主服务器上修改区域文件,添加新记录或修改现有记录,并增大版本号(序列号);教学时建议把 refresh 时间改小(如 10~60 秒)以便快速观察。
- 重启(或重载)主服务器服务:
/etc/init.d/named restart # CentOS 6
sudo systemctl restart named # CentOS 7
rndc reload abc.com # 只重载指定区域,更优雅
- 在从服务器上观察同步:
# 方式一:删除已同步的文件后重启服务,看是否被重新拉取
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
- 直接向从服务器查询新记录,确认能查到:
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)。
- 确保主配置文件中以下两行设置为
no:
dnssec-enable no;
dnssec-validation no;
- 编辑主配置文件
/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";
};
- 重启服务器:
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 正向能解析、反向不行
按顺序检查:
named.rfc1912.zones中是否声明了反向区域;- 反向区域名是否与网段匹配(
192.168.0.x→0.168.192.in-addr.arpa,注意反序、注意不要写成别的网段); - 反向区域文件是否存在、
file路径是否与声明一致、权限是否正确; named-checkzone 0.168.192.in-addr.arpa /var/named/data/master.0.168.192.in-addr.arpa.zone是否 OK;- PTR 记录左侧是否写的是主机位数字(相对名),右侧是否为以点结尾的 FQDN;
- 序列号是否递增、服务是否重载;
- 验证:
dig -x 192.168.0.183/nslookup 192.168.0.183。
补充:反向解析在公网上由 IP 地址的持有者(运营商/云厂商)配置,自建 DNS 无法为不属于自己的公网 IP 提供有效的公网反向解析。
5.7.4 从服务器不同步
检查清单:
- 主服务器 SOA 的 serial 是否递增(最常见原因,没改大就绝对不会同步);
- 主服务器
allow-transfer是否放行了从服务器 IP; - 从服务器区域
type slave+masters { 主IP; };是否正确; - 防火墙是否放行 TCP 53(区域传送走 TCP,只放 UDP 会导致"能查询但不能同步");
/var/named/slaves/目录对named用户是否可写(chown named:named,chmod 770),SELinux 是否允许(setsebool -P named_write_master_zones on或setenforce 0);- 主从时间是否同步;
- 主区域的 NS 记录中是否包含从服务器(影响 notify);
- 手工强制同步与观察:
# 从服务器上
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 修改区域文件后不生效
按下面顺序逐项排除:
- 忘记递增 serial——影响从服务器同步(主服务器自身重载通常仍会生效,但从服务器不会);
- 忘记重载服务——执行
rndc reload或systemctl reload named/service named reload; - 缓存未过期——记录的旧值还在缓存里:
- 本机 named 缓存:
rndc flush或rndc flushname www.abc.com; - 客户端/中间递归服务器缓存:只能等 TTL 到期,或直接向权威服务器查询绕过缓存:
dig @权威IP www.abc.com; - 系统级缓存:
nscd -i hosts、systemd-resolve --flush-caches;Windows 用ipconfig /flushdns;
- 本机 named 缓存:
- 改错了文件——安装 bind-chroot 后误改了
/var/named/chroot/...下的副本,或file指向的其实是另一个文件;用rndc status、named-checkconf -z确认实际加载的是哪个文件; - 被
/etc/hosts覆盖——/etc/nsswitch.conf中files在dns之前,本机 hosts 里有同名条目; - 客户端问的不是这台服务器——检查
/etc/resolv.conf,或用dig输出末尾的;; SERVER:行确认实际应答者; - 动态更新过的区域——存在
.jnl文件时手工编辑无效,需rndc freeze abc.com→ 编辑 →rndc thaw abc.com。
5.7.8 其他易错点
/etc/resolv.conf配置问题:该文件记录本机程序默认联系的 DNS 服务器,ping www.gnu.org这类命令都依赖它。配置好自己的 DNS 服务器后测试时,应在此文件中写上自己的服务器 IP 地址;为防止冲突混淆,应把文件中原有的记录注释或删除。- 数据库文件中的映射关系不被校验:DNS 数据库文件中的"名字"和"IP 地址"表示的仅是从名字到 IP 的映射关系,该 IP 地址是否真实存在、主机是否在线,DNS 服务器并不关心也不会校验。只需保证记录格式正确,解析即可生效。
- 区域声明文件路径与实际路径不一致:区域声明文件中所使用的数据库文件路径,必须与数据库文件的真实路径一致。
directory指令指定相对路径的基准目录(默认为/var/named),并注意文件权限与 SELinux 上下文。 - FQDN 忘记加末尾的点:会被自动补上当前域名,产生
www.abc.com.abc.com.这样的错误记录。 /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 注意事项汇总
- DNS 服务器最多 3 个:
/etc/resolv.conf中nameserver条目最多生效 3 条。 - 递归与迭代查询角色:客户端对本地 DNS 通常使用递归查询;本地 DNS 向上级服务器使用迭代查询。
- 文件路径一致性:区域声明中的
file路径必须与实际数据库文件路径一致(相对directory)。 - 记录仅为映射关系:DNS 不验证 IP 地址对应主机是否真实存在。
- 测试前修改
/etc/resolv.conf:验证自建 DNS 时,先将客户端 DNS 指向自建服务器,避免与原有配置混淆。 - 查看日志定位问题:服务启动失败时,优先使用
journalctl -xe(CentOS 7)或tail /var/log/messages(CentOS 6)获取详细报错。 - 改区域文件必递增 serial:这是主从同步的唯一依据。
- UDP 53 与 TCP 53 都要放行。
allow-transfer必须限制,防止区域数据被整体拖走。- 对外服务的权威 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。
参考答案要点:
- 浏览器/系统解析器先查浏览器自身 DNS 缓存与系统缓存(nscd/systemd-resolved);
- 按
/etc/nsswitch.conf中hosts: files dns的顺序,先查/etc/hosts,命中则直接使用; - 未命中则读取
/etc/resolv.conf,向第一个nameserver发起递归查询; - 本地 DNS 服务器若有缓存则直接返回(非权威回答);否则依据
named.ca向根服务器发起迭代查询; - 根返回
.com顶级域服务器地址 → 查询.com→ 返回baidu.com权威服务器地址 → 查询baidu.com权威服务器 → 得到www.baidu.com的 A 记录(可能先经过 CNAME 链); - 本地 DNS 把结果返回客户端并按 TTL 缓存;
- 浏览器拿到 IP 后与其建立 TCP 连接(三次握手,80/443 端口),必要时完成 TLS 握手;
- 发送 HTTP 请求(Host 头为
www.baidu.com),服务器按虚拟主机分发并返回响应; - 浏览器渲染页面,页面中的其他资源域名重复上述解析过程。
练习 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 记录),重启服务。
从服务器:
- 确保主配置文件中
dnssec-enable no;、dnssec-validation no;; - 在
/etc/named.rfc1912.zones中添加type slave的abc.com区域,masters { 192.168.0.183; };; - 重启 named:
sudo systemctl restart named; - 测试:在主服务器上添加新记录或修改现有记录并增大序列号,重载主服务器;然后用
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 # 兜底视图结果
附:常见问题
-
自己搭的 DNS 服务器如何与运营商联系起来,让全球能访问到自己域的解析? 需要在域名注册商/运营商处将该域的 NS 记录指向自己的 DNS 服务器(填写 NS 主机名与对应的公网 IP,即注册"DNS 主机记录/glue"),由上级域完成委派,全球查询才会被引导到你的服务器。同时你的服务器必须有固定公网 IP、放行 UDP/TCP 53,并建议至少部署两台(主 + 从)。
-
自己的 DNS 里能否写上
qq.com的域和 IP 对应? 技术上可以配置(本机会成为该域的"权威"并给出权威回答),但这只对把 DNS 指向你服务器的客户端生效,属于内部解析/DNS 劫持行为,不会影响全球 DNS;而且一旦对方真实 IP 变更就会导致访问异常,破坏正常解析,不应在生产环境中随意使用。合法场景仅限于内网测试、灰度引流等受控环境(此时更推荐用/etc/hosts或专门的内部域名)。 -
为什么修改了区域文件,别人还是解析到旧 IP? 因为各级递归服务器与客户端都按 TTL 缓存了旧记录。做法:变更前提前把该记录 TTL 调小(如 60 秒),等旧 TTL 过期后再变更;变更后可用
dig @权威IP直接向权威服务器验证,绕过缓存。 -
一台服务器可以同时是 A 域的主服务器和 B 域的从服务器吗? 可以。
type是按区域配置的,同一台 named 上不同 zone 可以分别是 master、slave、forward,互不影响。 -
allow-query和allow-recursion有什么区别?allow-query控制"谁可以向我提问"(包括查询本机权威区域);allow-recursion控制"谁可以让我去替他递归查询外部域名"。对外提供权威解析时通常allow-query { any; }但allow-recursion只放行内网。
此处评论已关闭