5. Authenticating DNS Responses (认证 DNS 响应)
5. Authenticating DNS Responses (认证 DNS 响应)
要使用 DNSSEC RR 进行认证, 安全感知解析器需要配置至少一个经过认证的 DNSKEY 或 DS RR 的知识.获取和认证此初始信任锚点 (initial trust anchor) 的过程是通过某种外部机制实现的.例如, 解析器可以使用某种离线认证交换来获取区域的 DNSKEY RR, 或获取标识和认证区域 DNSKEY RR 的 DS RR.本节的其余部分假设解析器已以某种方式获得了一组初始信任锚点.
初始 DNSKEY RR 可用于认证区域的顶点 DNSKEY RRset.要使用初始密钥认证顶点 DNSKEY RRset, 解析器必须 (MUST):
- 验证初始 DNSKEY RR 出现在顶点 DNSKEY RRset 中, 并且 DNSKEY RR 已设置 Zone Key Flag (区域密钥标志, DNSKEY RDATA 位 7); 并且
- 验证存在一些覆盖顶点 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 在区域中不存在.
当解析器指示支持 DNSSEC (通过设置 DO 位) 时, 安全感知名称服务器应该尝试在响应中提供必要的 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 (安全岛的特殊考虑)
安全岛 (islands of security, 参见 [RFC4033]) 是无法从其父区域构建到该区域的认证链的签名区域.验证安全岛内的签名需要验证器通过其他方式为该安全岛获取初始认证的区域密钥.如果验证器无法获得此类密钥, 它应该 (SHOULD) 切换到像安全岛中的区域未签名一样操作.
所有正常的验证响应过程都适用于安全岛.正常验证和安全岛内验证之间的唯一区别在于验证器如何为认证链获取信任锚点.
5.2. Authenticating Referrals (认证引用)
一旦签名父区域的顶点 DNSKEY RRset 得到认证, DS RRset 就可以用于认证到签名子区域的委托.DS RR 标识子区域顶点 DNSKEY RRset 中的 DNSKEY RR, 并包含子区域 DNSKEY RR 的加密摘要 (cryptographic digest).使用强加密摘要算法确保攻击者在计算上不可能生成与摘要匹配的 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, 则响应应该包含证明被委托名称不存在 DS RRset 的签名 NSEC RRset (参见第 3.1.4 节).如果引用既不包含 DS RRset 也不包含证明 DS RRset 不存在的 NSEC RRset, 则安全感知解析器必须 (MUST) 查询父区域的名称服务器以获取 DS RRset (参见第 4 节).
如果验证器认证了证明此区域不存在 DS RRset 的 NSEC 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 始终可以区分, 因为 SOA 位将在子 NSEC RR 中设置, 而在父 NSEC RR 中清除.当尝试证明 DS RRset 不存在时, 安全感知解析器必须 (MUST) 使用父 NSEC RR.
如果解析器不支持经过认证的 DS RRset 中列出的任何算法, 则解析器将无法验证到子区域的认证路径.在这种情况下, 解析器应该 (SHOULD) 将子区域视为未签名.
5.3. Authenticating an RRset with an RRSIG RR (使用 RRSIG RR 认证 RRset)
验证器可以使用 RRSIG RR 及其相应的 DNSKEY RR 来尝试认证 RRset.验证器首先检查 RRSIG RR 以验证它覆盖 RRset, 具有有效的时间间隔, 并标识有效的 DNSKEY RR.然后, 验证器通过将 RRSIG RDATA (不包括 Signature 字段) 与所覆盖 RRset 的规范形式 (canonical form) 连接来构建签名数据的原始形式.最后, 验证器使用公钥和签名来认证签名的数据.第 5.3.1, 5.3.2 和 5.3.3 节详细描述了每个步骤.
5.3.1. Checking the RRSIG RR Validity (检查 RRSIG RR 有效性)
如果以下所有条件都成立, 安全感知解析器可以使用 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 的所有者名称, 算法和密钥标签匹配.
- 匹配的 DNSKEY RR 必须 (MUST) 存在于区域的顶点 DNSKEY RRset 中, 并且必须 (MUST) 设置 Zone Flag 位 (DNSKEY RDATA Flag 位 7).
可能有多个 DNSKEY RR 匹配上述条件.在这种情况下, 验证器无法预先确定使用哪个 DNSKEY RR 来认证签名, 并且它必须 (MUST) 尝试每个匹配的 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 名称压缩 (DNS name compression), 递减的 TTL 或通配符扩展而与接收的 RRset 不同.验证器应该使用以下内容来重建原始签名数据:
signed_data = RRSIG_RDATA | RR(1) | RR(2)... 其中
"|" 表示连接
RRSIG_RDATA 是 RRSIG RDATA 字段的线格式 (wire format),
不包括 Signature 字段, Signer's Name 采用规范形式.
RR(i) = name | type | class | OrigTTL | RDATA length | RDATA
name 根据下面的函数计算
class 是 RRset 的类
type 是 RRset 类型, 类中的所有 RR
OrigTTL 是来自 RRSIG Original TTL 字段的值
RDATA 字段中的所有名称都采用规范形式
所有 RR(i) 的集合按规范顺序排序.
要计算名称:
let rrsig_labels = RRSIG Labels 字段的值
let fqdn = RRset 的完全限定域名 (fully qualified domain name),
采用规范形式
let fqdn_labels = 上述 fqdn 的标签计数.
if rrsig_labels = fqdn_labels,
name = fqdn
if rrsig_labels < fqdn_labels,
name = "*." | fqdn 最右边 rrsig_label 个标签
if rrsig_labels > fqdn_labels
RRSIG RR 未通过必要的验证检查,
绝对不能 (MUST NOT) 用于认证此 RRset.
名称和 RRset 的规范形式在 [RFC4034] 中定义.
委托边界 (delegation boundary) 的 NSEC RRset 需要特殊处理.有两个与签名的被委托名称关联的不同 NSEC RRset.一个 NSEC RRset 驻留在父区域中, 并指定父区域中存在哪些 RRset.第二个 NSEC RRset 驻留在子区域, 并标识子区域顶点存在哪些 RRset.父 NSEC RRset 和子 NSEC RRset 始终可以区分, 因为只有子 NSEC RR 会指示名称处存在 SOA RRset.当从父区域重建委托的原始 NSEC RRset 时, 绝对不能 (MUST NOT) 将 NSEC RR 与来自子区域的 NSEC RR 组合.当重建子区域顶点的原始 NSEC RRset 时, 绝对不能 (MUST NOT) 将 NSEC RR 与来自父区域的 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 的 Public Key 字段中 (在第 5.3.1 节中找到).[RFC4034] 提供了算法类型列表, 并提供了指向定义每个算法使用的文档的指针.
5.3.4. Authenticating a Wildcard Expanded RRset Positive Response (认证通配符扩展 RRset 肯定响应)
如果 RRset 的 RRSIG RR 中的标签计数小于 RRset 所有者名称中的标签数, 则响应是通过通配符扩展生成的肯定响应.通配符扩展本身的使用并不被视为错误, 但验证器必须使用 NSEC RR 来确认不存在更近的匹配 (closer match), 如第 3.1.3.3 节和第 5.4 节所述.
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 展示了认证过程的示例.