跳到主要内容

5. 资源记录集

每条 DNS 资源记录 (Resource Record, RR) 都有一个标签, 类别, 类型和数据. 若两条记录曾出现标签, 类别, 类型和数据全部相同的情况, 那是没有意义的 -- 服务器遇到这类重复记录时应将其抑制掉. 然而, 对大多数记录类型而言, 可能存在标签, 类别和类型相同但数据不同的多条记录. 这样一组记录在此被定义为资源记录集 (Resource Record Set, RRSet).

5.1. 从 RRSet 发送 RR​

对特定 (或非特定) 标签, 类别和类型的查询, 将始终返回相关联 RRSet 中的所有记录 -- 无论那是单条还是多条 RR. 如果整个 RRSet 无法装入响应, 则必须将该响应标记为 "截断 (truncated)".

5.2. RRSet 中 RR 的 TTL​

资源记录还有一个生存时间 (time to live, TTL). RRSet 中的各条 RR 有可能具有不同的 TTL. 尚未发现这种做法的任何用途是其他方式无法更好实现的. 然而, 这可能导致缓存服务器给出部分回复 (未标记为 "截断"), 即 RRSet 中部分而非全部 RR 的 TTL 已经过期.

因此, 在 RRSet 中使用不同的 TTL 在此被弃用, RRSet 中所有 RR 的 TTL 必须相同.

如果客户端收到一个响应, 其中包含来自某个 TTL 互不相同的 RRSet 的 RR, 它应将其视为错误. 如果相关 RRSet 来自对此数据而言非权威的来源, 客户端应直接忽略该 RRSet; 如果确实需要这些值, 则应设法从权威来源获取它们. 被配置为将所有查询发送到一个或多个特定服务器的客户端, 为此目的应将这些服务器视为权威的. 如果权威来源发送了这样一个格式错误的 RRSet, 客户端在所有用途上都应将这些 RR 视为: RRSet 中所有 TTL 都已被设为该 RRSet 中最低 TTL 的值. 在任何情况下, 服务器都不得发送 TTL 并非全部相等的 RRSet.

5.3. DNSSEC 特殊情况​

DNS 安全 (DNS Security, DNSSEC) [RFC2065] 所添加的记录类型中有两种在考虑资源记录集的形成时需要特别注意. 它们就是 SIG 和 NXT 记录. 应当指出, DNS 安全仍然非常新, 目前对它还缺乏经验. 读者应当做好准备: 随着 DNS 安全规范的成熟, 本文档中与 DNSSEC 有关的信息会变得过时.

5.3.1. SIG 记录与 RRSet​

一条 SIG 记录为 DNS 中的另一个 RRSet 提供签名 (验证) 数据. 在已签名的区域中, 该区域内的每个 RRSet 都会有一条与之关联的 SIG 记录. RRSet 的数据类型包含在 SIG RR 的数据中, 用以表明这条 SIG 记录与哪个特定的 RRSet 相关联. 如果套用上述规则, 那么每当为了验证响应而在响应中纳入一条 SIG 记录时, 与相应节点相关联的所有其他 RRSet 的 SIG 记录也都需要被纳入. 在某些情况下, 这可能是数量极大的记录, 而它们又是相当大的 RR, 更是雪上加霜.

因此, 明确允许授权节 (authority section) 只包含那些 "type covered" 字段等于所返回答案的 type 字段的 SIG RR. 然而, 当 SIG 记录是在答案节 (answer section) 中返回时 -- 无论是响应针对 SIG 记录的查询, 还是响应针对与某个名称相关联的所有记录 (type=ANY) 的查询 -- 都必须像对待任何其他 RR 类型一样, 纳入整个 SIG RRSet.

收到在授权节中包含 SIG 记录, 或者 (可能是不正确地) 将其作为附加数据包含的响应的服务器, 必须明白几乎可以肯定整个 RRSet 并未被全部纳入. 因此, 它们不得以这样的方式缓存该 SIG 记录: 即在该服务器收到针对 SIG 记录的查询时允许将其返回. RFC2065 实际上要求 SIG 查询只被发往权威服务器, 以避免此处可能引发的问题; 只要还存在不理解 SIG 记录特殊性质的服务器, 这一点就仍然是必要的. 然而, 在新实现中精心设计 SIG 记录的处理, 应当能在将来放宽这一限制, 使解析器无需特殊对待 SIG 记录查询.

偶尔有人提出, 收到的 SIG 记录请求应被转发给权威服务器, 而不是用缓存中的数据来回答. 这并无必要 -- 一个已经知道 SIG 属于需要如此特殊处理的个例的服务器, 更好的做法是考虑到 SIG 记录的特性来正确地缓存它们. 这样, 服务器就能判断何时可以安全地从缓存中回复, 以及何时答案不可得而必须转发该查询.

5.3.2. NXT RR​

下一资源记录 (Next Resource Record, NXT) 更为奇特. 在一个区域中, 针对某个特定标签永远只会有一条 NXT 记录, 所以表面上 RRSet 问题微不足道. 然而在区域切割 (zone cut) 处, 父区域和子区域 (按 RFC2065 的术语即超级区域和子区域) 都会为同一个名称拥有 NXT 记录. 这两条 NXT 记录并不构成一个 RRSet, 即使两个区域都托管在同一台服务器上也是如此. NXT RRSet 始终只包含单条 RR. 当两条 NXT 记录都可见时, 就存在两个 RRSet. 不过, 服务器在响应中收到 NXT 记录时, 并不需要将其作为特殊情况处理. 它们可以选择注意到存在两个不同的 NXT RRSet, 并像对待任何其他类型的两个不同 RRSet 那样对待. 也就是说, 缓存其中一个, 忽略另一个. 不过, 具有安全意识的服务器将需要正确处理所收到响应中的 NXT 记录.

5.4. 接收 RRSet​

服务器绝不能把响应中的 RR 与自身缓存中的 RR 合并成一个 RRSet. 如果响应所含的数据会与服务器缓存中的数据构成一个 RRSet, 则服务器必须视情况忽略响应中的 RR, 或者丢弃当前缓存中的整个 RRSet. 因此, 缓存与响应之间 TTL 不一致的问题不会造成困扰, 其中之一将被忽略. 也就是说, 如果来自某个答案的数据与缓存中的数据不同, 那么这两组数据中总有一组是不正确的. 服务器的挑战在于判断哪一组数据 (如果有的话) 是正确的, 并保留它而忽略另一组. 注意, 如果服务器收到一个答案, 其中包含的 RRSet 与其缓存中的 RRSet 相同 (可能 TTL 值除外), 那么它可以选择用所收到答案的 TTL 更新其缓存中的 TTL. 如果所收到的答案被认为比先前缓存的答案更具权威性 (如下一节所讨论的), 它就应当这样做.

5.4.1. 数据排名​

在考虑是接受回复中的某个 RRSet, 还是改为保留其缓存中已有的 RRSet 时, 服务器应当考虑各种数据相对而言的可能可信度 (trustworthiness). 来自回复的权威答案应当替换掉先前从某次回复的附加信息中获得的缓存数据. 然而, 如果缓存中已包含来自权威答案或区域文件的数据, 那么回复中的附加信息将被忽略.

可用数据的准确性由其来源推定. 可信度从高到低依次为:

  • 来自主区域文件的数据, 粘合记录 (glue) 数据除外,
  • 来自区域传送 (zone transfer) 的数据, 粘合记录除外,
  • 包含在权威回复答案节中的权威数据.
  • 来自权威答案授权节的数据,
  • 来自主区域的粘合记录, 或来自区域传送的粘合记录,
  • 来自非权威答案答案节的数据, 以及来自权威答案答案节的非权威数据,
  • 来自权威答案的附加信息, 来自非权威答案授权节的数据, 来自非权威答案的附加信息.

注意, 权威答案的答案节通常只包含权威数据. 然而, 当所查找的名称是一个别名 (alias) 时 (见第 10.1.1 节), 只有描述该别名的那条记录必然是权威的. 客户端应当假定其他记录可能来自服务器的缓存. 在需要权威答案的场合, 客户端应当使用与该别名相关联的规范名称 (canonical name) 重新查询.

从未经认证的, 属于这些分组中可信度最低者的来源接收并缓存的 RR -- 即来自附加数据节的数据, 以及来自非权威答案授权节的数据 -- 不应以这样的方式缓存: 即它们会被作为对某个收到查询的答案返回. 在适当情况下, 它们可以作为附加信息返回. 忽视这一点, 就会让相对不可信数据的可信度无缘无故地得到提升.

当 DNS 安全 [RFC2065] 在使用中, 并且已收到并验证了一个经过认证的回复时, 由此得到认证的数据应被视为比同一类型的未经认证数据更可信. 注意, 在本文档全文中, "authoritative" 指的是设置了 AA bit 的回复. DNSSEC 使用 SIG 和 KEY 记录的可信链来确定数据的真实性, AA bit 几乎无关紧要. 然而, 具有 DNSSEC 意识的服务器仍必须在响应中正确设置 AA bit, 以便与那些没有安全意识 (目前几乎全部如此) 的服务器正确协作.

注意, 除粘合记录外, 来自两个正确配置的主区域文件的数据, 来自两个正确配置的辅助区域 (来自区域传送的数据) 的数据, 或者来自正确配置的主区域与辅助区域的数据, 都不可能发生冲突. 当同一个名称的粘合记录存在于多个区域中且取值不同时, 名称服务器应当优先选择来自主区域文件的数据而非辅助区域的数据, 但在其他方面可以选择任何单一一组此类数据. 在能够确定的情况下, 选择看起来来自更接近权威数据源的来源的那一组数据可能是合理的. 在辅助数据与主数据之间选择主数据, 可以在此类数据出现问题时更容易地发现错误粘合数据的来源. 如果服务器能够从两个区域文件检测出一个或多个配置不正确以致产生冲突, 它就应当拒绝加载被判定为错误的区域, 并给出适当的诊断信息.

上文的 "粘合记录" 包括区域文件中并非真正属于该区域的任何记录, 其中包括被委派子区域的名称服务器记录 (NS 记录), 伴随这些 NS 记录的地址记录 (A, AAAA 等), 以及可能出现的任何其他零散数据.

5.5. 发送 RRSet (重述)​

在任何 DNS 回复中, 一个资源记录集只应被包含一次. 视需要, 它可以出现在答案节, 授权节或附加信息节中的任一节. 然而, 它不应在同一节或任何其他节中重复出现, 除非某项规范明确要求如此. 例如, AXFR 响应要求 SOA 记录 (始终是一个只含单条 RR 的 RRSet) 同时作为回复的第一条和最后一条记录. 在以此种方式要求重复的场合, 每种情况下传送的 TTL 必须相同.