delphij's Chaos

选择chaos这个词是因为~~实在很难找到一个更合适的词来形容这儿了……

31 Jul 2023

在本地架设根 DNS 的镜像

目的

在本地的局域网上建立 DNS 解析服务可以显著地改善 DNS 的安全性:所有的 DNS 查询将由可以信任的本地 DNS 解析服务进行验证, 而不是简单地相信一台不受控的远程服务器通过 UDP 提供的应答。因此,这些年来我自己的网络包括机房的网络都是自己运行一组 DNS 解析服务的。

在 DNS 查询过程中,根域 (.) 十分关键。传统上,本地的 DNS 解析服务通常会向一组事先配死的根服务器列表查询顶级域名的域名服务器, 这样一来,在查询过程中本地 DNS 解析服务会时不时地向根域 DNS 询问顶级域名的 NS 记录,这样一来,不可避免地,本地和根域 DNS 服务器之间的网络服务业者或是攻击者就可以获知该解析服务器正在查询的顶级域名,而如果没有启用 DNSSEC 验证,攻击者还可以进一步劫持顶级域名, 从而潜在地将用户的访问转向他们指定的目标来实现一些特定的目的,例如将用户不小心输入错误产生的流量变现, 或是利用用户的行为进行 DDoS 攻击。

另一方面,有时用户本地的 DNS 解析服务访问根域可能有一定的延迟,这样他们在首次访问某个顶级域名时就会产生更多的延迟。 与 ISP 或是公共 DNS 服务,例如 Google 的 8.8.8.8、CloudFlare 的 1.1.1.1 等等相比, 由于本地的用户数量没有那么多,用户访问的域名往往会不在 DNS 缓存中,从而让查询变得更慢。

由于根域的内容很少,因此在本地架设一份根域可以解决上面这些问题:通过直接从根 DNS 传输一份完整的根域,本地运行的 DNS 解析服务可以立即按图索骥而不是增加一次 DNS 查询,另一方面,如果用户输入了错误的顶级域名,这次查询也完全不会出现在互联网上, 因为本地的解析服务就可以立即知道该顶级域名不存在了。

做法

ICANN 的 xfr.lax.dns.icann.org 和 xfr.cjr.dns.icann.org,以及 b、c、d、f、g、k 这六组根 DNS 服务器允许直接通过 TCP AXFR 来获得根域。需要注意的是, ICANN 和这些根服务器运营者可能会关闭 AXFR 服务,因此你使用的 DNS 软件必须有能力在传输失败且本地的镜像过期时正确地回退到使用传统的方式进行查询。

攻击者可以轻易地通过劫持这些已知 IP 的 AXFR 请求来提供伪造的根域 .,因此在这样做时必须启用 DNSSEC 验证。

对于 unbound 来说,可以在 unbound.conf 中添加下面的配置并重启服务来启用这一功能:

auth-zone:
        name: "."
        primary: 199.9.14.201         # b.root-servers.net
        primary: 192.33.4.12          # c.root-servers.net
        primary: 199.7.91.13          # d.root-servers.net
        primary: 192.5.5.241          # f.root-servers.net
        primary: 192.112.36.4         # g.root-servers.net
        primary: 193.0.14.129         # k.root-servers.net
        primary: 192.0.47.132         # xfr.cjr.dns.icann.org
        primary: 192.0.32.132         # xfr.lax.dns.icann.org
        primary: 2001:500:200::b      # b.root-servers.net
        primary: 2001:500:2::c        # c.root-servers.net
        primary: 2001:500:2d::d       # d.root-servers.net
        primary: 2001:500:2f::f       # f.root-servers.net
        primary: 2001:500:12::d0d     # g.root-servers.net
        primary: 2001:7fd::1          # k.root-servers.net
        primary: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org
        primary: 2620:0:2d0:202::132  # xfr.lax.dns.icann.org
        fallback-enabled: yes
        for-downstream: no
        for-upstream: yes

注意以上的 IP 地址是目前 (2023年7月31日) 的 IP 地址。尽管这些地址基本上不会变化, 但是仍然建议和 IANA 的列表 核对之后再使用。 由于显而易见的原因,这个列表必须使用 IP 地址而不是域名。

确认运行状态

使用 unbound-control list_auth_zones 可以列出 unbound 服务器目前提供的权威域名的 SOA 序号,该序号可以与 IANA 的版本 「Root Zone File」 核对。