使用 unbound 作为递归 DNS 服务器

拒绝公共 DNS,使用 unbound 直接进行 DNS 递归查询。

本文为 DNS 完全解决方案三部曲之首 —— 递归 DNS。

背景

当讨论使用什么 DNS 时,总免不了信任问题,也即你选择相信哪个服务提供商。无论是使用运营商下发的 DNS(非集中化,但不透明,可能有隐私及安全问题),还是使用诸如 Quad9 之类的公共 DNS(集中化,且存在隐私顾虑),用户都必须选择信任一个对象,且这一对象通常是大型商业公司。那么,进行 DNS 查询是否非得依靠这些 DNS 服务提供商呢?从 DNS 原理的角度来看,显然不是。Unbound 作为递归 DNS 服务器,可以直接从根服务器开始进行 DNS 递归查询,相当于你自己实现了一个公共 DNS 服务提供器。

用法

Unbound 适用于各大操作系统(Linux、BSD、Windows、MacOS),这里以 Linux 为例。下载安装后,配置文件目录应当在 /etc/unbound,其中 /etc/unbound/unbound.conf.d 目录下存放你的自定义配置。应当注意到,此目录下已经有一个名为 root-auto-trust-anchor-file.conf 的文件,内容如下。

server:
    # The following line will configure unbound to perform cryptographic
    # DNSSEC validation using the root trust anchor.
    auto-trust-anchor-file: "/var/lib/unbound/root.key"

此文件用来进行 DNSSEC 验证,不要动它。我们在此目录下新建一个文件,名字取为 service.conf(或其他名字,只要以 .conf 结尾即可),内容如下。

server:
    verbosity: 0
    interface: 127.0.0.1
    prefer-ip4: yes
    hide-identity: yes
    hide-version: yes
    hide-trustanchor: yes
    prefetch: yes
    prefetch-key: yes
    aggressive-nsec: yes
    deny-any: yes
    do-not-query-localhost: no
    num-threads: 2
    msg-cache-slabs: 2
    rrset-cache-slabs: 2
    infra-cache-slabs: 2
    key-cache-slabs: 2
    rrset-cache-size: 20m
    msg-cache-size: 10m
    so-rcvbuf: 4m
    so-sndbuf: 4m
    outgoing-range: 500
    num-queries-per-thread: 250
    private-address: 10.0.0.0/8
    private-address: 172.16.0.0/12
    private-address: 192.168.0.0/16
    private-address: 169.254.0.0/16
    private-address: fd00::/8
    private-address: fe80::/10

配置文件中各项参数的含义参见文档。以上配置适合 2 线程的 CPU,其他情况可根据性能调优文档进行修改。

然后只需编辑 /etc/resolv.conf 文件,将其内容修改为 nameserver 127.0.0.1,并运行 chattr +i /etc/resolv.conf 命令以防止其被诸如 NetworkManager 之类的程序修改。

验证

须验证 DNSSEC 是否正常工作。运行以下命令。

dig sigfail.verteiltesysteme.net
dig sigok.verteiltesysteme.net

第一行命令的输出应当包含 SERVFAIL 状态码,且 DNS 服务器为 127.0.0.1#53;第二行命令的输出应当包含 NOERROR 状态码和一个 IPv4 地址,且 DNS 服务器为 127.0.0.1#53