UNIX/Linux系统管理技术手册-读书笔记-第十六章
《UNIX/Linux系统管理技术手册-读书笔记-第十六章
DNS:域名系统
1. DNS概述
1.1 什么是DNS
| 概念 | 说明 | 能做什么 |
|---|---|---|
| DNS(域名系统) | 分布式数据库,将主机名映射为IP地址(反之亦然) | 用户和程序使用名称访问资源,网络层使用IP地址路由 |
| 查询与响应 | 客户端发送名称+记录类型查询,服务器返回资源记录(RR) | 常见查询:A记录(名称→IPv4)、AAAA(名称→IPv6)、MX(邮件路由) |
| 权威服务器 | 正式描述某个区(zone)的数据 | 提供自己负责域名的权威答案 |
| 递归服务器 | 代替客户端完成完整查询(从根→TLD→权威) | 减轻客户端负担,缓存结果提升效率 |
| 缓存 | 存储已解析的答案,TTL(存活时间)控制有效期 | 减少重复查询,降低网络和服务器负载 |
1.2 DNS查询流程(以vangogh.cs.berkeley.edu为例)
- 客户端查询本地递归服务器(如
ns.cs.colorado.edu) - 本地服务器向根服务器查询 → 被引荐到**
.edu顶级域服务器** - 向
.edu服务器查询 → 被引荐到**berkeley.edu权威服务器** - 向
berkeley.edu查询 → 被引荐到**cs.berkeley.edu权威服务器** - 向
cs.berkeley.edu查询 → 获得最终A记录答案 - 沿途所有节点缓存结果(TTL控制有效期)
工具验证:dig +trace 或 drill -T 可手动跟随完整授权链。
1.3 DNS服务模式变迁
| 场景 | 推荐做法 | 说明 |
|---|---|---|
| 外部DNS(面向Internet) | 使用托管DNS服务(AWS Route 53、CloudFlare等) | 成本低、高可用、免运维 |
| 内部DNS(面向内网) | 自行搭建BIND或使用托管服务的内网版本 | 控制力强,便于与内部系统集成 |
| 客户端配置 | 每台主机配置/etc/resolv.conf和/etc/nsswitch.conf |
DNS查询的客户端侧设置 |
2. DNS客户端配置
2.1 /etc/resolv.conf —— 指定名称服务器
| 指令 | 格式 | 说明 |
|---|---|---|
nameserver |
nameserver 192.168.1.1 |
DNS服务器IP地址(最多3个) |
search |
search example.com sub.example.com |
非全限定名称的补全域列表(6~8个,总长≤256字符) |
domain |
domain example.com |
本地域名(与search二选一) |
示例:
search atrust.com booklab.atrust.com
nameserver 63.173.189.1
nameserver 174.129.219.225
行为:按顺序查询服务器,超时后尝试下一个(默认超时5s)。DHCP通常自动填充该文件。
2.2 /etc/nsswitch.conf —— 名称解析顺序
hosts: files dns
files:优先查询/etc/hosts(用于引导期间或覆盖特定映射)dns:查询DNS- 可根据需求调整顺序(如先dns再files)
💡 推荐保留
files在前,确保系统在DNS不可用时仍能解析自身和关键主机。
3. DNS名称空间与资源记录
3.1 关键概念
| 概念 | 说明 |
|---|---|
| 区(Zone) | DNS命名树中的独立管理单元,如example.com的正向区和1.168.192.in-addr.arpa的反向区 |
| 正向区 | 主机名 → IP地址(A/AAAA记录) |
| 反向区 | IP地址 → 主机名(PTR记录),基于in-addr.arpa(IPv4)或ip6.arpa(IPv6) |
| 全限定域名(FQDN) | 以点号结尾的完整域名,如ns1.example.com.(结尾点号在DNS中非常重要) |
| TLD | 顶级域(.com、.org、国家代码如.cn) |
3.2 常见资源记录类型
| 类型 | 功能 | 示例 |
|---|---|---|
| SOA | 区的起始授权(每个区一条) | example.com. IN SOA ns1.example.com. hostmaster.example.com. (2017110200 10800 1200 3600000 3600) |
| NS | 权威名称服务器 | example.com. IN NS ns1.example.com. |
| A | 名称 → IPv4地址 | ns1 IN A 63.173.189.1 |
| AAAA | 名称 → IPv6地址 | f.root-servers.net. IN AAAA 2001:500:2f::f |
| PTR | IP地址 → 名称(反向) | 1 IN PTR ns1.example.com. |
| MX | 邮件路由(优先级值小者优先) | example.com. IN MX 10 mail.example.com. |
| CNAME | 别名(昵称) | ftp IN CNAME anchor.example.com. |
| SRV | 服务位置 | _http._tcp.example.com. SRV 0 0 80 web.example.com. |
| TXT | 任意文本信息 | example.com. IN TXT "v=spf1 mx -all"(SPF反垃圾邮件) |
| DS/DNSKEY/RRSIG | DNSSEC安全相关 | 详见16.10节 |
CNAME限制:
- 区的apex(根域,如
example.com本身)不能是CNAME(RFC1033) - 解决方法:使用AWS Route 53/CloudFlare的“别名”功能(对外表现为A记录,自动同步目标IP)
3.3 SOA记录关键字段
| 字段 | 含义 | 推荐值 |
|---|---|---|
| 序列号 | 区数据版本号,每次修改必须递增 | 推荐YYYYMMDDNN(如2017110200) |
| 刷新 | 从服务器检查主服务器更新的间隔 | 1 |
| 重试 | 刷新失败后的重试间隔 | 10 |
| 过期 | 从服务器停止响应前,主服务器最长不可用时间 | 1 |
| 最小TTL | 否定缓存(查询失败)的存活时间 | 1 |
忘记更新序列号是DNS管理最常见的错误,会导致变更无法传播到从服务器。
3.4 反向区(PTR记录)重要性
A/AAAA和PTR必须匹配,否则会导致某些服务认证失败(如SSH的VerifyReverseMapping)- 示例:A记录
ns1.atrust.com. IN A 63.173.189.1,对应PTR在189.173.63.in-addr.arpa区中:1 IN PTR ns1.atrust.com.
3.5 轮询式DNS负载均衡(Round Robin)
为同一名称配置多个A记录:
www IN A 192.168.1.10
IN A 192.168.1.11
IN A 192.168.1.12
DNS服务器以轮询顺序返回,实现简单的负载分散。粗糙方案,生产环境建议使用专业负载均衡器。
4. BIND配置(核心)
4.1 BIND概述
| 组件 | 说明 |
|---|---|
| named | BIND名称服务器守护进程 |
| rndc | 远程控制命令(管理named) |
| named.conf | 主配置文件 |
| 区文件 | 资源记录数据文件 |
| 根提示文件(root.cache) | 根服务器列表,引导递归查询 |
📖 推荐版本:BIND 9(本书讨论),BIND 10开发中,BIND 4/8已过时。
4.2 named.conf核心语句
| 语句 | 功能 |
|---|---|
options { ... }; |
全局配置(日志、缓存大小、转发器、递归控制等) |
zone "example.com" { ... }; |
定义区(master/slave/hint/forward) |
view "internal" { ... }; |
DNS分割(内外网不同视图) |
acl { ... }; |
访问控制列表(IP地址匹配) |
key { ... }; |
TSIG共享密钥定义 |
logging { ... }; |
日志通道和分类 |
controls { ... }; |
rndc远程控制通道 |
4.3 options语句关键配置
| 选项 | 作用 | 推荐值 |
|---|---|---|
directory |
区文件路径 | /var/named |
recursion |
是否处理递归查询 | 权威服务器no,缓存服务器yes |
allow-query |
允许查询的IP | 内网IP段,外部仅公开服务 |
allow-recursion |
允许递归的客户端 | 仅内网用户 |
allow-transfer |
允许区传输的从服务器 | 仅指定从服务器IP/密钥 |
forwarders |
转发器列表 | 上游DNS服务器IP |
dnssec-enable |
DNSSEC支持 | yes |
dnssec-validation |
DNSSEC验证 | yes(递归服务器) |
max-cache-size |
缓存内存上限 | 根据内存调整(如512M) |
安全最佳实践:
- 对外部可见的服务器设置
recursion no - 用
allow-query限制区传输(allow-transfer) - 避免成为“开放式解析器”(Open Resolver)
4.4 zone语句(主/从/根提示/转发)
主服务器(Master) :
zone "example.com" {
type master;
file "forward/example.com";
allow-query { any; };
allow-transfer { slaves; };
};
从服务器(Slave) :
zone "example.com" {
type slave;
file "slave/example.com.cache"; # 从服务器本地缓存
masters { 192.168.1.1; }; # 主服务器IP
};
根提示(Root Hints) :
zone "." {
type hint;
file "root.cache";
};
转发区(Forward) :
zone "partner.com" {
type forward;
forwarders { 10.0.0.1; };
};
4.5 view语句(DNS分割)
| 场景 | 内部视图(Internal View) | 外部视图(External View) |
|---|---|---|
match-clients |
内网IP(如192.168.0.0/16) |
any |
recursion |
yes |
no |
| 区数据 | 包含所有内部主机(包括私有IP) | 仅公开主机(公网IP) |
示例:
view "internal" {
match-clients { 192.168.0.0/16; };
recursion yes;
zone "example.com" {
type master;
file "internal/example.com";
};
};
view "external" {
match-clients { any; };
recursion no;
zone "example.com" {
type master;
file "external/example.com";
};
};
顺序重要:限制最多的视图放前面,否则
any会提前匹配。
5. DNS安全机制
5.1 访问控制与TSIG
| 机制 | 说明 | 用途 |
|---|---|---|
| ACL(地址匹配列表) | 基于IP地址的访问控制 | allow-query、allow-transfer |
| TSIG(事务签名) | 共享密钥验证通信双方 | 主从服务器间区传输、动态更新认证 |
| TKEY | 自动交换TSIG密钥(Diffie-Hellman) | 简化密钥分发 |
| SIG(0) | 公钥签名事务 | 类似TSIG但使用公钥加密 |
TSIG配置步骤:
named.conf密钥定义:
key master-slave1. {
algorithm hmac-sha256;
secret "owKt6ZW0lu0gaVFkwOqGxA==";
};
在zone语句中应用:
allow-transfer { key master-slave1.; };
时钟同步:TSIG依赖时间戳,需用NTP保持服务器时钟同步(差异>5min会导致验证失败)。
5.2 DNSSEC(DNS Security Extensions)
| 概念 | 说明 |
|---|---|
| 目的 | 认证数据来源和完整性(防篡改、防欺骗) |
| 信任链 | 根 → 顶级域 → 二级域,每个父区签署子区的DS记录 |
| 密钥对 | KSK(key-signing key,签名ZSK)和ZSK(zone-signing key,签名记录集) |
| 记录类型 | DNSKEY(公钥)、RRSIG(签名)、DS(父区存子区密钥指纹)、NSEC/NSEC3(否定答复签名) |
部署步骤(简要) :
- 生成KSK和ZSK:
dnssec-keygen -a RSASHA256 -b 2048 -f KSK example.com - 使用
dnssec-signzone签名区文件 - 将
.signed文件配置到named.conf - 将DS记录提交给父区(注册商)
维护:
- ZSK定期轮换(3个月~1年),采用“预公布”方案
- 签名的区文件不可手动编辑,需重新签名
DNSSEC配置复杂,新手建议使用托管DNS服务(如AWS Route 53已内置DNSSEC支持)。
5.3 开放式解析器风险
- 可被任何人利用进行DNS放大攻击(反射攻击)
- 建议用
allow-recursion限制仅为内部用户服务 - 测试:访问DNS TOOLS网站“Open Resolver Test”
5.4 chroot环境运行named
|
|
- 限制named进程可见文件系统范围
- 需在chroot中复制必要文件(
/dev/null、区文件、配置等)
6. 调试工具
6.1 dig —— 核心查询工具
| 用法 | 功能 |
|---|---|
dig example.com |
查询A记录(默认) |
dig example.com MX |
查询MX记录 |
dig @8.8.8.8 example.com |
指定DNS服务器查询 |
dig -x 63.173.189.1 |
反向查询(PTR记录) |
dig +trace example.com |
从根服务器追踪授权链 |
dig +short example.com |
精简输出(仅IP) |
dig ANY example.com |
查询所有记录(仅返回缓存数据,非权威全量) |
6.2 drill(DNSSEC调试增强版)
6.3 nslookup / host
- 更简单的查询工具,适合快速检查
nslookup example.comhost -t MX example.com
6.4 rndc —— 运行时控制
| 命令 | 功能 |
|---|---|
rndc reload |
重新加载配置和所有区 |
rndc reload example.com |
仅重新加载指定区 |
rndc reconfig |
重新读取配置文件(添加新区) |
rndc freeze example.com |
暂停动态更新,允许手动编辑区文件 |
rndc thaw example.com |
恢复动态更新 |
rndc dumpdb |
转储缓存到named_dump.db |
rndc querylog |
动态启用/禁用查询日志 |
rndc flush |
清空缓存 |
rndc stop / rndc halt |
停止named |
7. 常见错误与排查
7.1 常见日志消息
| 消息 | 含义 | 解决方法 |
|---|---|---|
lame server resolving |
某个区授权了不存在的名称服务器 | 检查父区和子区的NS记录一致性 |
No default TTL set |
区文件缺少$TTL指令 |
在文件顶部添加$TTL 1d |
No NS RRs found |
SOA记录后缺少NS记录 | 添加NS记录,注意缩进 |
Address already in use |
端口53被占用 | 检查是否有另一个named在运行 |
Too many timeouts ... disabling EDNS |
防火墙阻止大UDP分组 | 检查防火墙允许UDP 53或降级DNS |
rejected zone |
区文件解析错误 | 检查文件语法(遗漏点号、括号等) |
7.2 检查残缺授权(Lame Delegation)
父区授权了不存在的名称服务器,或子区未接受授权。
诊断方法:
7.3 正向/反向区不一致
- A记录和PTR记录不匹配导致认证延迟或失败
- 修改IP后务必同步更新反向区
7.4 忘记更新序列号
- 从服务器不会加载新数据
- 修复:更新主服务器序列号 → 等待刷新周期 → 或手动
rndc reload example.com
8. 本章核心命令速查表
| 命令/文件 | 功能 |
|---|---|
dig example.com |
查询A记录 |
dig @8.8.8.8 example.com MX |
指定服务器查询MX |
dig -x 63.173.189.1 |
反向查询 |
dig +trace example.com |
从根跟踪授权链 |
drill -T example.com |
类似dig +trace |
nslookup example.com |
简单查询 |
rndc reload |
重新加载配置 |
rndc querylog |
切换查询日志 |
rndc flush |
清空缓存 |
dnssec-keygen -a HMAC-SHA256 -b 128 -n HOST keyname |
生成TSIG密钥 |
dnssec-signzone -N increment example.com |
签名区文件 |
/etc/resolv.conf |
DNS客户端配置 |
/etc/nsswitch.conf |
名称解析顺序 |
/etc/named.conf |
BIND主配置文件 |
/var/named/ |
BIND区文件目录(典型) |
DBA视角补充:
- 数据库集群内部DNS:如MongoDB、Cassandra等分布式数据库通常使用DNS(SRV记录或A记录列表)发现集群节点。确保内部DNS稳定可靠是数据库高可用的前提。
- 连接字符串与DNS:应用数据库连接字符串使用域名而非IP,便于迁移和灾备切换(通过修改DNS即可切换流量)。需注意DNS TTL设置,太长的TTL会导致切换延迟。
- 数据库的PTR记录:某些数据库安全配置会检查客户端IP反向解析,确保PTR记录正确可避免认证延迟。
- 内部DNS自建 vs 托管:对于生产数据库集群,推荐使用自建BIND或内部托管DNS服务(如AWS Route 53 Private Hosted Zone),避免依赖公网DNS解析内部服务。
- 动态DNS更新:在DHCP环境中,结合BIND的动态更新(
nsupdate)可自动为数据库节点注册DNS记录,简化节点扩缩容的DNS维护。- DNSSEC与数据库:DNSSEC主要用于公网安全,内部数据库服务通常不需要启用(增加复杂性和延迟)。
文章作者 会写代码的小郎中
上次更新 2011-06-27
许可协议 CC BY-NC-ND 4.0