萝卜小站

要做所有萝卜中最胡的一条

0%

通过Cloudflare Worker部署Clash订阅文件

我们可以在 Cloudflare 上面通过部署 Worker ,来模拟一个Clash订阅服务器。支持模拟流量限制和时间限制。

前期准备

首先要自己搭建好节点服务器,具体教程可以参考:Trojan搭建具体流程 或者 CentOS下基于X-UI搭建Vless + Reality协议

搭建成功后,并且节点使用无问题,再继续本教程。

在 Cloudflare 上需要配置好域名解析

本教程默认你已经熟悉Clash的订阅文件规则,且熟悉javascript语言。

不熟悉的可以参考 Clash系列客户端订阅地址配置教程 ,完全不会的建议别折腾本教程。

无论是搭建 Trojan 节点还是搭建 Vless 节点亦或是其他节点,对于Clash来说不过是 proxy 不同而已,在部署的时候按需更改即可。

Worker 部署

在Cloudflare首页,点击左侧 Workers 和 Pages,点击创建按钮,点击 创建Worker 按钮。

标题输入 clash 即可,内容不用动,然后直接点击右下角的 部署 ,稍等几秒进行全球部署。

成功后点击右上角的 编辑代码 按钮,进入编辑界面,先清空左侧代码,然后粘贴如下代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

const vlessConfig = `
# 白名单模式,国内直连命中规则走直连,其他全部走代理
# 规则集来自https://github.com/Loyalsoldier/clash-rules
# 规则文件使用https://ghp.ci。加速访问
allow-lan: true
mode: Rule
log-level: info
proxies:
- {name: 美国24, server: 172.245.156.24, port: 27818, reality-opts: {public-key: g1f1wLjim5gOVGnI5LGUV0dL4iFXPoiepOPZfSxJe14}, client-fingerprint: chrome, type: vless, uuid: 391fd05c-00c4-4931-b5cd-d21bf9ff1be9, tls: true, tfo: false, flow: xtls-rprx-vision, skip-cert-verify: false, servername: www.faketeams.com, network: tcp}
proxy-groups:
- name: 外网
type: select
proxies:
- 美国24
- DIRECT
- name: 直连
type: select
proxies:
- DIRECT
- 美国24
- name: 广告
type: select
proxies:
- REJECT
- DIRECT
rule-providers:
reject:
type: http
behavior: domain
url: "https://ghp.ci/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/reject.txt"
path: ./ruleset/reject.yaml
interval: 86400

direct:
type: http
behavior: domain
url: "https://ghp.ci/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/direct.txt"
path: ./ruleset/direct.yaml
interval: 86400

icloud:
type: http
behavior: domain
url: "https://ghp.ci/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/icloud.txt"
path: ./ruleset/icloud.yaml
interval: 86400

apple:
type: http
behavior: domain
url: "https://ghp.ci/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/apple.txt"
path: ./ruleset/apple.yaml
interval: 86400

private:
type: http
behavior: domain
url: "https://ghp.ci/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/private.txt"
path: ./ruleset/private.yaml
interval: 86400

applications:
type: http
behavior: classical
url: "https://ghp.ci/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/applications.txt"
path: ./ruleset/applications.yaml
interval: 86400

lancidr:
type: http
behavior: ipcidr
url: "https://ghp.ci/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/lancidr.txt"
path: ./ruleset/lancidr.yaml
interval: 86400

cncidr:
type: http
behavior: ipcidr
url: "https://ghp.ci/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/cncidr.txt"
path: ./ruleset/cncidr.yaml
interval: 86400
rules:
- RULE-SET,reject,广告
- RULE-SET,direct,直连
- RULE-SET,icloud,直连
- RULE-SET,apple,直连
- RULE-SET,private,直连
- RULE-SET,applications,直连
- RULE-SET,lancidr,直连
- RULE-SET,cncidr,直连
- GEOIP,LAN,直连
- GEOIP,CN,直连
- MATCH,外网
`;




export default {

async fetch(request, env, ctx) {
const url = new URL(request.url);
const UA = request.headers.get('User-Agent') || 'null';
const userAgent = UA.toLowerCase();
switch (url.pathname.toLowerCase()) {
case '/':
return new Response('<!DOCTYPE html><html><body><h1>别尝试访问这里,这里没有你想要的。</h1></body></html>', {
headers: { "content-type": "text/html;charset=UTF-8" }
});
case `/${env.UUID}`:
// if (userAgent && userAgent.includes('mozilla')){
// return new Response(`请将地址填入客户端中使用,不会用来问我。\nhttps://diaoqi.767766.xyz/${env.UUID}`);
// }
const today = new Date();
const end = new Date(today.getFullYear(), 11, 31)
const expire = Math.floor(end.getTime() / 1000) // 今年最后一天时间戳(到秒)
let FileName = 'Diaoqi Cloud';

const haveDays = (end.getTime() - today.getTime()) / (1000 * 60 * 60 * 24) // 还剩多少天
const UD = Math.floor((365 - haveDays) * 1073741824 / 2); // 一天算1G
let total = 400 * 1073741824; // GB

return new Response(`${vlessConfig}`, {
status: 200,
headers: {
"Content-Disposition": `attachment; filename=${FileName}`,
"Content-Type": "text/plain;charset=utf-8",
"Profile-Update-Interval": "6",
"Content-Encoding": "gzip",
"Subscription-Userinfo": `upload=${UD}; download=${UD}; total=${total}; expire=${expire}`,
}
});
default:
return new Response('Not found', { status: 404 });
}
},
};

脚本先定义了一个叫 vlessConfig 的长字符串,后面js代码先不看,我们先看这个长字符串。

这个字符串就是我们的 Worker服务器 将要返回给客户端的订阅内容。

这里需要注意 proxies 字段,一定要替换成你自己的节点信息,且其中的 name 字段要和 proxy-groups 中的名字保持一致。更改好后点击右上角 部署 按钮,稍等几秒后,点击左上角返回 Worker主页。

代码讲解

本小节就讲javascript代码了,不感兴趣的完全可以跳过本小节,继续阅读 配置Worker 小节即可,不影响部署。

在定义了长字符串 vlessConfig 后,我们使用 fetch 函数来处理客户端发起的请求。只有在请求URL中含有 UUID 时我们才返回订阅信息。如果请求者不是Clash客户端而是浏览器之类的话,我们也可以拦截返回提示信息,当然也可以不拦截,直接返回明文订阅信息,此处注释掉的内容就是拦截浏览器请求,可视情况打开注释。

接下来的代码就是根据本年度剩余天数来模拟剩余流量了,定义了总流量为400GB,到期日为本年最后一天。当然这些代码只是模拟了功能,并没有真正实现,说白了就是看一乐。如果想实现到期后不提供订阅其实也不难,但本文不做讲解。

最后把所有的信息通过请求头中的 Content-Disposition 和 Subscription-Userinfo 字段返回给客户端。

代码基本就这些了,记得保存,回到 Worker主页 。

配置 Worker

在 Worker主页 点击上面的 设置 Tab页,在 域和路由 右边点击 添加 → 自定义域 ,输入一个二级域名即可,Cloudflare会自动识别并添加好DNS解析。

点击 变量和机密 右侧的 添加 按钮,类型为 Text 变量名称输入 UUID ,值输入 tg 。

最后点击部署即可。

等待一分钟后,我们可以浏览器访问 https://域名/tg ,来下载我们的订阅文件。

若下载成功,则节点部署完毕,我们导入上面的链接到客户端软件,进行节点的订阅。

各个客户端软件的订阅流程不同,请自行按照各软件的方式配置订阅链接。