Skip to main content

4. Name Servers (名称服务器)

本章深入探讨DNS名称服务器的内部工作原理、区域管理和查询算法。


4.1. Introduction (简介)

名称服务器是构成域数据库的信息存储库。数据库被划分为称为区域 (zones) 的部分,这些区域分布在名称服务器之间。

基本任务

虽然名称服务器可以有几个可选功能和数据源,但名称服务器的基本任务是使用其区域中的数据回答查询。

设计特点:

  • 名称服务器可以以简单的方式回答查询
  • 响应始终可以仅使用本地数据生成
  • 响应包含问题的答案或对"更接近"所需信息的其他名称服务器的引用

冗余性要求

给定区域将从多个名称服务器可用,以确保其在主机或通信链路故障时的可用性。

要求:

  • ✅ 通过管理规定,每个区域必须在至少两个服务器上可用
  • ✅ 许多区域的冗余度超过此要求

示例架构:

example.com 区域
├── ns1.example.com (主服务器)
├── ns2.example.com (从服务器1)
└── ns3.backup.net (从服务器2,异地)

权威性和缓存

给定名称服务器通常支持一个或多个区域,但这仅为其提供有关域树小部分的权威信息。

数据类型:

  1. 权威数据 (Authoritative Data)

    • 服务器负责的区域数据
    • 标记为权威响应
  2. 缓存数据 (Cached Data)

    • 关于树其他部分的非权威数据
    • 标记为非权威响应

响应标记:

查询 www.example.com
→ 权威服务器: AA=1 (Authoritative Answer)
→ 缓存数据: AA=0 (Non-Authoritative)

4.2. How the database is divided into zones (数据库如何划分为区域)

域数据库以两种方式分区:按 (class) 和在名称空间中节点之间的切割 (cuts)。

按类分区 (Class Partition)

类分区很简单。任何类的数据库都与所有其他类分开组织、委派和维护。

特点:

  • 按照惯例,所有类的名称空间相同
  • 可以将单独的类视为并行名称空间树的数组
  • 附加到节点的数据对于这些不同的并行类将不同

创建新类的原因:

  1. 现有类型需要新的数据格式
  2. 希望有现有名称空间的单独管理版本

可视化:

IN类 (Internet):
.
/|\
a b c

CH类 (Chaos):
.
/|\
a b c

HS类 (Hesiod):
.
/|\
a b c

按切割分区 (Cuts in Name Space)

在类内,可以在任意两个相邻节点之间进行"切割"。

区域定义:

  • 进行所有切割后,每组连接的名称空间是一个单独的区域
  • 区域被称为对连接区域中所有名称具有权威性
  • 名称空间中的"切割"对于不同类可能在不同位置

规则:

  • ✅ 每个区域至少有一个节点,因此有域名
  • ✅ 特定区域中的所有节点都是连接的
  • ⭐ 每个区域都有一个最高节点,它比区域中任何其他节点更接近根
  • ⭐ 此节点的名称通常用于标识区域

区域示例:

        . (根区域)
|
+---+---+
| |
com org (com区域从这里开始)
|
example (example.com区域从这里开始)
|
+--+--+
| |
www mail (都在example.com区域内)

委派控制 (Delegation Control)

数据库在特定组织想要接管子树控制权的点进行分区。

组织控制权: 一旦组织控制其自己的区域,它可以单方面:

  • ✅ 更改区域中的数据
  • ✅ 增长连接到区域的新树部分
  • ✅ 删除现有节点
  • ✅ 在其区域下委派新的子区域

内部分区:

  • 如果组织有子结构,可能希望进行进一步的内部分区
  • 实现名称空间控制的嵌套委派
  • 有些划分纯粹是为了使数据库维护更方便

4.2.1. Technical considerations (技术考虑)

区域数据的四个主要部分

描述区域的数据有四个主要部分:

1. 区域内所有节点的权威数据 (Authoritative Data)

区域顶部节点到叶节点或区域底部边缘切割上方节点的所有RR。

示例:

example.com.  3600  IN  SOA   ns1.example.com. admin.example.com. (...)
example.com. 3600 IN NS ns1.example.com.
example.com. 3600 IN NS ns2.example.com.
example.com. 3600 IN A 93.184.216.34
www.example.com. 3600 IN A 93.184.216.34
mail.example.com. 3600 IN A 93.184.216.35

2. 定义区域顶部节点的数据 (Top Node Data)

关键RR类型:

NS记录: 列出区域的所有服务器,每个服务器一个RR

example.com.  3600  IN  NS  ns1.example.com.
example.com. 3600 IN NS ns2.example.com.

SOA记录: 描述区域管理参数的单个记录

example.com.  3600  IN  SOA  ns1.example.com. admin.example.com. (
2024010101 ; Serial (序列号)
3600 ; Refresh (刷新间隔)
1800 ; Retry (重试间隔)
604800 ; Expire (过期时间)
86400 ) ; Minimum TTL (最小TTL)

SOA字段说明:

  • Serial: 区域的版本号,用于同步
  • Refresh: 从服务器检查更新的间隔
  • Retry: 刷新失败后的重试间隔
  • Expire: 如果无法刷新,何时停止提供区域
  • Minimum TTL: 否定响应的缓存时间

3. 描述委派子区域的数据 (Delegated Subzones)

描述区域底部边缘切割的NS RR,命名子区域的服务器。

特点:

  • 这些RR不是区域权威数据的一部分
  • 应该与子区域顶部节点中的相应RR完全相同

示例:

; 父区域 (example.com)
sub.example.com. 3600 IN NS ns1.sub.example.com.
sub.example.com. 3600 IN NS ns2.sub.example.com.

; 子区域 (sub.example.com) - 应该有相同的NS记录

位置规则:

  • NS RR仅在作为某个区域顶部节点的节点处找到
  • 在区域数据中,NS RR位于:
    • ✅ 区域的顶部节点 (权威的)
    • ✅ 区域底部边缘的切割处 (非权威的)
    • ❌ 从不在两者之间

4. 允许访问子区域名称服务器的数据 (Glue Data)

问题: 子区域的NS RR命名服务器,但不提供地址

场景: 如果名称服务器的名称本身在子区域中,我们可能面临循环依赖:

要查询 ns1.sub.example.com 的地址
→ 需要联系 sub.example.com 的服务器
→ 但 sub.example.com 的服务器就是 ns1.sub.example.com
→ 循环!

解决方案: "粘合"记录 (Glue Records)

; 父区域中的委派
sub.example.com. 3600 IN NS ns1.sub.example.com.
sub.example.com. 3600 IN NS ns2.sub.example.com.

; 粘合记录 - 打破循环依赖
ns1.sub.example.com. 3600 IN A 192.0.2.1
ns2.sub.example.com. 3600 IN A 192.0.2.2

规则:

  • 仅当名称服务器的名称在切割"下方"时才需要
  • 仅作为引用响应的一部分使用
  • 不是权威数据的一部分

区域传输

方法:

  • 通过传输RR在名称服务器之间传输整个区域
  • 可以在一系列消息中传输
  • 或通过FTP传输主文件 (文本表示)

区域文件示例:

$ORIGIN example.com.
$TTL 3600

@ IN SOA ns1.example.com. admin.example.com. (
2024010101 3600 1800 604800 86400 )
IN NS ns1.example.com.
IN NS ns2.example.com.
IN MX 10 mail.example.com.
IN A 93.184.216.34

www IN A 93.184.216.34
mail IN A 93.184.216.35

4.2.2. Administrative considerations (管理考虑)

创建新子区域的步骤

步骤1: 识别父区域

当某个组织想要控制其自己的域时,第一步是识别适当的父区域,并让父区域的所有者同意委派控制权。

约束:

  • 技术上,树中何处可以完成此操作没有特定限制
  • 管理上,有一些分组:
    • 顶层组织在 [RFC-1032] 中讨论
    • 中级区域可以自由创建自己的规则

组织策略示例:

大学A: 使用单个区域
university-a.edu

大学B: 按部门组织子区域
university-b.edu
├── cs.university-b.edu (计算机科学)
├── ee.university-b.edu (电气工程)
└── lib.university-b.edu (图书馆)

步骤2: 演示冗余支持

新所有者应该被要求演示冗余的名称服务器支持。

重要概念:

  • 区域的服务器不需要驻留在该域中有名称的主机中
  • 如果服务器广泛分布,区域通常对整个互联网更易访问
  • 而不是在管理区域的同一组织控制的物理设施内

地理分布示例:

uk域 (United Kingdom)
├── ns1.uk (英国本地)
├── ns2.uk (英国本地)
└── ns3.usa.net (美国) ← 提供跨大西洋冗余

好处:

  • 美国主机可以获取UK数据而无需使用有限的跨大西洋带宽
  • 提高全球可访问性和性能

步骤3: 添加委派记录

作为最后的安装步骤,应将委派NS RR和粘合RR添加到父区域。

一致性要求:

  • 两个区域的管理员应确保标记切割两侧的NS和粘合RR一致
  • 并保持一致

委派配置:

; 父区域 (example.com) 配置
sub.example.com. 86400 IN NS ns1.sub.example.com.
sub.example.com. 86400 IN NS ns2.sub.example.com.
ns1.sub.example.com. 86400 IN A 192.0.2.1
ns2.sub.example.com. 86400 IN A 192.0.2.2

; 子区域 (sub.example.com) 配置
@ IN SOA ns1.sub.example.com. admin.sub.example.com. (...)
IN NS ns1.sub.example.com.
IN NS ns2.sub.example.com.

4.3. Name server internals (名称服务器内部)

4.3.1. Queries and responses (查询和响应)

名称服务器的主要活动是回答标准查询。

查询组件:

  • QTYPE: 所需信息的类型
  • QCLASS: 所需信息的类
  • QNAME: 感兴趣的名称

查询模式

非递归模式 (Non-Recursive Mode)

特点:

  • 服务器最简单的模式
  • 仅使用本地信息回答查询
  • 响应包含:错误、答案或引用

要求: ✅ 所有名称服务器必须实现非递归查询

响应类型:

1. 权威名称错误 (NXDOMAIN)
2. 临时错误
3. 组合:
- 回答问题的RR + 数据来源指示
- 对更接近祖先区域的名称服务器的引用
- 服务器认为有用的其他RR

递归模式 (Recursive Mode)

特点:

  • 客户端最简单的模式
  • 名称服务器充当解析器角色
  • 返回错误或答案,从不引用

要求: ⚠️ 此服务在名称服务器中是可选的

服务器可以选择:

  • 限制可以使用递归模式的客户端
  • 完全不提供递归服务

响应类型:

1. 查询的答案 (可能前面有CNAME RR)
2. 名称错误 (NXDOMAIN)
3. 临时错误指示

递归服务的有用场景

  1. 简单请求者: 缺乏使用直接答案以外的能力
  2. 协议桥接: 需要跨越协议或其他边界
  3. 集中缓存: 希望集中缓存而不是每个客户端单独缓存的网络

递归控制位

RA位 (Recursion Available):

  • 在所有响应中由名称服务器设置或清除
  • 如果名称服务器愿意为客户端提供递归服务,则为真
  • 无论客户端是否请求递归服务
  • RA信号可用性而不是使用

RD位 (Recursion Desired):

  • 查询包含的位
  • 指定请求者是否想要此查询的递归服务
  • 客户端可以从任何名称服务器请求递归服务
  • 但应该仅依赖从先前发送过RA的服务器接收它

协商机制:

客户端查询:
RD=1 (我想要递归)

服务器响应:
RA=1, RD=1 → 递归模式已使用 ✓
RA=0, RD=1 → 递归不可用,返回引用

重要规则:

  • 除非通过RD请求,否则名称服务器不应执行递归服务
  • 这避免干扰名称服务器及其数据库的故障排除

4.3.2. Algorithm (算法)

名称服务器使用的实际算法将取决于本地OS和用于存储RR的数据结构。

标准查询算法

以下算法假设RR组织在几个树结构中,每个区域一个,另一个用于缓存:

步骤1: 设置递归可用位

根据名称服务器是否愿意提供递归服务,在响应中设置或清除RA值。

如果 (递归可用 AND 通过查询中的RD位请求):
转到步骤5 (递归处理)
否则:
转到步骤2 (非递归处理)

步骤2: 搜索可用区域

搜索可用区域以查找最接近QNAME祖先的区域。

如果找到这样的区域:
转到步骤3
否则:
转到步骤4

步骤3: 在区域中逐标签匹配

从区域向下,逐标签匹配。匹配过程可以以几种方式终止:

情况a: 匹配整个QNAME

找到了节点。

如果节点的数据是CNAME AND QTYPE不匹配CNAME:
1. 将CNAME RR复制到响应的答案部分
2. 将QNAME更改为CNAME RR中的规范名称
3. 返回步骤1
否则:
1. 将所有匹配QTYPE的RR复制到答案部分
2. 转到步骤6

情况b: 匹配将使我们离开权威数据

这是一个引用。当遇到带有NS RR的节点标记区域底部边缘的切割时发生。

1. 将子区域的NS RR复制到响应的权威部分
2. 将可用地址放入附加部分
- 使用粘合RR (如果地址不可从权威数据或缓存获得)
3. 转到步骤4

情况c: 在某个标签处匹配不可能

查找通配符。

如果"*"标签不存在:
如果我们查找的名称是查询中的原始QNAME:
在响应中设置权威名称错误并退出
否则:
只是退出 (跟随CNAME时)

如果"*"标签存在:
1. 将该节点的RR与QTYPE匹配
2. 如果有匹配,复制到答案部分
3. 设置RR的所有者为QNAME (不是带"*"标签的节点)
4. 转到步骤6

步骤4: 在缓存中匹配

开始在缓存中向下匹配。

如果在缓存中找到QNAME:
1. 将附加到它的所有匹配QTYPE的RR复制到答案部分
2. 如果没有来自权威数据的委派:
- 从缓存中查找最佳的
- 将其放入权威部分
3. 转到步骤6

步骤5: 递归解析

使用本地解析器或其算法的副本来回答查询。

1. 使用解析器回答查询
2. 将结果 (包括任何中间CNAME) 存储在响应的答案部分
3. 转到步骤6

步骤6: 添加附加RR

仅使用本地数据,尝试向查询的附加部分添加其他可能有用的RR。

示例: MX记录的邮件服务器地址
query: example.com MX
answer: example.com MX 10 mail.example.com
additional: mail.example.com A 93.184.216.34

退出算法。


4.3.3. Wildcards (通配符)

基本概念

定义: 所有者名称以标签*开头的RR称为通配符。

用途: 通配符RR可以被视为用于合成RR的指令。

工作原理:

当满足适当条件时,名称服务器创建RR:
- 所有者名称 = 查询名称
- 内容 = 从通配符RR中获取

常见用例

最常用于创建将用于将邮件从互联网转发到其他邮件系统的区域。

概念: 向服务器查询中呈现的该区域中的任何名称都将被假定存在,具有某些属性,除非存在明确的相反证据。

示例:

; 为example.com中所有未明确定义的主机创建A记录
*.example.com. 3600 IN A 192.0.2.100

; 查询
unknown.example.com → 返回 192.0.2.100
anything.example.com → 返回 192.0.2.100

; 但如果有明确定义
www.example.com. 3600 IN A 93.184.216.34
→ 查询www.example.com返回 93.184.216.34 (不使用通配符)

通配符规则

所有者名称格式: *.<anydomain>

约束:

  • <anydomain>不应包含其他*标签
  • 应该在区域的权威数据中
  • 通配符可能适用于<anydomain>或其下任何节点的查询

重要: 术语"区域"而不是"域"的使用是有意的

  • 这些默认值不跨区域边界传播
  • 尽管子区域可以通过设置类似默认值来选择实现该外观

通配符匹配示例

$ORIGIN example.com.
*.example.com. IN A 192.0.2.100
*.sub.example.com. IN A 192.0.2.200

; 查询结果
test.example.com → 192.0.2.100 (匹配第一个通配符)
test.sub.example.com → 192.0.2.200 (匹配第二个通配符)
a.b.example.com → 192.0.2.100 (匹配第一个通配符)
www.example.com → 如果明确定义,使用明确定义的值

4.3.4. Negative response caching (Optional) (负响应缓存,可选)

概念

当名称服务器发现名称不存在时,它可以缓存此信息。

好处:

  • 减少对权威服务器的查询
  • 提高性能
  • 减少网络流量

实现考虑

缓存时间: 使用SOA记录中的最小TTL字段

缓存内容:

查询: nonexistent.example.com
响应: NXDOMAIN (名称不存在)
缓存: "nonexistent.example.com在接下来的N秒内不存在"

注意: 此功能在RFC 1034中标记为可选,后来在RFC 2308中标准化。


关键概念总结

名称服务器架构

  1. 区域存储: 分布式数据库,按区域组织
  2. 查询处理: 递归和非递归两种模式
  3. 缓存机制: 提高性能和减少负载
  4. 冗余设计: 每个区域至少2个服务器

区域管理

  1. 委派机制: 父区域委派给子区域
  2. 粘合记录: 解决循环依赖
  3. 区域传输: 主从同步机制
  4. 一致性维护: 父子区域NS记录一致

查询算法

  1. 分步处理: 清晰的算法流程
  2. 递归支持: 可选但推荐
  3. 通配符处理: 灵活的默认值
  4. 缓存优化: 本地缓存提高性能

下一章: 5. Resolvers (解析器) - 探讨DNS解析器的工作原理和实现