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

使用 cf workers 反向代理 nextdns 或者 adguardHome,配合国内 CDN 让你飞起

  •  
  •   Jesmora · 2022-04-13 16:31:08 +08:00 · 6651 次点击
    这是一个创建于 716 天前的主题,其中的信息可能已经有所发展或是发生改变。
    你是否对 nextdns 及 adguardhome 去广告的能力感叹,但是在国内的网络环境,它们速度真的是一言难尽。今天,我就来分享一个如何使用 cf workers 反向代理,然后再配合优质 CDN ,让你在国内也正常使用这些 dns

    准备工作

    • cloudflare 账号;
    • 你要反代的 dns 服务( nextdns 、adh 等)
    • 一个自己的域名 (可选)

    第一步

    登录到你的 clodflare 账号,然后进入 workes ,创建一个服务,粘贴以下代码。

    // 请求路径。请修改此路径,避免该 worker 所有人都能使用。
    const endpointPath = '/dns-query';
    // 上游 DoH 地址。必需是域名,不能是 IP 。Cloudflare 有限制。
    const upstream = '这里填写要反代的 dns-query';
    
    /**
     * @param {Request} request
     * @param {URL} clientUrl
     */
    async function handleRequestGet(request, clientUrl) {
      const dnsValue = clientUrl.searchParams.get('dns')
    
      if (dnsValue == null) {
        return new Response('missing parameters', { status: 400 });
      }
    
      if (request.headers.get('accept') != 'application/dns-message') {
        return new Response('bad request header', { status: 400 });
      }
    
      const upstreamUrl = new URL(upstream);
      upstreamUrl.searchParams.set('dns', dnsValue);
      const upstreamRequest = new Request(upstreamUrl.toString(), {
        headers: request.headers,
        method: 'GET',
      });
      upstreamRequest.headers.set('host', upstreamUrl.hostname)
      return await fetch(upstreamRequest);
    }
    
    /**
     * @param {Request} request
     * @param {URL} clientUrl
     */
    async function handleRequestPost(request, clientUrl) {
      if (request.headers.get('content-type') != 'application/dns-message') {
        return new Response('bad request header', { status: 400 });
      }
      const upstreamRequest = new Request(upstream, {
        method: 'POST',
        headers: {
          'accept': 'application/dns-message',
          'content-type': 'application/dns-message',
        },
        body: await request.arrayBuffer()
      });
      return await fetch(upstreamRequest);
    }
    
    /**
     * @param {Request} request
     */
    async function handleRequest(request) {
      const clientUrl = new URL(request.url);
      if (clientUrl.pathname != endpointPath) {
        return new Response('Hello World!', { status: 404 });
      }
    
      switch (request.method) {
        case 'GET':
          return handleRequestGet(request, clientUrl)
        case 'POST':
          return handleRequestPost(request, clientUrl)
        default:
          return new Response('method not allowed', { status: 405 });
      }
    }
    
    addEventListener('fetch', event => {
      event.respondWith(handleRequest(event.request));
    });
    

    然后保存即可,现在,你就可以使用你反向代理的 dns-query 了,如果需要自定义域名也可以自行百度。

    这里有个问题,就是 cf 官方的 cdn 国内访问也是很拉,所有,我们可以自定义域名,然后套上第三方 cdn 。这里就不做推荐了,你可以选择又拍云、多吉云等等

    第二步 (可选)

    自定义域名后,选择一个 cdn 服务商,我这里使用的是多 j 云。剩下的配置我就不演示了,就跟网站设置 cdn 一样,做个 cname 解析即可。

    第三步

    测试我们反向代理的效果是否能用

    我这里反向代理的是 nextdns ,后台响应如下:

    要快速检测生效,可使用 cfw 工具配置 tun 模式

    23 条回复    2023-05-26 23:42:38 +08:00
    Jesmora
        1
    Jesmora  
    OP
       2022-04-13 16:53:05 +08:00
    我这里再加个工具网站,关于 iOS 用户想要使用 DoH ,不需要使用第三方工具,iOS 大于 14 的基本支持自定义配置,所以我们可以不借助第三方 app 使用 iOS 的 profile 功能,生成一个 mobileconfig 文件,你就可以随时添加 DoH 或者 DoT 。
    工具链接: https://dns.notjakob.com/tool.html
    Frank777
        2
    Frank777  
       2022-04-13 18:25:35 +08:00
    @Jesmora #1 使用 IOS profile 是不是不能使用魔法上网 app 了?
    0o0O0o0O0o
        3
    0o0O0o0O0o  
       2022-04-13 18:51:48 +08:00 via iPhone
    Cavolo
        4
    Cavolo  
       2022-04-13 19:02:58 +08:00 via iPhone
    @Frank777 魔法工具也能配置 doh
    seakingii
        5
    seakingii  
       2022-04-13 19:30:16 +08:00
    不太明白,你这样做的链路是 : 我的电脑 > 多吉云 CDN > CF WORKER > DNS 服务器吗?

    能不能 : 我的电脑 > 多吉云 CDN > DNS 服务 这样?还少个步骤

    是不是我哪里理解有误
    ik
        6
    ik  
       2022-04-13 19:37:28 +08:00 via iPhone
    @seakingii “但是在国内的网络环境,它们速度真的是一言难尽”
    since2021
        7
    since2021  
       2022-04-13 19:51:10 +08:00
    又认识一个免费资源,多 J 云~
    seakingii
        8
    seakingii  
       2022-04-13 19:51:53 +08:00
    @ik 你理解错误我的疑问

    楼主说: 我的电脑 > DNS 服务慢,中间要再加个 CF ,因为 我的电脑 > CF 也慢,所以 还要加个 多吉云 , 那楼主就是认为
    多吉云 > CF 快 , CF > DNS 快, 所以就算加了 2 个中间层还是快
    我的问题是 多吉云 > DNS 不行吗 ? 就慢了? 一定要在 多吉云和 DNS 中间加个 CF?
    0o0O0o0O0o
        9
    0o0O0o0O0o  
       2022-04-13 19:59:10 +08:00 via iPhone
    @seakingii 一般来说 CDN 不具备代理功能,你没有办法更改公共 DoH 域名的解析,所以你的模型中还需要一台国内服务器和一个域名。CF workers 是免费额度较高的 serverless ,并且可以很好地和域名解析结合到一起,承担了反代的功能。
    since2021
        10
    since2021  
       2022-04-13 20:03:26 +08:00
    直接用百度云函数了好了,小于百万次也免费~
    seakingii
        11
    seakingii  
       2022-04-13 20:03:35 +08:00
    @0o0O0o0O0o

    可能我的理解有误:

    我的理解是 :

    1 访问 多吉云 CDN,
    2 多吉云 那边邦我访问 DNS
    3 多吉云 将 DNS 的响应返回给我

    这几个步骤下来,多吉云 没有起到类似 "反代"的功能吗?

    除非不能"简单"的,中间还需要有应用代码解析请求进行复杂一点的操作
    lxxself
        12
    lxxself  
       2022-04-14 00:23:56 +08:00
    “剩下的配置我就不演示了”,这话让我折腾好一会还是没弄好。多吉云 cdn -> cf worker ->nextdns ,这其中的多吉云 cdn 配置的源地址是 cf worker 的 xxx.xxx.workers.dev 还是说是 cf 后台配置的域名(规则转发到 worker 的域名)?
    Jesmora
        13
    Jesmora  
    OP
       2022-04-14 09:54:10 +08:00
    @Frank777 正常使用
    Jesmora
        14
    Jesmora  
    OP
       2022-04-14 09:58:19 +08:00
    @0o0O0o0O0o 你见过支持这样 https://example.workers.dev/https://family.cloudflare-dns.com/dns-query 的 doh 的吗?
    我自定义域名了还得 https://www.mydomain.com/https://dns.google/dns-query ,那我使用 profile 自定义 mobileconfig 的时候校验不过,思路是好的,但有时候聪明反被聪明误
    Jesmora
        15
    Jesmora  
    OP
       2022-04-14 10:17:42 +08:00
    @seakingii 不是这样的,cf-workers 反向代理第三方 dns 是为了自定义域名使用优质 cdn ,你不能直接 cname 第三方 dns 服务,并且也不支持,自定义域名后的逻辑链路如下: https://store.heytapimage.com/cdo-portal/feedback/202204/14/68688cfdf1c8a527761896df453f4ae6.png
    0o0O0o0O0o
        16
    0o0O0o0O0o  
       2022-04-14 11:11:09 +08:00   ❤️ 2
    @Jesmora #14 你这批评,让我还去搜了下 RFC...没有定义说不能这样啊?代码里稍微处理一下,这样 path 部分编不编码都支持,说到底就是个反代。

    用 curl --doh-url 和 dnslookup 测试均能通过

    curl --doh-url https://exmaple.workers.dev/https://dns.google/dns-query https://www.google.com/robots.txt
    curl --doh-url https://exmaple.workers.dev/https%3A%2F%2Fdns.google%2Fdns-query https://www.google.com/robots.txt
    curl --doh-url https://exmaple.workers.dev/https://cloudflare-dns.com/dns-query https://www.google.com/robots.txt
    curl --doh-url https://exmaple.workers.dev/https%3A%2F%2Fcloudflare-dns.com%2Fdns-query https://www.google.com/robots.txt



    ```
    addEventListener("fetch", event => {
    event.respondWith(handleRequest(event.request))
    })

    async function handleRequest(request) {
    let url = new URL(request.url);
    let upstream = new URL(decodeURIComponent(url.pathname.replace(/^\/+/, '')).replace(/^https:\/+/, 'https://'));

    upstream.search = url.search;

    return fetch(upstream,
    {
    method: request.method,
    body: request.body,
    headers: request.headers,
    keepalive: request.keepalive,
    }
    );
    }
    ```
    Rilimu
        17
    Rilimu  
       2022-04-25 19:15:42 +08:00
    我说这代码怎么眼熟。

    复制粘贴别人的代码不署名。

    给后人指条路。代码源复制自 github 上的 cfdohpw 项目。
    baodl
        18
    baodl  
       2022-04-27 15:08:32 +08:00
    @Jesmora 能不能给写下 第二步 (可选)
    自定义域名后,选择一个 cdn 服务商,我这里使用的是多 j 云。剩下的配置我就不演示了,就跟网站设置 cdn 一样,做个 cname 解析即可。

    卡在这第二步不会弄了。 多吉云创建的加速 CDN 只能是备案的域名,国外的域名如 xxx.xxx.workers.dev 不支持,然后用了一个备案的域名,生成了一个 cdn 地址,如 xxx.s2-web.dogedns.com. 想加 CNAME 了,但是在 CF 那里有要求,此域名的 NS 必须托管在 CF ,否则不能 CNAME 指向这个加速 CDN ,但是托管了,备案就掉了。到这块不会弄了,能不能给指导一下啊?
    Jesmora
        19
    Jesmora  
    OP
       2022-04-28 10:48:55 +08:00
    @baodl 用你备案域名在多吉那里添加一个服务,把 xxx.xxx.workers.dev 作为回源地址,然后多吉生成的地址你在你域名解析那里添加 cname 记录就行了,没有必要去 cf 那里解析
    baodl
        20
    baodl  
       2022-04-30 16:15:48 +08:00
    谢谢,已经照你说的弄好了。但是最后效果不太好,在 workers 上的 DOH 解析,用多吉的 CDN 加速反而还慢了。不如直接访问 workers.dev 了。
    c398425861
        21
    c398425861  
       2022-11-11 14:00:52 +08:00
    反代不支持 edns ?
    a9k1n9
        22
    a9k1n9  
       2022-11-27 19:47:19 +08:00
    “missing parameters”属于正常吗?
    eudemonwind
        23
    eudemonwind  
       307 天前
    @0o0O0o0O0o 老哥能不能给个修改好后的完整代码? 比较看好你这个方案哈
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2885 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 40ms · UTC 11:26 · PVG 19:26 · LAX 04:26 · JFK 07:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.