共计 3064 个字符,预计需要花费 8 分钟才能阅读完成。
记得在很久以前,大概还是拨号上网的年代,我们在浏览器里输入一个错误的网址,跳转出来的往往不是浏览器的报错页面,而是运营商精心准备的“导航网站”,上面贴满了各种花花绿绿的广告。那时候不懂技术,只觉得运营商好贴心,还怕我迷路。后来才明白,这不过是 DNS 劫持的一种最原始的表现形式。如今虽然这种赤裸裸的流氓行为少了一些,但 DNS 查询依然是我们隐私泄露的重灾区。你访问了哪个网站,在什么时间访问的,对于掌控着 DNS 服务器的 ISP 来说,简直就是透明的。为了把这最后一块隐私拼图补上,我开始关注 [[DoH]],也就是 DNS over HTTPS。
我们为什么需要给 DNS 加把锁
要理解 DoH,首先得回过头来看看传统的 DNS 是怎么工作的。打个比方,传统的 DNS 查询就像是写明信片。你在明信片上写着“我要去 google.com”,然后把它丢进邮筒。在这个过程中,邮递员(ISP)、负责分拣的中间设备、甚至是你隔壁懂点技术的邻居,只要他们想,都能看到你这张明信片上写了什么。这就是为什么在公共 WiFi 下上网很不安全的原因之一,也是为什么某些地区能通过 DNS 污染来阻止你访问特定网站。
而 DoH,全称 DNS over HTTPS,它的做法是把这张“明信片”塞进了一个厚厚的信封里,并且还加上了密封火漆。这个信封就是 HTTPS 协议。在网络传输的过程中,外部观察者只能看到你发出了一个 HTTPS 请求(就像你访问普通的网页一样),但完全不知道这个请求里包含的内容是 DNS 查询,也不知道你到底想去哪个网站。这种混淆流量的做法,不仅保护了隐私,还顺带解决了一个大麻烦:因为 DoH 使用的是标准的 443 端口,和我们日常访问网页的流量一模一样,网络管理者很难在不屏蔽所有 HTTPS 流量的前提下单独屏蔽 DoH。这对于身处复杂网络环境中的我们来说,无疑是一个巨大的优势。
深入剖析 DoH 的独特优势
在 DoH 出现之前,其实已经有了 DNS over TLS(DoT)。DoT 同样加密了 DNS 查询,但它使用的是专门的 853 端口。这就像是你虽然用了信封,但在这个信封上贴了个巨大的标签:“这是一封 DNS 查询信”。网络管理员只要简单粗暴地封锁 853 端口,就能让你的 DoT 失效。相比之下,DoH 就“鸡贼”得多,它把自己伪装成普通的 Web 流量,隐藏在浩瀚的 HTTPS 数据流中,这种“大隐隐于市”的策略,让它拥有了更强的抗干扰能力。
我在实际使用中发现,DoH 的另一个好处是浏览器的原生支持。现在的 Chrome、Firefox 甚至 Edge 都内置了 DoH 客户端。这意味着,即使你的操作系统层面的 DNS 被劫持或者配置错误,只要你开启了浏览器的 DoH 功能,你的网页浏览依然是安全且准确的。特别是配合一些能够过滤广告的上游 DNS 服务器(比如 [[AdGuard]] 的 DNS),还能在源头上屏蔽掉不少烦人的追踪器和广告脚本,网页加载速度反而因为减少了多余请求而变快了。
手把手搭建私有 DoH 服务器
说了这么多理论,如果不自己动手搭一个,总觉得差点意思。市面上虽然有 [[Cloudflare]] 或 Google 提供的公共 DoH 服务,但考虑到网络延迟和“鸡蛋不能放在同一个篮子里”的原则,我更倾向于在自己的 VPS 上搭建一个私有的 DoH 服务器。这样不仅能掌控日志(或者选择完全不记录日志),还能自定义过滤规则。
我的搭建方案是:前端使用 [[Nginx]] 处理 HTTPS 请求,后端使用 [[AdGuard Home]] 处理 DNS 查询。选择 AdGuard Home 是因为它自带了非常漂亮的 Web 管理界面,而且支持各种 DNS 过滤规则,维护起来非常省心。
首先,我们需要在 VPS 上安装 AdGuard Home。如果你习惯使用 [[Docker]],那这步简直易如反掌。只需要拉取镜像,映射端口,几行命令就能跑起来。这里需要注意的是,因为我们要用 Nginx 做反向代理,所以 AdGuard Home 的 Web 管理端口和 DNS 端口最好映射到本地或者是 Docker 的内部网络,不要直接暴露在公网。
接下来是重头戏,配置 Nginx。你需要申请一个域名,并为它申请 SSL 证书(推荐使用 [[Let’s Encrypt]],免费且自动化)。在 Nginx 的配置文件中,我们需要设置一个 location 块,将特定的路径(比如 /dns-query)转发到后端 AdGuard Home 的 DoH 端口。
配置文件的核心部分大概长这样(仅作示意):
location /dns-query {
proxy_pass http://127.0.0.1:3000/dns-query;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
这里可能会遇到的一个坑是 Content-Type 的处理。标准的 DoH 客户端会发送 application/dns-message 类型的请求,确保 Nginx 没有对这种类型的请求做奇怪的拦截或缓存。搭建完成后,你可以在 AdGuard Home 的“加密设置”里看到刚才配置的域名是否生效。最后,别忘了在客户端(比如你的 [[iOS]] 设备或 [[Clash]] 配置文件)填入你的 DoH 地址,通常格式是 https://your-domain.com/dns-query。
更加轻量与极简的替代方案
如果你觉得上面的 Nginx 加 AdGuard Home 的组合拳有点过于硬核,或者你压根就不想维护一台 VPS,那这里还有两个让我觉得眼前一亮的替代方案,它们在易用性和成本之间找到了不同的平衡点。
首先是无需服务器的 [[RethinkDNS]] 方案。这个项目简直是“服务器恐惧症”患者的福音。它最大的特点是 Serverless,你可以直接把它的解析服务部署在 [[Cloudflare Workers]] 或者 [[Deno]] Deploy 上。这意味着你不仅不需要付 VPS 的钱,还能享受到 Cloudflare 那遍布全球的边缘节点速度。配置过程异常简单,基本上在 GitHub 上 Fork 项目后,点击几下部署按钮就能搞定。对于那些只想安安静静做个 DNS 查询,不需要太复杂日志分析的朋友来说,RethinkDNS 绝对是性价比最高的选择。
其次是主打傻瓜式部署的 [[NbDNS]]。如果你手头有服务器,但一看到 Nginx 的配置文件和复杂的证书申请流程就头大,那 NbDNS 就是为你准备的。作者的设计初衷似乎就是为了解决配置繁琐的问题,它把核心功能封装得非常好,几乎不需要你去折腾反向代理的细节,一键脚本就能把服务跑起来。它就像是一个精简版的 DoH 服务端,去掉了那些花里胡哨的功能,只保留了最核心的 DNS over HTTPS 转发能力,非常适合在配置较低的“小鸡”(低配 VPS)上跑,资源占用极低且足够稳定。
最后
折腾完这一套流程,当你看到 AdGuard Home 的后台仪表盘上开始跳动一个个绿色的查询请求时,那种掌控感是非常迷人的。搭建私有 DoH 服务器,不仅仅是为了防止运营商的偷窥,更是为了在这个日益封闭和中心化的网络世界里,保留一份属于自己的选择权。
技术本身是中立的,DoH 既可以被用来保护隐私,也可能被恶意软件利用来隐藏通信。但对于我们普通用户来说,多掌握一种工具,就多了一分在数字世界中自由行走的底气。或许下一次,当你身处一个陌生的公共网络,或者发现某个网站莫名其妙打不开时,这个静静运行在远端服务器上的小服务,会成为你最可靠的向导。

