跳到主要内容

5. 认证 DNS 响应 (Authenticating DNS Responses)

为了使用 DNSSEC RR 进行认证, 安全感知解析器需要预先配置至少一个已认证 DNSKEY 或 DS RR 的知识. 获取并认证这个初始信任锚的过程通过某种外部机制完成. 例如, 解析器可以使用某种离线认证交换来获得区域的 DNSKEY RR, 或获得一条用于标识并认证区域 DNSKEY RR 的 DS RR. 本节其余部分假定解析器已经以某种方式获得了一组初始信任锚.

初始 DNSKEY RR 可用于认证区域顶点 DNSKEY RRset. 若要使用初始密钥认证顶点 DNSKEY RRset, 解析器 MUST:

  1. 验证初始 DNSKEY RR 出现在顶点 DNSKEY RRset 中, 且该 DNSKEY RR 设置了 Zone Key Flag (DNSKEY RDATA bit 7); 并且
  2. 验证存在某条覆盖该顶点 DNSKEY RRset 的 RRSIG RR, 且该 RRSIG RR 与初始 DNSKEY RR 的组合能够认证该 DNSKEY RRset. 使用 RRSIG RR 认证 RRset 的过程见第 5.3 节.

解析器使用初始 DNSKEY RR 认证顶点 DNSKEY RRset 后, 可使用 DS RR 认证来自该区域的委派. 这允许解析器从初始密钥开始, 使用 DS RRset 沿 DNS 树递归向下推进, 获得其他顶点 DNSKEY RRset. 如果解析器配置了根 DNSKEY RR, 且每个委派都有与之关联的 DS RR, 则解析器可以获得并验证任何顶点 DNSKEY RRset. 使用 DS RR 认证委派响应的过程见第 5.2 节.

第 5.3 节说明解析器在认证区域顶点 DNSKEY RRset 后, 如何使用顶点 DNSKEY RRset 中的 DNSKEY RR 和来自该区域的 RRSIG RR 来认证区域中的任何其他 RRset. 第 5.4 节说明解析器如何使用来自该区域的已认证 NSEC RRset 来证明某个 RRset 不存在于该区域中.

当解析器通过设置 DO 位表示支持 DNSSEC 时, 安全感知名称服务器应尝试在响应中提供必要的 DNSKEY, RRSIG, NSEC 和 DS RRset (见第 3 节). 但是, 安全感知解析器仍可能收到缺少适当 DNSSEC RR 的响应. 这可能是由于配置问题, 例如上游非安全感知递归名称服务器意外干扰 DNSSEC RR; 也可能是由于蓄意攻击, 即攻击者伪造响应, 从响应中剥离 DNSSEC RR, 或修改查询使 DNSSEC RR 看起来未被请求. 响应中缺少 DNSSEC 数据本身 MUST NOT 被视为不存在认证信息的指示.

解析器 SHOULD 预期从已签名区域获得认证信息. 如果解析器已配置该区域的公钥信息, 或者该区域的父区域已签名且来自父区域的委派包含 DS RRset, 则解析器 SHOULD 认为该区域已签名.

5.1. 安全孤岛的特殊考虑事项 (Special Considerations for Islands of Security)

安全孤岛 (见 [RFC4033]) 是无法从其父区域构造到该区域认证链的已签名区域. 在安全孤岛内验证签名要求验证器通过其他方式获得该孤岛的初始已认证区域密钥. 如果验证器无法获得这样的密钥, 它 SHOULD 切换为把安全孤岛中的区域当作未签名区域来操作.

验证响应的所有正常过程都适用于安全孤岛. 正常验证与安全孤岛内验证之间的唯一区别在于验证器如何为认证链获得信任锚.

5.2. 认证委派响应 (Authenticating Referrals)

一旦已认证已签名父区域的顶点 DNSKEY RRset, 就可以使用 DS RRset 认证到已签名子区域的委派. DS RR 标识子区域顶点 DNSKEY RRset 中的一条 DNSKEY RR, 并包含该子区域 DNSKEY RR 的密码学摘要. 使用强密码学摘要算法可确保攻击者在计算上不可行地生成与该摘要匹配的 DNSKEY RR. 因此, 认证该摘要使解析器能够认证匹配的 DNSKEY RR. 随后解析器可以使用该子 DNSKEY RR 认证整个子区域顶点 DNSKEY RRset.

给定某个委派的 DS RR, 如果以下条件全部成立, 则可以认证子区域的顶点 DNSKEY RRset:

  • DS RR 已使用父区域顶点 DNSKEY RRset 中的某条 DNSKEY RR 认证 (见第 5.3 节).
  • DS RR 中的 Algorithm 和 Key Tag 与子区域顶点 DNSKEY RRset 中某条 DNSKEY RR 的 Algorithm 字段和 key tag 匹配, 并且当使用 DS RR 的 Digest Type 字段指定的摘要算法对该 DNSKEY RR 的所有者名称和 RDATA 求哈希时, 得到的摘要值与 DS RR 的 Digest 字段匹配.
  • 子区域中匹配的 DNSKEY RR 设置了 Zone Flag 位, 对应私钥已对子区域顶点 DNSKEY RRset 签名, 并且得到的 RRSIG RR 能够认证子区域顶点 DNSKEY RRset.

如果来自父区域的委派响应不包含 DS RRset, 该响应应包含一个已签名 NSEC RRset, 证明被委派名称不存在 DS RRset (见第 3.1.4 节). 如果委派响应既不包含 DS RRset, 也不包含证明 DS RRset 不存在的 NSEC RRset, 安全感知解析器 MUST 向父区域的名称服务器查询 DS RRset (见第 4 节).

如果验证器认证了一条 NSEC RRset, 证明该区域不存在 DS RRset, 则不存在从父区域通向子区域的认证路径. 如果解析器拥有属于子区域或子区域以下任何委派的初始 DNSKEY 或 DS RR, 则该初始 DNSKEY 或 DS RR MAY 用于重新建立认证路径. 如果不存在这样的初始 DNSKEY 或 DS RR, 验证器就无法认证子区域内或子区域以下的 RRset.

如果验证器不支持已认证 DS RRset 中列出的任何算法, 则解析器没有受支持的从父区域通向子区域的认证路径. 如上所述, 解析器应像处理已认证 NSEC RRset 证明不存在 DS RRset 的情况一样处理此情况.

注意, 对于已签名委派, 有两条 NSEC RR 与被委派名称关联. 一条 NSEC RR 位于父区域中, 可用于证明被委派名称是否存在 DS RRset. 第二条 NSEC RR 位于子区域中, 标识子区域顶点处存在哪些 RRset. 父 NSEC RR 和子 NSEC RR 总能区分, 因为子 NSEC RR 中会设置 SOA 位, 而父 NSEC RR 中会清除该位. 安全感知解析器在尝试证明 DS RRset 不存在时 MUST 使用父 NSEC RR.

如果解析器不支持已认证 DS RRset 中列出的任何算法, 则解析器将无法验证通向子区域的认证路径. 在这种情况下, 解析器 SHOULD 把子区域当作未签名区域处理.

5.3. 使用 RRSIG RR 认证 RRset (Authenticating an RRset with an RRSIG RR)

验证器可以使用 RRSIG RR 及其对应的 DNSKEY RR 尝试认证 RRset. 验证器首先检查 RRSIG RR, 以确认它覆盖该 RRset, 具有有效时间区间, 并标识一条有效的 DNSKEY RR. 然后, 验证器通过将 RRSIG RDATA (不含 Signature Field) 与被覆盖 RRset 的规范形式相附加, 构造已签名数据的规范形式. 最后, 验证器使用公钥和签名认证已签名数据. 第 5.3.1, 5.3.2 和 5.3.3 节详细描述每个步骤.

5.3.1. 检查 RRSIG RR 有效性 (Checking the RRSIG RR Validity)

如果以下条件全部成立, 安全感知解析器可以使用 RRSIG RR 认证 RRset:

  • RRSIG RR 和 RRset MUST 具有相同的所有者名称和相同的类.
  • RRSIG RR 的 Signer's Name 字段 MUST 是包含该 RRset 的区域名称.
  • RRSIG RR 的 Type Covered 字段 MUST 等于 RRset 的类型.
  • RRset 所有者名称中的标签数 MUST 大于或等于 RRSIG RR 的 Labels 字段中的值.
  • 验证器所认为的当前时间 MUST 小于或等于 RRSIG RR 的 Expiration 字段中列出的时间.
  • 验证器所认为的当前时间 MUST 大于或等于 RRSIG RR 的 Inception 字段中列出的时间.
  • RRSIG RR 的 Signer's Name, Algorithm 和 Key Tag 字段 MUST 与区域顶点 DNSKEY RRset 中某条 DNSKEY RR 的所有者名称, 算法和 key tag 匹配.
  • 匹配的 DNSKEY RR MUST 存在于区域顶点 DNSKEY RRset 中, 并且 MUST 设置 Zone Flag 位 (DNSKEY RDATA Flag bit 7).

可能有多条 DNSKEY RR 匹配上述条件. 在这种情况下, 验证器无法预先确定使用哪条 DNSKEY RR 来认证签名, 因此 MUST 尝试每条匹配的 DNSKEY RR, 直到签名得到验证, 或者没有更多匹配公钥可尝试为止.

注意, 只有在验证器使用 DNSKEY RR 验证签名前先认证该 DNSKEY RR 时, 此认证过程才有意义. 如果满足以下任一条件, 匹配的 DNSKEY RR 被视为真实可信:

  • 包含该 DNSKEY RR 的顶点 DNSKEY RRset 被视为真实可信; 或
  • RRSIG RR 覆盖的 RRset 是顶点 DNSKEY RRset 本身, 且该 DNSKEY RR 要么匹配来自父区域的已认证 DS RR, 要么匹配信任锚.

5.3.2. 重构已签名数据 (Reconstructing the Signed Data)

一旦 RRSIG RR 满足第 5.3.1 节描述的有效性要求, 验证器就必须重构原始已签名数据. 原始已签名数据包括 RRSIG RDATA (不含 Signature 字段) 和 RRset 的规范形式. 除排序之外, RRset 的规范形式还可能因 DNS 名称压缩, TTL 递减或通配符扩展而不同于收到的 RRset. 验证器应使用以下内容重构原始已签名数据:

signed_data = RRSIG_RDATA | RR(1) | RR(2)...  where

"|" denotes concatenation

RRSIG_RDATA is the wire format of the RRSIG RDATA fields
with the Signature field excluded and the Signer's Name
in canonical form.

RR(i) = name | type | class | OrigTTL | RDATA length | RDATA

name is calculated according to the function below

class is the RRset's class

type is the RRset type and all RRs in the class

OrigTTL is the value from the RRSIG Original TTL field

All names in the RDATA field are in canonical form

The set of all RR(i) is sorted into canonical order.

To calculate the name:
let rrsig_labels = the value of the RRSIG Labels field

let fqdn = RRset's fully qualified domain name in
canonical form

let fqdn_labels = Label count of the fqdn above.

if rrsig_labels = fqdn_labels,
name = fqdn

if rrsig_labels < fqdn_labels,
name = "*." | the rightmost rrsig_label labels of the
fqdn

if rrsig_labels > fqdn_labels
the RRSIG RR did not pass the necessary validation
checks and MUST NOT be used to authenticate this
RRset.

名称和 RRset 的规范形式定义见 [RFC4034].

委派边界处的 NSEC RRset 需要特殊处理. 与已签名被委派名称关联的 NSEC RRset 有两个不同集合. 一个 NSEC RRset 位于父区域, 指定父区域中存在哪些 RRset. 第二个 NSEC RRset 位于子区域, 标识子区域顶点处存在哪些 RRset. 父 NSEC RRset 和子 NSEC RRset 总能区分, 因为只有子 NSEC RR 会指示该名称处存在 SOA RRset. 在重构来自父区域委派的原始 NSEC RRset 时, NSEC RR MUST NOT 与来自子区域的 NSEC RR 合并. 在重构子区域顶点的原始 NSEC RRset 时, NSEC RR MUST NOT 与来自父区域的 NSEC RR 合并.

注意, 委派点处两个 NSEC RRset 中的每一个都有对应的 RRSIG RR, 其所有者名称与被委派名称匹配, 并且这些 RRSIG RR 各自都是与包含对应 NSEC RRset 的同一区域相关联的权威数据. 必要时, 解析器可以通过检查 Signer's Name 字段来区分这些 RRSIG RR.

5.3.3. 检查签名 (Checking the Signature)

一旦解析器按第 5.3.1 节所述验证了 RRSIG RR, 并按第 5.3.2 节所述重构了原始已签名数据, 验证器就可以尝试使用密码学签名来认证已签名数据, 从而最终认证该 RRset.

RRSIG RR 中的 Algorithm 字段标识用于生成签名的密码学算法. 签名本身包含在 RRSIG RDATA 的 Signature 字段中, 用于验证签名的公钥包含在匹配 DNSKEY RR (见第 5.3.1 节) 的 Public Key 字段中. [RFC4034] 提供算法类型列表, 并指向定义每种算法用法的文档.

5.4. 经认证的不存在证明 (Authenticated Denial of Existence)

解析器可以使用已认证 NSEC RR 来证明某个 RRset 不存在于已签名区域中. 安全感知名称服务器应在发给安全感知解析器的响应中自动包含已签名区域所需的任何 NSEC RR.

不存在证明按以下规则确定:

  • 如果请求的 RR 名称与已认证 NSEC RR 的所有者名称匹配, 则该 NSEC RR 的 type bit map 字段列出该所有者名称处存在的所有 RR 类型, 解析器可以通过检查位图中是否存在请求的 RR 类型来证明该请求 RR 类型不存在. 如果已认证 NSEC RR 所有者名称中的标签数等于覆盖它的 RRSIG RR 的 Labels 字段, 则该 NSEC RR 的存在证明无法使用通配符扩展匹配该请求.

  • 如果按照 [RFC4034] 中定义的规范 DNS 名称顺序, 请求的 RR 名称会出现在已认证 NSEC RR 的所有者名称之后, 且在该 NSEC RR 的 Next Domain Name 字段列出的名称之前, 则区域中不存在具有该请求名称的 RRset. 但是, 仍可能使用通配符来匹配请求的 RR 所有者名称和类型, 因此证明请求的 RRset 不存在还需要证明不存在任何可能用于生成肯定响应的通配符 RRset.

此外, 安全感知解析器 MUST 按第 5.3 节所述认证组成不存在证明的 NSEC RRset.

为了证明某个 RRset 不存在, 解析器必须能够同时验证被查询 RRset 不存在且不存在相关通配符 RRset. 证明这一点可能需要来自该区域的多个 NSEC RRset. 如果响应中不存在所需 NSEC RRset 的完整集合 (可能由于消息截断), 则安全感知解析器 MUST 重新发送查询, 以尝试获得验证请求 RRset 不存在所需的完整 NSEC RR 集合. 但是, 与所有 DNS 操作一样, 解析器 MUST 限制其为回答任何特定查询所投入的工作量.

由于已验证 NSEC RR 同时证明其自身及其对应 RRSIG RR 的存在, 验证器 MUST 忽略 NSEC RR 中 NSEC 和 RRSIG 位的设置.

5.5. 签名未能验证时的解析器行为 (Resolver Behavior When Signatures Do Not Validate)

如果由于任何原因没有任何 RRSIG 能够验证, 响应 SHOULD 被视为 BAD. 如果验证是为了服务递归查询而执行, 名称服务器 MUST 向发起客户端返回 RCODE 2. 但是, 当且仅当原始查询设置了 CD 位时, 它 MUST 返回完整响应. 关于缓存未能验证响应的内容, 另见第 4.7 节.

5.6. 认证示例 (Authentication Example)

附录 C 展示认证过程示例.