从原理到加密:全面解析DNS及DoH/DoT配置指南

互联网的每一个角落都建立在数字之上,即 IP 地址(例如 172.217.160.78)。但对于人类来说,记住一长串无规律的数字显然是不现实的。我们更擅长记住像 google.com 这样的域名。那么,计算机是如何将我们输入的域名“翻译”成机器能够理解的 IP 地址呢?答案就是 DNS (Domain Name System, 域名系统)

本文将带你从 DNS 的基础工作原理出发,亲手搭建一个本地 DNS 服务器,并最终升级到更安全、更私密的加密 DNS (DoH/DoT),让你彻底掌握这个互联网世界的核心枢纽。

一、DNS 工作原理:互联网的“电话簿”

你可以将 DNS 简单地理解为一本庞大且分布在全球的“电话簿”。当你想要访问 www.google.com 时,你的计算机会向 DNS 系统查询,DNS 则会告诉你 www.google.com 对应的“电话号码”(IP 地址)是 172.217.160.78。这个查询过程通常是递归的,涉及多个层级的服务器,主要分为以下几个步骤:

  1. 客户端请求:你的浏览器首先检查自己的缓存,如果没有找到记录,它会向操作系统配置的 本地 DNS 解析器 (Recursive Resolver) 发出请求。这个解析器通常由你的网络服务提供商 (ISP) 提供,或者你也可以手动设置为公共 DNS,如 Google 的 8.8.8.8

  2. 递归查询开始:本地 DNS 解析器收到请求后,也会先检查自己的缓存。如果缓存中没有,它将开启一次完整的递归查询之旅:

    • 第一站:根域名服务器 (Root Servers):解析器首先询问全球仅有的 13 组根服务器:“谁知道 .com 域名归谁管?” 根服务器不会直接告诉它 google.com 的 IP,而是回复一个 .com 顶级域 (TLD) 名服务器 的地址列表。
    • 第二站:顶级域 (TLD) 名服务器:解析器接着向列表中的一个 .com TLD 服务器发送请求:“谁知道 google.com 归谁管?” TLD 服务器同样不会直接给出最终答案,而是指向管理 google.com 这个域的 权威名称服务器 (Authoritative Name Server)
    • 第三站:权威名称服务器:最后,解析器向 google.com 的权威名称服务器(通常由 Google 自己管理)发送请求:“www.google.com 的 IP 地址是什么?” 这次,权威名称服务器会给出最终的、准确的 IP 地址。
  3. 结果返回与缓存:本地 DNS 解析器获取到 IP 地址后,会将其返回给你的计算机,同时将这个记录缓存一段时间(由 TTL 值决定)。这样,在缓存有效期内,当再次访问同一个域名时,解析器就可以直接从缓存中返回结果,大大加快了访问速度。

二、搭建本地 DNS 缓存服务器 (使用 Dnsmasq)

每次都向上级 DNS 服务器查询会增加延迟。通过在你的局域网内搭建一个 DNS 缓存服务器,可以让网络内所有设备的首次查询结果都被缓存下来,显著提升后续访问的速度。我们将使用 dnsmasq,一个轻量级的 DNS、DHCP 和 TFTP 服务器,非常适合家庭或小型办公网络。

步骤 1: 安装 Dnsmasq

在基于 Debian 或 Ubuntu 的系统上,安装非常简单:

1
2
sudo apt update
sudo apt install dnsmasq

步骤 2: 配置 Dnsmasq

dnsmasq 的主配置文件是 /etc/dnsmasq.conf。在修改前,最好先备份一份:

1
sudo cp /etc/dnsmasq.conf /etc/dnsmasq.conf.backup

然后,编辑配置文件:

1
sudo nano /etc/dnsmasq.conf

以下是一些推荐的配置项,你可以将它们添加到文件末尾(或取消已有行的注释并修改):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 监听端口,53是DNS的标准端口
port=53

# 指定监听的IP地址。127.0.0.1 是为了本机测试,
# 192.168.1.1 是你服务器的内网IP,用于服务局域网内其他设备
# 请将其替换为你服务器的实际IP地址
listen-address=::1, 127.0.0.1, 192.168.1.1

# 绑定到指定的网络接口,增强安全性
bind-interfaces

# 设置上游DNS服务器(当本地无缓存时,dnsmasq会向这些服务器查询)
# 这里使用了 Google 和 Cloudflare 的公共DNS
server=8.8.8.8
server=1.1.1.1

# 从 /etc/hosts 文件中读取本地DNS记录,方便自定义域名
expand-hosts

# 增加DNS缓存条数,默认为150
cache-size=1000

步骤 3: 启动并验证服务

保存配置文件后,重启 dnsmasq 服务使其生效:

1
2
sudo systemctl restart dnsmasq
sudo systemctl status dnsmasq

使用 dig 命令来测试缓存服务器是否正常工作:

1
2
3
4
5
# 第一次查询,会向上游服务器请求
dig @127.0.0.1 www.bilibili.com

# 第二次查询,应该会直接从缓存返回,Query time 会显著降低
dig @127.0.0.1 www.bilibili.com

在输出中,留意 Query time 的变化,以及 SERVER 字段是否指向 127.0.0.1#53

三、DNS 的安全进化:DoT 与 DoH

传统的 DNS 查询(端口 53)是 明文传输 的。这意味着在你和 DNS 服务器之间的任何节点(如你的 ISP、网络中的黑客)都能轻易地看到你访问了哪些网站,甚至可以篡改查询结果,将你引向恶意网站(DNS 劫持)。

为了解决这个问题,加密 DNS 应运而生,其中最主流的两种技术是:

  • DNS over TLS (DoT): 将 DNS 查询和响应通过 TLS (传输层安全协议) 加密通道进行传输。它使用专门的端口 853。由于端口是固定的,它仍然可能被网络管理员或防火墙识别并屏蔽。

  • DNS over HTTPS (DoH): 将 DNS 查询数据打包成 HTTPS 请求,通过标准的 HTTPS 端口 443 发送。由于 DoH 流量与普通的网页浏览流量(HTTPS)混杂在一起,它极难被识别和过滤,提供了更强的抗封锁能力和隐私保护。

四、配置 DoH 客户端 (使用 cloudflared)

我们可以通过 Cloudflare 提供的 cloudflared 工具,在本地搭建一个 DoH 代理。它会接收本地的普通 DNS 请求,将其加密并通过 DoH 发送出去,从而保护你的 DNS 查询隐私。

步骤 1: 安装 cloudflared

1
2
3
4
5
# 下载适用于 AMD64 架构的 Debian 包
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb

# 安装软件包
sudo dpkg -i cloudflared-linux-amd64.deb

步骤 2: 配置为 DoH 服务

cloudflared 配置为一个系统服务,让它在后台作为 DNS 代理运行。

1
2
# 这条命令会创建一个服务,并生成一个默认配置文件
sudo cloudflared service install

默认情况下,cloudflared 会监听 127.0.0.1:53。为了与我们之前配置的 dnsmasq 整合,我们需要让它们监听在不同的端口。我们让 cloudflared 监听 127.0.0.1:5053

编辑 cloudflared 的配置文件:

1
sudo nano /etc/cloudflared/config.yml

将文件内容修改为:

1
2
3
4
5
6
7
8
9
10
11
# 这个文件使用 YAML 格式
# 指定代理监听的端口和地址
proxy-dns: true
proxy-dns-port: 5053
proxy-dns-address: 127.0.0.1

# 指定上游的 DoH 服务器
upstream:
- https://1.1.1.1/dns-query
- https://1.0.0.1/dns-query
- https://dns.google/dns-query

步骤 3: 整合 dnsmasq 与 cloudflared

现在,我们修改 dnsmasq 的配置,让它不再向 8.8.8.8 等公共 DNS 发送明文查询,而是将所有查询转发给我们本地的、加密的 cloudflared 服务。

编辑 /etc/dnsmasq.conf

1
sudo nano /etc/dnsmasq.conf

注释掉或删除所有旧的 server= 行,并添加一行新的,指向 cloudflared 监听的端口:

1
2
3
4
5
6
# ... 其他配置保持不变 ...

# 将所有查询转发到本地的 cloudflared DoH 代理
server=127.0.0.1#5053

# ... 其他配置保持不变 ...

步骤 4: 重启服务并最终验证

重启两个服务以应用所有更改:

1
2
sudo systemctl restart cloudflared
sudo systemctl restart dnsmasq

现在,你的网络查询流程变成了:

客户端设备 -> dnsmasq (缓存) -> cloudflared (加密) -> DoH 服务器

你可以将局域网内其他设备的 DNS 服务器地址设置为你这台服务器的 IP (192.168.1.1)。这样,整个局域网的 DNS 查询都将享受到 缓存加速DoH 加密 的双重好处。

要验证 DoH 是否生效,可以访问 Cloudflare 的帮助页面:https://1.1.1.1/help。如果一切正常,页面上的 “Using DNS over HTTPS (DoH)” 项目应该会显示 “Yes”。

总结

DNS 是我们畅游数字世界的向导。通过本文的实践,你不仅理解了它的工作原理,还学会了如何通过 dnsmasq 提升网络性能,更重要的是,学会了使用 cloudflared 和 DoH 技术来保护自己的网络隐私和安全,抵御潜在的监控和劫持。在一个日益重视数据隐私的时代,掌握这些技能无疑是为你的数字生活增添了一道坚实的壁垒。