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

2022-04-13 16:31:08 +08:00
 Jesmora
你是否对 nextdns 及 adguardhome 去广告的能力感叹,但是在国内的网络环境,它们速度真的是一言难尽。今天,我就来分享一个如何使用 cf workers 反向代理,然后再配合优质 CDN ,让你在国内也正常使用这些 dns

准备工作

第一步

登录到你的 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 模式

7505 次点击
所在节点    DNS
23 条回复
Jesmora
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
2022-04-13 18:25:35 +08:00
@Jesmora #1 使用 IOS profile 是不是不能使用魔法上网 app 了?
0o0O0o0O0o
2022-04-13 18:51:48 +08:00
Cavolo
2022-04-13 19:02:58 +08:00
@Frank777 魔法工具也能配置 doh
seakingii
2022-04-13 19:30:16 +08:00
不太明白,你这样做的链路是 : 我的电脑 > 多吉云 CDN > CF WORKER > DNS 服务器吗?

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

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

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

可能我的理解有误:

我的理解是 :

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

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

除非不能"简单"的,中间还需要有应用代码解析请求进行复杂一点的操作
lxxself
2022-04-14 00:23:56 +08:00
“剩下的配置我就不演示了”,这话让我折腾好一会还是没弄好。多吉云 cdn -> cf worker ->nextdns ,这其中的多吉云 cdn 配置的源地址是 cf worker 的 xxx.xxx.workers.dev 还是说是 cf 后台配置的域名(规则转发到 worker 的域名)?
Jesmora
2022-04-14 09:54:10 +08:00
@Frank777 正常使用
Jesmora
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
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
2022-04-14 11:11:09 +08:00
@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
2022-04-25 19:15:42 +08:00
我说这代码怎么眼熟。

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

给后人指条路。代码源复制自 github 上的 cfdohpw 项目。
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
2022-04-28 10:48:55 +08:00
@baodl 用你备案域名在多吉那里添加一个服务,把 xxx.xxx.workers.dev 作为回源地址,然后多吉生成的地址你在你域名解析那里添加 cname 记录就行了,没有必要去 cf 那里解析
baodl
2022-04-30 16:15:48 +08:00
谢谢,已经照你说的弄好了。但是最后效果不太好,在 workers 上的 DOH 解析,用多吉的 CDN 加速反而还慢了。不如直接访问 workers.dev 了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/846768

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX