V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
crzidea
V2EX  ›  DNS

分享一个自己用 Cloudflare Workers 实现的 0 运维成本 DNS 方案

  •  
  •   crzidea · 4 天前 · 2450 次点击

    项目地址: https://github.com/crzidea/doh

    我知道大家很多人的分流规则是这样的:

    1. 国内域名转发到 DHCP 获取的 DNS
    2. 国外域名转发到 1.1.1.1

    但是肯定会有漏网之鱼不在已知的域名列表里,该怎么办呢?我猜有能力的各位是这么配置的:

    1. 支持 EDNS Client Subnet 的环境中,比如在 dnsmasq 中配置,再将请求通过 DoH 转发到 8.8.8.8 。
    2. 不支持 EDNS Client Subnet 的环境中,比如 clash ,通过 fallback 配置根据默认的解析结果,如果不是大陆的 IP 再从 1.1.1.1 解析一遍。

    但是上述方法都有一些小瑕疵:

    1. EDNS Client Subnet 虽然可以准确的解析出来离我们墙内最近的结果,但是当解析结果不在墙内时,有可能会产生相反的效果。比如 VPN 出口在美国,我们要访问的 CDN 虽然在国内没有节点,但是在日本有节点,这时我们的流量会路由到美国,再路由到日本,回程时也一样再绕回来。
    2. clash fallback 的方法目前已经不可靠了。我自己遇到过 Wikipedia 的 DNS 被污染后的解析结果是国内 IP 的结果。

    在这个背景下,本着能不花钱就不花钱的原则,我开发了这个项目。用户解析 DNS 的时候,会同时向 Google DNS 查询两次:

    1. 第 1 个的 Client Subnet 参数带着本地 ISP 的 IP
    2. 第 2 个的 Client Subnet 参数带着 VPN 的 IP

    如果第 1 个的解析结果对应的地区信息与我们想要的地区信息一致,就采纳第 1 次的解析结果,否则的话采用第 2 个。

    这样做还会有以下好处:

    1. Github Actions 、Cloudflare Workers 、Cloudflare D1 全都是免费的,甚至 MaxMind 的最基础的数据库也是免费的。
    2. 不支持 EDNS Client Subnet 的客户端,比如 clash ,可以把查询参数放到 URL 参数中,也可以使用。
    3. 利用 Cloudflare 的网络资源和 Cloudflare 许诺的未来 D1 支持跨地区同步,理论上可以是分布式的。但是我没交钱,所以网络延时大概 200 ms 左右,有钱的大哥可以开个订阅试试。另外建议 D1 位置选择欧洲西部,别问我怎么知道的。
    4. GeoIP 数据库的更新过程是全自动的,自己完全不用管,不用担心长时间忘记更新数据库。感谢 Github Actions 和 MaxMind 。
    5. 甚至直接支持了 IPv6 和 HTTP/3 。

    附带博客链接: https://crzidea.com/#/article/introducing-crzidea-doh

    第 1 条附言  ·  4 天前
    大家不用纠结白名单和黑名单的问题哈,不管是白名单还是黑名单,已知的名单仍然还是用起来速度更快,关键是不在名单里的域名,有可能存在国内( ISP )、日本( CDN )、美国( VPN )三种情况,这类的未知域名,不管使用之前的哪个单个 DNS 都覆盖不全,这个时候就需要这个 DoH 来补位了。具体一点说,把这个设置为 default 就可以,cn 和 !cn 的仍然使用你们现在的规则就可以。
    还有就是很多人提到的 mosdns 、smartdns 这类的需要在 Linux 环境中运行的服务,但是移动设备是不行的,移动设备上只能填写一个 URL ,如果连回家里或者自己的服务器,移动设备在外面的时候和家里、服务器的源 IP 都是不一样的,家里宽带是联动,手机是移动的情况下,解析结果不对会造成更糟糕的跨网访问问题。而且在自己服务器上运行的话是有运维成本的,在家里运行也需要公网 IP 。
    29 条回复    2024-09-18 09:49:25 +08:00
    lightionight
        1
    lightionight  
       4 天前
    想法比较有创意👍, 还没用过 CF workers, 有空试试
    yxmyxmyyy
        2
    yxmyxmyyy  
       4 天前 via Android   ❤️ 1
    看起来好麻烦,我用的最简单的分流就是默认走节点解析,然后根据国内白名单域名匹配走国内 dns 解析,这样又快又简单,走节点解析也会就近解析节点附近的 cdn ,而且这个方案也完全杜绝了 dns 泄露,毕竟只有国内域名用国内 dns 解析,这个方案用了一年多没啥问题
    terrancesiu
        3
    terrancesiu  
       4 天前
    这个很舒服啊,该有的都有。
    crzidea
        4
    crzidea  
    OP
       4 天前
    另外,感兴趣的朋友们,求个 Github Star~~~
    (真 · 图穷见匕)
    hello158
        5
    hello158  
       4 天前
    这个图是用啥画的
    crzidea
        6
    crzidea  
    OP
       4 天前
    @hello158 plantuml 、C4
    ztmzzz
        7
    ztmzzz  
       4 天前 via iPhone
    客户端带上自己的 ip 访问 cf 的 worker ,问题是访问 cf 很慢啊,还时不时断联。
    iorilu
        8
    iorilu  
       4 天前
    不错, 有空试试

    不过建议 OP 有空弄个中文的 readme

    毕竟这东西主要也是给国内人用的把
    crzidea
        9
    crzidea  
    OP
       4 天前
    @ztmzzz 考虑到了这个情况,clash 和 https-dns-proxy 都是可以通过 socks5 代理的,代理的时候把参数填全了,也是可以正常访问的。不过我测试下来直连反而延时更低,http/2 、http/3 、IPv4 、IPv6 可以互相保证访问的可靠性。
    crzidea
        10
    crzidea  
    OP
       4 天前
    @iorilu 伪装起来,保护好自己[手动狗头]
    Phant0m
        11
    Phant0m  
       4 天前
    dns 查询延迟 200ms 有点大啊
    SenLief
        12
    SenLief  
       4 天前
    除了 geosite cn 外全部由代理解析。
    crzidea
        13
    crzidea  
    OP
       4 天前
    @Phant0m 可以实际测试一下直接在美国 VPS 上带着中国 IP 的 EDNS Client Subnet 参数从 Google DNS 查询国内域名,比如 www.aliyun.com 的耗时,可能你会对 200 ms 这个数字有一个新的认识~
    crzidea
        14
    crzidea  
    OP
       4 天前
    @SenLief 这个是除了已知国内和国外之外的另外的一个默认配置哈,不是说让全部转发到这一个服务上。两个黑白名单的就近解析会更快,最后一部分不确定的域名在用这个服务解析,会更准确。
    ciki
        15
    ciki  
       4 天前
    都是 clash 懒人规则梭哈
    mjikop1231
        16
    mjikop1231  
       4 天前
    我还用国内 dns 解析的主要原因还是 akadns ,已经不管什么泄露不泄露了
    为什么还有 CDN 不想用 EDNS client subnet 啊
    journalist
        17
    journalist  
       4 天前 via iPhone
    在我的使用过程中域名规则占绝大部分,dns 有目标服务器处理。优化 dns 的目的主要是优化直连情况下的速度,去污染到不是主要,国内白名单即可。针对不同 CDN ,有的日本快( akamai ),有的美国快( Edgecast 、CDN77 、Zenlayer 等),像 fastly 这种则可以通过计算得出想要的 IP https://github.com/IrineSistiana/mosdns/discussions/511 其他的一些 CDN 是否能通过类似的方法来提速现在还不清楚,这种有规律的完全可以本地处理只要第一次查,可以理解为高级功能的 hosts 文件。Cloudflare 和部分 Akamai 最简单,因为可以任意换。怎样高效的记录和修改是我比较关心的,目前我结合了 mosdns+coredns ,但是还很不成熟。
    jqtmviyu
        18
    jqtmviyu  
       4 天前
    我是 smartdns 使用 ecs, 作为 clash 的上游, 国内白名单走运营商和腾讯阿里, 默认走国外 dns

    clash 使用 redir-host, 然后开启 sni 嗅探功能, 似乎能够解决你提到的这两个问题.
    crzidea
        19
    crzidea  
    OP
       4 天前
    @jqtmviyu 根据 SNI 判断仍然需要依赖规则里有这个域名,以及仍然不能避免不知道该用日本的流量要先绕道美国的问题。
    crzidea
        20
    crzidea  
    OP
       4 天前
    @yxmyxmyyy @SenLief @ciki @journalist 大家不用纠结白名单和黑名单的问题哈,不管是白名单还是黑名单,已知的名单仍然还是用起来速度更快,关键是不在名单里的域名,有可能存在国内( ISP )、日本( CDN )、美国( VPN )三种情况,这类的未知域名,不管使用之前的哪个单个 DNS 都覆盖不全,这个时候就需要这个 DoH 来补位了。具体一点说,把这个设置为 default 就可以,cn 和 !cn 的仍然使用你们现在的规则就可以。
    还有就是很多人提到的 mosdns 、smartdns 这类的需要在 Linux 环境中运行的服务,但是移动设备是不行的,移动设备上只能填写一个 URL ,如果连回家里或者自己的服务器,移动设备在外面的时候和家里、服务器的源 IP 都是不一样的,家里宽带是联动,手机是移动的情况下,解析结果不对会造成更糟糕的跨网访问问题。而且在自己服务器上运行的话是有运维成本的,在家里运行也需要公网 IP 。
    showgood163
        21
    showgood163  
       4 天前
    感谢分享。之后研究看看。
    alamak76
        22
    alamak76  
       4 天前
    有没有用 ip2location lite 数据库?
    crzidea
        23
    crzidea  
    OP
       3 天前
    @alamak76 用哪个库不重要吧。我试过用不同服务提供的 GeoIP 查询接口,但是测试下来还是 D1 查询延时更低,D1 里的数据库从哪儿拉下来的也不太重要,只有有而且能更新就可以了。反而是不要太大,否则的话更新起来会比较麻烦。

    这里有不同的实现。
    https://github.com/crzidea/doh/blob/93beafaa534a08aa65a8af0444f4e10da87a12e1/workers.js#L245
    jqtmviyu
        24
    jqtmviyu  
       2 天前
    @crzidea #19 " Meta 内置了 Sniffer 域名嗅器,通过读取握手包内的域名字段,将 IP 还原成域名,有效解决 Mapping 机制的短板。"

    按我的理解, 就算是使用 redir-host, 发给服务器的也是 域名, 应该没有这种问题了呀.
    LuvF
        25
    LuvF  
       2 天前 via Android
    cloudflare 的 api key 权限明确一下吧
    crzidea
        26
    crzidea  
    OP
       2 天前 via Android
    @jqtmviyu 并不能。嗅探只在特定支持的客户端解决了映射问题,比如多个域名共用一个 IP ,解决的是客户端侧的已知规则内的路由问题,对于不在已知规则里的域名是没有任何作用的,而且并不会和服务端有什么关系,因为需要服务端协议支持。除了没解决问题以外,嗅探只支持没有启用 HTTPS 协议,而且域名一旦启用 ECH 连嗅探都不能用了,而且还必须得使用特定客户端。
    crzidea
        27
    crzidea  
    OP
       2 天前 via Android
    @LuvF 我有点忘了需要给 token 哪些权限了,如果试过的话帮忙发一下权限列表,谢谢啦~
    LuvF
        28
    LuvF  
       2 天前   ❤️ 1
    @crzidea #27 刚刚测试了一下 给这些权限应该就行
    angeltop
        29
    angeltop  
       4 小时 28 分钟前
    感谢分享,有空试试
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5792 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 06:18 · PVG 14:18 · LAX 23:18 · JFK 02:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.