通过 Cloudflare Workers&Pages 搭建 DOH 服务,解决 DNS 污染

听说校园网对你站搞了 dns 污染,不能直接打开?由于众所周知的原因,国外的 doh 服务在国内不是无法使用,就是解析速度感人;国内诸如 阿里家360 家腾讯家 的 doh 虽说可以解决你站的 dns 污染,但在国内网络环境下其他该被污染的网站依然会被污染。
因此,可以使用 cloudflare 提供的 workers/pages 免费计划,搭建一个自用的 doh 服务,并可配合优选手段,实现更加快速、准确、安全的 dns 解析,一劳永逸的解决 dns 污染问题。

适用平台

目前 Chrome、Firefox、Edge 等主流浏览器在 PC 端均有自带的 doh 功能,前不久 Firefox 的安卓客户端也添加了 doh 功能

要求

  • Cloudflare 帐号
  • 一个域名(可选,若使用 Workers 搭建域名需托管在 Cloudflare 上)
  • github 帐号(可选,可以 Fork 仓库自动同步实现自动更新、修改)

相关项目

注意事项

  • Cloudflare Workers&Pages 免费计划每天有十万次的请求次数 (用不完,根本用不完)
  • 使用 Cloudflare Workers/Pages搭建doh中转并不违反Cloudflare服务条款,可放心使用
  • 通过优选 IP、优选域名等手段提升国内的使用质量这一做法,理论上违反 Cloudflare 服务条款,可能会引起警告、封号等后果,但 doh 占用的流量微乎其微,应该没人会较真,毕竟还有那么多用优选跑代理的
  • doh 默认的/dns-query 查询路径会被 有关部门的 探测节点主动探测并封禁域名 (本人就被封过几次),因此最好修改默认的查询路径

搭建流程

  • Pages 搭建
    Pages 默认的域名没有被墙,所以不需要自备域名,也不需要修改路径,可以直接用。但 Pages 的优选方法相对麻烦,查询速度取决于运营商和网络质量。
    首先 Fork doh-cf-pages 仓库


    在 Cloudflare 的 Workers 和 Pages 界面选择“创建应用程序”,选择“Pages”–>“导入现有 Git 存储库”,绑定 github 帐号,选取刚才 fork 的仓库

    修改项目名称,构建设置默认,保存并部署,大功告成。之后复制生成的域名到浏览器的 doh 配置界面,粘贴使用即可。这个项目默认可使用任何路径查询,如果需要修改可自行修改代码

  • Workers 搭建
    Workers 搭建的步骤和 Pages 的差不多,差别在于:Workers 默认的域名被墙了,需要绑定自定义域名;Workers 可以直接创建一个 Hello World 应用,然后点击编辑代码,复制粘贴 doh-cf-workers 中 index.js 的内容,点击部署即可,修改中转至的 doh 服务、解析路径也可以通过这种方法修改。

  • Workers 优选域名
    在浏览器使用 doh 进行 dns 查询前,会先使用系统 dns 查询 doh 的 ip。众所周知,cloudflare 在国内的使用体验并不算好,虽说用的是泛播 ip,但国内往往会解析到美国,因此可以通过优选改善使用体验。这一做法违反 cloudflare 的服务条款,自行衡量风险
    首先需要有一个托管到 cloudflare 的域名,我使用的是在 dpdns.org 上注册的免费三级域名。在域名的 DNS 界面添加一个 CNAME 记录,CNAME 目标域名可自行搜索优选域名,并在本地网络环境进行测试。注意一定要关闭小黄云。


    然后选择 Workers 路由,根据以下格式添加一条路由即可。

4 Likes

学习了:face_savoring_food:

只要不使用常见默认查询路径就不会被主动探测吗?:thinking:

会不会存在对 DoH 流量的特征分析之类的机制?(不是很懂)

1 Like

有,doh 的流量特征其实挺明显的:大量小数据包组成的 tls 加密连接。不过已经 tls 加密了,最多通过 client hello 信息看到访问的域名,是看不到访问的路径的,所以只能探测默认路径。

2 Likes

DoH 本质和 HTTPS 是一样的,至少我用了有一年了没有遇到什么问题

不过 DoH 的流量包特征比较明显,一小一大,基于机器学习的流量分析应该可以很轻松地发现

分享一波我用 Caddy 搭的 DoH 代理:

ah.example.com {
    route /ciallo* {
        rewrite * /dns-query
        reverse_proxy {
            to https://dns.google https://cloudflare-dns.com https://dns.quad9.net https://dns.adguard.com
            lb_policy random
            header_up Host {upstream_hostport}
        }
    }
    respond "Not Found 404" 404
}

最后查询的 DoH 地址就为:https://ah.example.com/ciallo

1 Like

我见过有的 custom dns server 可以给 response 加 padding 削弱特征,比如这个:

padding: 将加密 DNS 的报文填充至固定长度,防止流量分析。

不过效果未知,因为我搭在本地。(

1 Like

stateless 是学网工的嘛?我看 GitHub 活动好多和网络相关(

只是比较感兴趣(

关于为什么,可以在解构栈上单开一栈来分析了 :rofl:

2 Likes