如何在 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"