使用 Knot-Resolver 自建 DNS

一、什么是 DNS

DNS(Domain Name System)是一个全球化的分布式数据库,用于存储域名与互联网 IP 地址的映射关系。DNS 分为两大类:权威 DNS,递归 DNS。

  • 权威 DNS: 权威 DNS 服务器只对自己所拥有的域名进行域名解析,对于不是自己的域名则拒绝访问。比如,向 “example.com” 的权威 DNS 服务器查询 “test.com” 的域名肯定会查询失败。
  • 递归 DNS: 递归 DNS(也称本地 DNS 或者缓存 DNS)用于域名查询。递归 DNS 会迭代权威服务器返回的应答,直至最终查询到的 IP 地址,将其返回给客户端,并将请求结果缓存到本地。

二、自建 DNS 的作用

  • 提供 DNS 缓存。将 DNS 查询结果缓存下来,避免重复向上查询 DNS 结果,提高查询速率。
  • 防止 DNS 污染。部分 DNS 提供商会针对部分 DNS 查询返回错误的结果,以达到无法访问或跳转到错误目标地址的目的,自建 DNS 服务则可以避免这样的情况。

三、递归 DNS 的选型

选型主要有两个:

3.1 Knot Resolver

Knot Resolver 是 Knot DNS (高性能的权威 DNS 服务器)的子项目

  • 项目开源,源代码在 GPL 许可下可用。
  • 高性能,服务器采用与其余 DNS 递归器不同的缩放策略 —— 无线程、无共享架构(除了可能共享的缓存)。可以在不停机的情况下启动、停止或重新配置实例。

3.2 CoreDNS

CoreDNS 是 k8s 中的一个插件,可作为 k8s 的服务发现,也可单独作为 DNS 服务器使用。

  • 使用 Go 语言编写,项目开源,在 Apache License Version 2 许可下可用。
  • 配置文件简单,语法类似于 Caddyfile。
  • 插件丰富,通过插件可提供外部缓存等功能。

四、搭建 Knot-Resolver

本文就先使用 Knot-Resolver 来搭建 DNS 服务

4.1 安装

1
2
3
4
wget https://secure.nic.cz/files/knot-resolver/knot-resolver-release.deb
dpkg -i knot-resolver-release.deb
apt update
apt install -y knot-resolver

4.2 启动服务

1
2
3
4
# 启动服务
systemctl start kresd@1.service
# 开机自启服务
systemctl enable kresd@1.service

五、配置

配置文件路径:

1
/etc/knot-resolver/kresd.conf

5.1 监听接口

以下配置指示 Knot Resolver 在 IP 地址 127.0.0.1接收标准的未加密 DNS 查询和 DNS-over-TLS 查询

net.listen('127.0.0.1', 53, { kind = 'dns' })
net.listen('127.0.0.1', 853, { kind = 'tls' })

5.2 限制访问

在使用 IP 防火墙不限制 DNS 解析器访问的情况下,可以使用结合查询源信息和策略规则的视图模块来实现访问限制。以下配置仅允许来自子网 192.0.2.0/24 中的客户端的查询,并拒绝所有其余的。

modules.load('view')

-- whitelist queries identified by subnet
view:addr('192.0.2.0/24', policy.all(policy.PASS))

-- drop everything that hasn't matched
view:addr('0.0.0.0/0', policy.all(policy.DROP))

5.3 转发

将 DNS 查询转发到其他公共 DNS 服务商,将自动选择响应最快的 IP 地址进行返回。

policy.FORWARD() 函数一次最多接受四个 IP 地址

-- Forward all queries to public resolvers https://www.nic.cz/odvr
policy.add(policy.all(
   policy.FORWARD({
        '8.8.8.8', 
        '1.1.1.1'
    })
))

转发到 DNS-over-TLS 则是

policy.add(policy.all(
    policy.TLS_FORWARD({
        {'1.1.1.1', hostname='one.one.one.one'},
        {'1.0.0.1', hostname='one.one.one.one'}
    })
))

一些公共 DNS-over-TLS 提供商可能会应用速率限制,这使得他们的服务与 Knot Resolver 的 TLS 转发不兼容。值得注意的是,从 2019 年 7 月 10 日起, Google 公共 DNS将无法使用。

更多配置说明可以查看官方文档:Knot Resolver Docs


参考资料