什么是 DNSSEC?工作原理详解

DNSSEC(DNS Security Extensions,DNS 安全扩展)为 DNS 记录添加数字签名,使解析器能够验证某个应答确实来自域名所有者,并且在传输途中没有被篡改。它不会加密任何内容,而是通过一条从 DNS 根区开始的信任链来证明真实性。

普通的 DNS 无法分辨真实应答和伪造应答。DNSSEC 由 RFC 4033、4034 和 4035 标准化,弥补了这一缺口。本指南将介绍涉及的记录类型、验证的工作方式,以及最容易让已签名域名下线的错误。

DNSSEC 解决的问题

递归解析器会接受第一个与其查询相匹配的应答。如果攻击者能够注入伪造的响应(例如处于网络路径上,或者在缓存投毒攻击中抢在真实服务器之前应答),就可以把该解析器的用户重定向到攻击者选定的 IP 地址。共用该解析器的所有人都会得到这个虚假应答,直到缓存条目过期。

DNSSEC 让伪造变得可以被发现。每一组记录都用区域的私钥签名,相应的公钥则发布在 DNS 中。验证型解析器会检查签名,并拒绝任何无法通过验证的内容。如果您想先了解解析器和权威服务器,请阅读 DNS 是什么及其工作原理。

DNSSEC 记录类型

记录所在位置用途
DNSKEY已签名的区域用于验证该区域签名的公钥
RRSIG已签名的区域对一个记录集(例如某个名称的所有 A 记录)的签名,带有有效期的开始和结束时间
DS上级区域委派签名者(Delegation Signer):子区域密钥签名密钥的哈希,把上级与子区域关联起来
NSEC已签名的区域通过给出按排序的下一个存在的名称,证明某个名称或记录类型不存在
NSEC3已签名的区域与 NSEC 相同,但使用经过哈希的名称(RFC 5155),使枚举区域内的所有名称更加困难
CDS / CDNSKEY已签名的区域向上级区域通知应当发布哪条 DS 记录,从而实现自动更新(RFC 7344)

我们的 DNS 记录类型指南介绍了这些签名所保护的普通记录,例如 A、MX 和 TXT。

为什么需要证明“不存在”

如果没有 NSEC 或 NSEC3,攻击者就可以伪造 NXDOMAIN(“此名称不存在”)响应,而这种响应无法自带签名,因为没有可供签名的记录。NSEC 记录为解析器提供了一份已签名的声明,证明两个名称之间不存在任何内容,因此“否认”也可以被验证。

密钥签名密钥与区域签名密钥

大多数区域使用两种密钥,都以 DNSKEY 记录的形式发布:

  • 区域签名密钥(ZSK),DNSKEY 标志为 256:为区域的普通记录集签名。可以频繁轮换,无需牵涉其他任何人。
  • 密钥签名密钥(KSK),DNSKEY 标志为 257:只为 DNSKEY 记录集签名。它的哈希会写入上级区域的 DS 记录,所以更换它需要更新域名注册商处的设置。

把职责拆分后,日常的密钥更换都留在您的 DNS 服务商内部,而较少发生的 KSK 更换是唯一会涉及上级区域的操作。有些部署则改用单个合并的签名密钥,这样更简单,在使用算法 13(采用 SHA-256 的 ECDSA P-256)等现代椭圆曲线算法时很常见。

信任链

只有当解析器信任生成签名的密钥时,签名才有用。DNSSEC 从 2010 年完成签名的根区开始,一步步建立这种信任。验证型解析器内置了根区的 KSK,作为信任锚。要验证 www.example.com,解析器会依次执行:

  1. 使用根区信任锚来验证根区的 DNSKEY 集。
  2. 验证根区中 com 的已签名 DS 记录,然后检查它是否与 com 的 DNSKEY 集中的 KSK 匹配。
  3. 验证 com 区域中 example.com 的已签名 DS 记录,然后检查它是否与 example.com 发布的 KSK 匹配。
  4. 使用 example.com 的 DNSKEY 集来验证 www.example.com 的 A 记录上的 RRSIG。

如果每一环都验证通过,则应答是安全的。如果上级区域没有该区域的 DS 记录,则该区域是不安全的(未签名),应答会照常返回。如果存在 DS 但签名无法通过验证,则应答是伪造的(bogus)。

如何查看验证结果:AD 与 SERVFAIL

当验证型解析器成功验证了某个应答时,会在响应中设置 AD(Authenticated Data,已认证数据)标志。您可以用 dig 看到它:

$ dig +dnssec www.example.com A @1.1.1.1

;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; ANSWER SECTION:
www.example.com.  300  IN  A      192.0.2.10
www.example.com.  300  IN  RRSIG  A 13 3 300 20261101000000 20261011000000 12345 example.com. (signature data)

验证失败时,解析器不会返回可能被伪造的数据,而是返回 SERVFAIL,在用户看来,这与网站不存在或 DNS 故障没有区别。要确认原因是 DNSSEC,请在禁用检查的情况下重复查询:

dig www.example.com A           # status: SERVFAIL
dig +cd www.example.com A       # status: NOERROR, answer returned

如果 +cd(禁用检查)的查询成功而普通查询失败,就说明该区域的 DNSSEC 已损坏。我们的 DNSSEC检测会为您运行这些检查,并显示 DS、DNSKEY 和签名状态。

DNSSEC 常见的故障原因

更换 DNS 服务商时没有删除 DS 记录

这是最典型的故障。注册局中的 DS 记录仍然指向旧服务商的 KSK。更换名称服务器之后,新服务商要么提供未签名的区域,要么用不同的密钥签名。验证型解析器发现 DS 没有匹配的密钥,就会把该区域标记为 bogus,于是每次查询都会返回 SERVFAIL。

安全的迁移步骤如下:

  1. 在域名注册商处删除 DS 记录。
  2. 等待旧的 DS 从缓存中过期:至少等待上级区域中该 DS 记录的 TTL,您可以用 dig example.com DS 查看。等待一两天是常见的安全余量。
  3. 把名称服务器改为新服务商,并等待旧的 NS 记录过期。
  4. 在新服务商处启用 DNSSEC,并在域名注册商处发布其新的 DS 记录。

有些服务商支持多签名者的部署方式,可以避免出现未签名的空窗期,但这需要两家服务商相互配合。

签名过期

每个 RRSIG 都有过期时间。如果签名流程停止了(例如自建服务器上的重新签名任务失败),签名最终会过期,区域就会变成 bogus。

密钥轮换过快

在缓存获取到新密钥之前就移除旧密钥,会导致仍持有旧 DNSKEY 集或 DS 记录的解析器出现故障。密钥轮换必须遵守相关的 TTL。

如何为您的域名启用 DNSSEC

  1. 确认您的顶级域支持 DNSSEC;大多数通用顶级域和许多国家/地区顶级域都支持。
  2. 在您的 DNS 托管服务商处开启 DNSSEC 签名。它会生成密钥并为区域签名。
  3. 把 DS 记录的详细信息(密钥标签、算法、摘要类型和摘要)复制到域名注册商的 DNSSEC 设置中。如果您的服务商和注册商是同一家公司,这通常是自动完成的,有些注册局也会自动读取 CDS 记录。
  4. 使用我们的 DNSSEC检测验证结果,并用 DNS查询工具确认普通查询仍然正常。

常见问题

DNSSEC 会加密我的 DNS 查询吗?

不会。DNSSEC 提供的是真实性和完整性,而不是隐私。查询和应答在网络上仍然可见。加密来自 DNS over TLS 或 DNS over HTTPS,它们与 DNSSEC 互为补充。

如果我的网站使用 HTTPS,还需要 DNSSEC 吗?

HTTPS 证书已经能防止伪造的 DNS 应答悄悄冒充您的网站,但 DNSSEC 还能保护邮件路由、用于验证的 TXT 记录以及其他记录。DANE 也需要它,DANE 会把 TLS 证书信息发布在 DNS 中。

为什么我的域名在某些网络上能访问,在另一些网络上却不能?

如果 DNSSEC 已损坏,只有验证型解析器会返回 SERVFAIL,不做验证的解析器仍然会应答。这就使得故障看起来取决于所在的网络。

如何安全地关闭 DNSSEC?

先在域名注册商处删除 DS 记录,等它从缓存中过期,然后再停止为区域签名。如果顺序颠倒,就会导致故障。

亲自试试

使用我们的免费工具,把本指南付诸实践。

继续阅读

已复制到剪贴板