如何在 Ubuntu 上使用 Nginx 轻松设置 DNS over TLS Resolver

本教程将向您展示如何设置自己的 基于 TLS 的 DNS (DoT) 解析器在 Ubuntu 上使用 Nginx,因此您的 DNS 查询可以被加密并防止被窥探。

什么是基于 TLS 的 DNS 及其重要性

DNS(域名系统)负责将域名转换为 IP 地址。 它是在 1987 年设计的,没有考虑到安全或隐私。 默认情况下,DNS 查询未加密。 它们在线路上以纯文本形式发送,可以被中间实体利用。 例如,中国的防火墙(GFW) 使用一种称为 DNS缓存毒 审查中国互联网。 (他们还使用其他方法,这超出了本文的范围。)

GFW 会检查发送到中国境外 DNS 服务器的每个 DNS 查询。 由于纯文本 DNS 协议基于 UDP,这是一种无连接协议,GFW 可以欺骗客户端 IP 和服务器 IP。 当 GFW 在其阻止列表中找到域名时,它会更改 DNS 响应。 例如,如果中国互联网用户想要访问 google.com,GFW 会将位于中国的 IP 地址而不是 Google 的真实 IP 地址返回给用户的 DNS 解析器。 然后 DNS 解析器将假 IP 地址返回给用户的计算机,因此用户无法访问 google.com。

DNS over TLS 意味着 DNS 查询通过使用 TLS 加密的安全连接发送,TLS 是加密 HTTP 流量的相同技术。

为什么要运行自己的 DoT 解析器?

已经有一些公共 DNS 解析器,如 1.1.1.1 和 9.9.9.9 支持 DNS over TLS,因此如果您没有技能或时间来运行自己的解析器,可以使用它们。 但是,有些人认为这仍然允许大型 DNS 服务提供商收集有关用户的信息。 他们似乎更信任他们的 ISP。 但我认为,如果您对隐私有疑虑,您应该运行自己的 DoT 解析器,这样大型 DNS 服务提供商和您的 ISP 都无法监视您。

目前,并非所有 DNS 解析器(BIND、Unbound、Knot 解析器、PowerDNS 递归器等)都支持 DNS over TLS。 我将向您展示如何为您现有的 DNS 解析器设置 Nginx TLS 代理以提供 DoT 服务,而不是为特定解析器制作指南,因此无论您使用什么 DNS 解析器,您都可以按照本教程进行操作。

先决条件

假设您在 Ubuntu 服务器上运行了一个 DNS 解析器。 您可以使用任何 DNS 解析器(BIND、Unbound、Knot 解析器……)我个人使用 BIND。

  • 在 Ubuntu 16.04/18.04 上设置你自己的 BIND9 DNS 解析器
  • 在 Ubuntu 20.04 上设置你自己的 BIND9 DNS 解析器

您还需要一个域名,因为 DNS 客户端需要与我们的 DNS 解析器建立安全的 TLS 连接。 我从 NameCheap 注册了我的域名,因为价格低廉,而且他们提供终身免费的 whois 隐私保护。

满足上述要求后,请按照以下说明进行操作。

第 1 步:在 Ubuntu 服务器上安装 Nginx

这很容易做到。 只需运行以下命令。

sudo apt install nginx

第 2 步:从 Let’s Encrypt 获取受信任的 TLS 证书

DNS over TLS 需要在服务器端安装 TLS 证书。 我们将获取并安装 Let’s Encrypt 证书。 使用 Let’s Encrypt 证书的优势在于它是免费的,更容易设置,并且受到客户端软件的信任。

运行以下命令以从默认的 Ubuntu 存储库安装 Let’s Encrypt 客户端 (certbot)。

sudo apt install certbot

要获得 Let’s Encrypt TLS 证书,我们可以使用以下命令创建 Nginx 虚拟主机。 替换 dot.example.com 用你自己的域名。 不要忘记为此子域创建 DNS A 记录。

sudo nano /etc/nginx/conf.d/dot.example.com.conf

复制以下文本并将其粘贴到虚拟主机文件中。

server {
      listen 80;
      server_name dot.example.com;

      root /usr/share/nginx/html/;

      location ~ /.well-known/acme-challenge {
         allow all;
      }
}

Save 和 close 文件。 重新加载 Nginx 以使更改生效。

sudo systemctl reload nginx

创建并启用虚拟主机后,运行以下命令以使用 webroot 插件获取 Let’s Encrypt 证书。

sudo certbot certonly --webroot --agree-tos --email [email protected] -d dot.example.com -w /usr/share/nginx/html/

第 3 步:在 Nginx 中创建 DNS over TLS 代理

编辑 Nginx 主配置文件。

sudo nano /etc/nginx/nginx.conf

在此文件的底部添加以下行。 请注意,它们需要放置在 http 语境。

stream {
    # DNS upstream pool
    upstream dns {
        zone dns 64k;
        server 127.0.0.1:53;
    }

   # DoT server for decryption
   server {
        listen 853 ssl;
        ssl_certificate /etc/letsencrypt/live/dot.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/dot.example.com/privkey.pem;
        proxy_pass dns;
    }
}

在上面的配置中,我们让 Nginx 在端口 853 上终止 TLS 连接,然后它将 DNS 请求重定向到本地 DNS 解析器侦听 127.0.0.1:53.

Save 和 close 文件。 然后测试Nginx配置并重启。

sudo nginx -t
sudo systemctl restart nginx

如果Ubuntu服务器上运行了防火墙,则需要打开TCP 853端口。例如,如果您使用UFW防火墙,则运行以下命令。

sudo ufw allow 853/tcp

由于我们使用的是基于 TLS 的 DNS,因此无需担心 DNS 放大攻击。

步骤 5:在 Ubuntu 桌面上配置 Stubby DoT 客户端

Stubby 是由 getdns 团队开发的开源 DNS 存根解析器。 存根解析器是最终用户计算机上的小型 DNS 客户端,它接收来自 Firefox 等应用程序的 DNS 请求,并将请求转发到递归解析器,例如 1.1.1.1 或 8.8.8.8。 Stubby 的特殊之处在于它支持基于 TLS 的 DNS。 默认情况下,它只会发送加密的 DNS 请求。

从默认存储库在 Ubuntu 桌面上安装 Stubby。

sudo apt install stubby

安装后,stubby 在后台运行。 检查其状态:

systemctl status stubby

Stubby 侦听本地主机 (127.0.0.1) 的 TCP 和 UDP 端口 53。 默认情况下,Stubby 使用第三方 DNS over TLS 解析器。 我们需要配置它以使用我们自己的。

sudo nano /etc/stubby/stubby.yml

向下滚动到 upstream_recursive_servers: 部分并在其他 DNS 服务器上方添加以下文本。 将 12.34.56.78 替换为 DoT 解析器的 IP 地址。

# My Own DNS over TLS resolver
  - address_data: 12.34.56.78
    tls_auth_name: "dot.example.com"

然后找到以下行:

round_robin_upstreams: 1

改变 10. 这将使 stubby 始终使用您自己的 DNS over TLS 解析器。 如果它不可用,stubby 将使用其他 DNS 服务器。 Save 文件并重新启动 stubby 以使更改生效。

sudo systemctl restart stubby

第 6 步:配置 Ubuntu 桌面以使用 Stubby

尽管 Stubby 正在运行,但操作系统并未使用它。 单击桌面右上角的网络管理器图标。 然后选择有线设置。 (如果您使用的是 Wi-fi,请选择 Wi-fi 设置。)

加密DNS

单击齿轮按钮。

tls 上的 cloudflare dns

选择 IPv4 选项卡,然后在 DNS 设置中,切换 Automatic 关闭,这将阻止您的 Ubuntu 系统从您的路由器获取 DNS 服务器地址。 Enter 127.0.0.1 在 DNS 字段中。 点击 Apply 按钮保存更改。

通过 tls 端口 853 的 dns

然后重新启动 NetworkManager 以使更改生效。

sudo systemctl restart NetworkManager

重新连接后,您可以看到您的 Ubuntu 系统现在使用 127.0.0.1 作为 DNS 服务器 Details 标签。

tls 上的存根解析器 dns

如何检查您的 DNS 流量是否已加密

我们可以使用 WireShark 来监控 DNS 流量。 在 Ubuntu 桌面上安装 WireShark。

sudo apt install wireshark

如果您被问到“非超级用户是否应该能够捕获数据包?”,请回答“是”。 安装后,运行以下命令将您的用户帐户添加到wireshark 组,以便您可以捕获数据包。

sudo adduser your-username wireshark

注销并重新登录以使更改生效。 然后从您的应用程序菜单中打开 WireShark,在 WireShark 中选择您的网络接口。 例如,我的以太网接口名称是 enp5s0。 然后输入 port 853 作为捕获过滤器。 这将使 WireShark 仅捕获端口 853 上的流量,这是 DNS over TLS 使用的端口。

ubuntu 18.04 粗短

单击左上角的按钮开始捕获。 之后,在终端窗口中,使用以下命令查询域名 dig 公用事业。 例如,我可以查询我的域名的 A 记录。

dig A linuxbabe.com

现在您可以在 WireShark 中看到捕获的 DNS 流量。 连接通过 TCP 建立并使用 TLS 加密,这正是我们想要的。 您应该检查 Destination 列是否包含您的 DoT 解析器的 IP 地址。

安全DNS

如果未加密发送 DNS 查询,则计算机将在端口 53 上联系 DNS 服务器。您可以再次捕获数据包 port 53 作为捕获过滤器,但您不会在 WireShark 中看到任何数据包,这意味着 stubby 正在加密您的 DNS 查询。

总结

我希望本教程可以帮助您在 Ubuntu 上使用 Nginx 设置 DNS over TLS 解析器。 您可能还想阅读:

  • 使用 DNSdist 在 Ubuntu 上通过 HTTPS (DoH) 解析器运行您自己的 DNS

与往常一样,如果您发现这篇文章有用,请订阅我们的免费时事通讯以获取更多提示和技巧。 保重?