域名解析结果替换JS DNS-Response-Replacer-JS 是我正在开发的一个用来替换DNS解析结果的工具。目前用于将使用 Cloudflare CDN 的网站域名解析结果替换为使用 Cloudflarespeedtest 优选结果。
本文写一些开发过程中的碎碎念。
Cloudflare 优选IP那些事
Cloudflare 这玩意不用我介绍了。我只能说这是我目前已知的能在网站受到攻击后不会以优先抛弃用户为操作准则的免费CDN。阿里腾讯那些狗屎CDN基本是只要用户被黑产瞄准后就优先抛弃用户。
唯一的问题是 Cloudflare 默认分配的IP在中国基本上很难用,速度很差,经常连接超时,甚至会被干扰(比如Cloudflare 流量遭大规模斗地主)。
在这种环境下,社区诞生了 Cloudflare IP优选工具 XIU2/CloudflareSpeedTest 。只不过这个工具只负责进行IP优选,具体使用则或是需要用户自己修改 Hosts,或者使用 iptables 这种复杂的网络工具,或者使用 3Proxy 配置代理或 mosdns 这种很难配置的DNS服务器,无论哪一个都很麻烦。
为此我想到的是,只是替换一个DNS解析结果,既不至于一个一个抠草莓籽,也不至于非要用麻烦复杂的工具大牛拉小车,不如自己造个轮子。
选型实现
首先是要选使用什么编程语言做这件事。
我个人目前能流畅使用的编程语言有 PHP、Javascript、bash 。这种复杂的本地应用,PHP 和 bash 都不适合,那能用的就只有 Javascript 了 。
我在使用 Javascript 和 Python 之间也纠结过一阵子,毕竟现在 Python 因为AI的原因实在是火得离谱了,前几年是个人就要吹自己会 Java,现在是个人就要吹自己会H5,马上过几年就得吹 Python 了。

图片来源:《震惊!开源项目Phobos开发者竟被大主播冒名顶替》
不过 再不学 Python 你就要被淘汰了 这个梗都过时了。
当然我是没完全用 Python 做过开发的,但是这种单一需求,现学现用应该也不是很难。
但是最终几个因素还是让我选择了js而不是py。
- Python 本地化应用我不知道最终部署后有多大的库依赖性,毕竟本身 Python 这玩意开发过程中装库的时侯就乱七八糟,又有全局安装又有虚拟环境。Node 这边我是知道只要 Node 能跑起来后所有乱七八糟的包和库都能打包
- 用AI问了一下,基本所有AI给得结论都是: Node 的性能比 Python 高的。这个有点反直觉,毕竟我骂了 Node 的服务端性能这么多年(毕竟我是写PHP的,且PHP也是免编译的解释性语言),突然冒出来个比 Node 还有历史的语言,热度远高于 Node,性能却比 Node 差
- 我没有做过纯 Node 开发,也没有做过 Python 开发。这两点生疏程度是一样的。但是 Javascript 的前端开发我是很熟悉的,大部分语言特性大坑我还是知道的,使用 Javascript 能避免摔很多跟头
- 最主要的还是,这种场景下,选择使用 Python 基本不会对自己的行业能力有多大提升。毕竟我是从通信网络测试自己转到软件开发的,这一块的区别我是亲身体验过的。学生阶段的自己写着玩和职业编程的差距就是天壤地别。这个时候用 Python 写程序的话基本就是闹着玩的级别,没什么学习价值,毕竟代码量工程量太小了。
使用AI起基本框架
这一块我偷懒了。
原本的开发流程,应该是先找个用 Node 实现的DNS服务器的开源项目,或者找对应的 Node DNS 解析库,然后照葫芦“切”瓢,一边研究DNS库怎么用,一边把对应的域名解析替换结果实现。
有了AI之后,直接让AI生成一个用 Node 实现的DNS服务器就得了,省去了到处翻开源项目然后被根本就跑不起来的不靠谱项目坑的过程。
其实也没多少代码量。也都说了,本身就是把拿到上游的解析结果中属于 Cloudflare CDN 的结果替换成指定的IP地址。唯一的难点也只在于,如何在没有 ipset 的场景下,判定一个 IPv4/IPv6 属于一个CIDR块。
基本功能一个下午就实现了。我其实也就是判定 A 记录和 AAAA 记录中有没有 Cloudflare 地址,其他类型一律不改动直接转发。
本质上这就是一个域名解析服务器。
把本机的DNS地址改成127.0.0.1,用了一天,没出问题。Cloudflare 的 IP 能正常更改成优选IP,非 Cloudflare 能够正常转发。

直接访问使用 Cloudflare CDN 的网站,速度快到起飞。爽!
我哪知道 DNS over TCP 是标配功能啊
不出意外的话,就要出意外了。
第二天也继续用自己写的服务做域名解析。
然后在我尝试使用淘宝的时侯,解析失败了……
用nslookup和dig测试对应的域名,100%复现。用对应的域名请求上游服务器,无问题。


“为啥?”我十分困惑。
检查了一下日志发现我写的服务根本没收到DNS请求。而当我直接向上游做DNS查询的时候,系统却是发了一个 TCP 请求。

啥? DNS over TCP ?这玩意是系统标配?我一直以为 DNS over TCP 就和 DoT DoH 一样只是个进阶的可选方案,没想到这玩意是标配。
(突然感觉自己老了)
简单来讲,传统的 DNS over UDP 包太小(512字节限制),超了这个限制,麻烦就不断。UDP当然能支持大于512字节的包(已存在对应的DNS扩展协议),但是连路上可能又会有其他设备把这一个包分片或者其他的处理错误。反正这破事光靠UDP是解决不了。
赶紧又写了一段 TCP 监听的代码。这玩意卡了我半天,因为 Node 的 UDP 库 和 TCP 库,风格完全不一样,而我 DNS 解析的那段代码写得太耦合了,半天扣不出来。最后没办法,不想抠了,直接写了段独立的完全仅代理DNS over TCP 的代码。我也是没发现用 Cloudflare CDN 有用到 DNS over TCP,Cloudflare 的结果基本都是一个域名对应两个IP,没有那么大,不会超过需要 DNS over TCP 才能处理的情况。
我也说了,这玩意基本是个人用,没必要做到企业级产品化的完成度。
UNKNOWN_65又是啥
调试的时候优化了一下日志输出,然后就看到一大堆 UNKNOWN TYPE 65 日志。

SCVB HTTPS。https://datatracker.ietf.org/doc/rfc9460/?include_text=1
DNS如今已经变得这么复杂了吗?
(顿时觉得自己快被淘汰了)
本地化部署那些事
这玩意自用也就是这么回事,但是如果想开源发布的话,就得考虑其他人如何安装这玩意。
打包
前文也说了,我没做过 Node 的本地化应用。打包这事情我是不知道怎么做的。
Linux 端目前我就是 sudo node dns-response-replacer-js.js
就跑起来了。确切的说还不是 sudo node
而是 sudo [全路径]/node
,因为 node 官方给的安装方案把 node 安装到了当前用户目录下了(~/nvm/versions/node/v22.17.1/bin/node
)。够傻的。
Windows 端我更是不知道怎么搞才是正确的。全局安装 Node 这事情放在菜鸟用户端不可能。我现在就直接把整个 node 官网提供的二进制文件都扔到项目文件夹里,然后 node 跑起来。Windows 端监听 53 端口不需要管理员权限这事情我也不知道该说啥好,但是弹出来的一次性防火墙设置要是选错了,我也不知道该去哪里改。
网络配置
前文也多次提到了,这玩意本质上是一个DNS服务器,而且严重依赖上游服务器。
我本机是 Linux Mint 22.1,基于 Ubuntu 24.04。Linux平台的resolv.conf的问题我就不多说了,对Linux网络配置熟悉的人基本都知道这玩意的恩怨情仇,不了解的朋友也只要知道:“这个保存着DNS服务器IP的resolv.conf文件在最近十多年间一直被各个阵营乱七八糟的应用接管,但一直就没个定数,更没有官方的简单的正规的清晰的明确的文档和配置指南”。
而Windows那边就更别提了,Win10/Win11就是Win7的套皮。Win10的网络配置套皮更是根本就没做完。

当然,与其说是没做完,到不如说是照搬照抄的 Android。 但是!原生 Android 的网络配置本身就是个残疾!

DHCP网络配置可以单独修改DNS这个设置自Win9x就是个功能项,但是因为Win10完全是照抄的安卓设计风格,所以直接把错误答案抄上去了。(就这操作,微软应该聘请姜萍)


Win11 倒是重新设计成 IP 和 DHCP 可以分开配置了。但是 Win11 是同时照抄了 MacOS 和 Android,设计更是混乱。好在 Win11 提供的配置页面藏得比 Win7 还深,所以大部分人配置网络配置会直接点开 Win7 的经典网络配置选项卡。(微软你自己也知道自己做的这玩意就是一坨屎啊)


不过当然,把DNS配置成 127.0.0.1
之后,不论是Win7还是Win10还是Win11,DNS配置在属性状态页都不显示。



(要是2030年微软再出个操作系统然后还继续用Win7的功能界面,那就是2010年的Bug一直带到2030年,满20年)
仅是操作系统这么烂就已经导致指导用户操作会变成一个巨大的障碍。
我想实现的是,依靠一些脚本,能实现把用户当前的DNS配置备份到文件,然后将本机DNS设置成127.0.0.1。等有需要时再通过备份文件把配置恢复。
这一块,Linux目前我只会操作 resolv.conf。理论上只要网络环境不变化(不重启,不断网,不DHCP续期),这个文件就不会变化,那我每次开机后手动把 nameserver 127.0.0.1
覆盖到 resolv.conf 应该就可以?但实际上 resolv.conf 的内容总是毫无规律的恢复成默认配置。至于 Windows,我更是懒得去弄。
懒。不想弄。目前的功能上我够用了,一下子就没动力继续开发了。
开源
我得说我没少给开源项目提过 Pull request,但是几乎没有收到过 Pull request。
虽然一方面我做的项目,小而精的基本都是拿来即用且完全没有修改的必要,大而肿的基本没人用。
当然最讨厌的一点,还是国内很多人拿了就用,有新功能新特性自己偷摸改了之后直接改了名字说是自己原创的,或者干脆像某为这种流氓公司一样直接就拿开源项目说自己做的,然后背地里还在你的issue提一堆乱七八糟的新需求,但是一点贡献都没有。
本身开源项目就是希望有相同需求的开发者能合作解决同一个痛点,但是现状就是很残酷的一个开发者给一堆白眼狼打工。
目前还有的可以填的坑:
- 支持 DNS over TCP 时的结果替换
- 更好的上游DNS查询方式(目前严重依赖配置文件中的第一条DNS服务器)
- 更好的本地缓存方式(目前使用的是同步保存到json文件)
- 支持 DNS over TLS
- 支持 DNS over HTTPS
- 支持 SVCB/HTTPS
- 热重载配置文件
- 支持其他 CDN 的解析替换
- 实现 Docker 部署
- 实现 Windows 服务
- 实现 Linux 服务
- 实现 Openwrt 服务
- 实现域名黑名单功能
- 实现IP黑名单功能
尤其是后两个,问题很严重。
第一个,目前 Cloudflare 官方提供的 [IP地址范围/IP Ranges] 并不是 100% 正确的,有很多IP地址并不属于 Cloudflare,而是由其他公司或组织在使用。如果遇到解析结果包含在 Cloudflare 官方提供的地址范围但实际所属并不是 Cloudflare CDN,会导致对应的域名无法访问。

第二个,部分 Cloudflare 的高级客户可能有自己独立的IP段,这些网站无法使用其他IP进行访问。以前单纯只用 Cloudflare IP 优选的时候就遇到过,明明网站请求头有 Cloudflare 的信息,页面也调用了 Cloudflare 验证码,但是使用优选IP就是会导致网站无法访问。
现状
反正我自己够用了,继续开发的动力一下子就没那么强烈了。
谁要是有一样的痛点那就自己写代码自己弄去,能发 Pull request 提交新功能更好,反正我也强求不了。我也没啥动力,反正又没人给我钱。
无名无利的,谁愿意费那么多劲。
The post
正在开发中的 DNS-Response-Replacer-JS first appeared on
石樱灯笼博客.