warp-masque-actions README

The project's README from github.com/byJoey/warp-masque-actions. As one markdown file: README.md.

WARP MASQUE 配置生成器

一键生成 Cloudflare WARP 的 mihomo 配置,57 个节点,跑在 GitHub Actions 上。 不用自己装环境,不用服务器。

仓库里有两条流水线:

另外 worker/ 目录是套娃那条的 Worker 版本,部署到 Cloudflare 上自己每 4 小时 更新,带个状态页。见跑在 Worker 上。

怎么用

1. Fork 这个仓库

点右上角 Fork。

2. 打开 Actions 页面

Fork 过来的仓库默认不开 Actions,会看到一个提示,点 I understand my workflows, go ahead and enable them 就行。

3. 跑一次

左边选 生成 WARP MASQUE 配置,右边点 Run workflow,绿色按钮再点一次。 等一分钟左右。

4. 下载

跑完点进这次运行的页面,最下面 Artifacts 里有个 warp-masque-config, 下载解压。

5. 导入客户端

解压出来三个文件:

必须用 mihomo Alpha 内核

masque 只有 mihomo 的 Alpha 分支才有,稳定版导进去会直接报错说不认识这个类型。 所以客户端不光要是 mihomo 内核,还得能切到 Alpha。

Windows / macOS / Linux

Clash Verge Rev —— 装完打开 设置 → Clash 内核,把内核换成 Alpha,等它下载完自动重启。

切内核和升级 Verge 本身是两回事。把程序更新到最新版不会让内核变成 Alpha, 得手动在这个页面切。没切就导入会报 unsupport proxy type: masque。

Android

ClashMetaForAndroid —— 认准 Prerelease-alpha 那个 tag,正式版不行。

iOS

ClashMi —— 内置 mihomo 内核, 把 warp-masque.yaml 直接导进去就行。同一个 App 也有 macOS / Android / Windows / Linux 版本。

Shadowrocket 也能用。它不吃 yaml,但 artifact 里已经带了 warp-masque-shadowrocket.txt,一行一个 masque:// 链接, 挑一条复制进 Shadowrocket 就行。

跨平台,也可以看看

FlClash —— 界面比较新,Windows / macOS / Linux / Android 都有。内核版本在设置里换。

不用图形界面

直接下 mihomo Alpha 二进制,mihomo -d 配置目录 跑起来就行。

这些用不了

Surge、Quantumult X、Karing 不是 mihomo 内核,也不认 masque,导进去没用。

关于节点

57 个节点是同一个 WARP 账号的不同接入地址,出口 IP 是一样的。 多节点是为了某个地址被墙时能自动换一个,不是多国家落地。 想选国家得用 WARP+ 或 ZeroTrust,这个仓库不支持。

里面有 28 个 IPv6 节点,你没 IPv6 的话它们会连不上,但客户端会自动跳过, 不影响用。

几个提醒

配置里的 private-key 相当于账号密码,别往外发。artifact 默认存 7 天, 公开仓库的 artifact 谁都能下载,介意就把 fork 出来的仓库设成私有。

想换一套密钥就重新跑一次 workflow,每次都是全新账号。

别写成定时任务高频跑,WARP 会风控封号。

常见问题

导入报「unsupport proxy type: masque」

完整报错长这样:

订阅配置校验失败,请检查订阅配置文件,变更已撤销
level=error msg="proxy 0: unsupport proxy type: masque"

内核还是稳定版,没切到 Alpha。 这是目前最多人踩的一个。

Clash Verge Rev 的切法:打开「设置 → Clash 内核」,选 Alpha,点切换, 等它下载完会自动重启内核。然后再导入配置。

注意切内核和更新程序本身是两回事,把 Verge 升到最新版并不会让内核变成 Alpha。

Actions 页面有个黄色警告,要紧吗

如果你看到的是这个:

Node.js 20 is deprecated. The following actions target Node.js 20 ...

不影响结果,配置照样能生成。这个仓库已经升级到 node24 的 action 版本, 重新 Fork 或者同步一下上游就没有了。

Fork 早了的话,把 .github/workflows/warp-masque.yml 里这两行改一下:

uses: actions/checkout@v6
uses: actions/upload-artifact@v6

为什么节点延迟不一样,但测速结果都差不多

57 个节点是同一个 WARP 账号的不同接入地址,出口 IP 是同一个。 延迟差异来自你到接入点的网络路径,真正落地的还是那台 Cloudflare 机器。

所以挑延迟最低的用就行,不用一个个试速度。

artifact 过期了怎么办

重新跑一次 workflow,会生成一套全新的密钥和配置。artifact 默认存 7 天, 想留久一点在 Run workflow 的时候把保留天数改大。

iOS 怎么用

用 ClashMi,它内置 mihomo 内核, warp-masque.yaml 直接导入就行,和桌面端一样。

Shadowrocket 也支持 masque。它不认 yaml,但 artifact 里的 warp-masque-shadowrocket.txt 就是现成的 masque:// 链接, 一行一个,复制一条导进去即可。

Surge、Quantumult X、Karing 不行。

能选国家吗

不能。免费 WARP 账号的出口由 Cloudflare 任播决定,你在哪就近落哪。 要指定落地得用 WARP+ 或者 ZeroTrust,这个仓库不支持。

跑 workflow 报 login failed

Failed to connect tunnel: login failed!

账号被 Cloudflare 风控了,通常是短时间内建连太频繁导致的。 重新跑一次 workflow 拿新账号就行,另外别把 workflow 改成定时高频跑。

想改配置

scripts/gen_masque.py 顶部三个常量控制节点池:

V4    = [...]   # IPv4 接入地址
V6    = [...]   # IPv6 接入地址
PORTS = (...)   # 端口

分流规则用的是 ACL4SSR,改 RULESETS 那个列表。


套娃:Opera VPN 叠在 WARP 上

纯 WARP 的出口是 Cloudflare 自己的 IP,任播决定落地,选不了国家。 想换出口就得在后面再接一跳。

Opera 浏览器自带的免费 VPN 正好能干这个:底层是 SurfEasy 的标准 HTTPS 代理, 匿名注册、不限流量、连账号都不用。

本机 -> MASQUE 接入点 -> Opera 落地 -> 目标

为什么要套,不直接用 Opera

单用 Opera,你的机器直接连 77.111.x.x,这个段一查就知道是什么。 套上 MASQUE 之后本机只跟 162.159.198.x 这类 Cloudflare 地址通信, Opera 的地址整个封在 QUIC 隧道里。抓包对比过,直连能看到 Opera 服务器, 套娃之后完全看不到。

全组合

57 个 MASQUE 接入点和每个 Opera 落地都配一遍。落地通常 9 到 11 个, 最终 400 上下的节点。

这么做是为了任一环失效都还有路走:某个接入点被墙了换个端口或换个段, 某个落地挂了同地区还有别的。节点名直接写明链路,欧洲[email protected] 就是欧洲第 1 个落地经 162.159.198.1:443 接入。

组合太多没法平铺着选,按地区收成了 亚洲线路、欧洲线路、美洲线路 三个 url-test 组,各自在本地区所有组合里挑最快的。都开了 lazy, 不会一进去就把四百多条全测一遍。

怎么跑

Actions 里选 Opera over MASQUE(套娃),点 Run workflow。

跑完配置有两个地方:仓库里的 configs/opera-masque.yaml(流水线自动提交回来), 或者运行页面下面的 Artifacts。只想下载不想提交的话,跑之前把 commit 勾去掉。

Opera 凭据会过期

匿名注册的凭据会失效。opera-proxy 自己默认每 4 小时刷一次, 但 API 不返回真实过期时间,给不了准数。连不上就重跑一次换新的。

落地只有三个大区

Opera VPN 只提供亚洲、欧洲、美洲,没有国家级选项。实测落地分别是 新加坡、阿姆斯特丹、美东。

这条流水线也要 Alpha 内核

dialer-proxy 和 masque 一样只有 Alpha 分支支持。 Shadowrocket、Stash 不认 dialer-proxy,用不了套娃配置—— 它们可以用上面纯 WARP 那份。

改配置

scripts/gen_opera_masque.py。接入点清单和纯 WARP 那份是同一批 (V4 / V6 / PORTS),REGIONS 控制取哪些 Opera 大区。


跑在 Worker 上

Actions 那条要手动点一下才跑。如果想要它自己更新、随时有个 URL 能拿到最新配置, 用 worker/ 这份。

一份聚合订阅,导进去有两类线路可切:

套娃线路超时或某个落地挂了,切 WARP直连 顶上。这两类共用同一批 MASQUE 接入点,直连组本来就在配置里(做 dialer-proxy 的目标),顺手暴露出来而已。

不用定时任务。Opera 凭据 4 小时到期,Worker 在订阅被访问时才检查: 没过期直接给缓存,过期了才重新注册。没人用就不动,不浪费。

WARP 的注册信息存 KV 里复用,不会每次都注册新设备。

密码和订阅路径都在界面上设,所以部署只需要绑一个 KV, 不用配环境变量,也不用加 cron。

部署方式一:网页(不用装任何东西)

全程在 Cloudflare 后台点,四步。

1. 建 KV

Cloudflare 后台 → 左边 存储和数据库 → KV → 创建实例。 名字随便填,比如 opera-masque。

找不到入口的话,Workers 和 Pages 里也能进 KV。菜单名各语言版本略有差异, 认准 "KV" 这两个字母。

2. 建 Worker 并贴代码

左边 Compute (Workers) → 创建 → 从 Hello World! 开始 → 起个名 → 部署。

先部署一个空壳,然后点右上角 编辑代码,把 worker/dist/worker.js 整个文件的内容复制进去, 覆盖掉原来的 Hello World。这是打包好的单文件,全选粘贴就行。

粘完点 部署。

3. 绑 KV

回到 Worker 页面 → 设置 → 绑定 → 添加 → 选 KV 命名空间。

点 部署。

4. 打开设密码

访问 https://你的worker名.你的子域.workers.dev, 第一次打开会让你设管理密码,设完直接进管理页。

订阅地址、改路径、改密码都在这个页面上。

第一次点订阅可能要等十几秒,它在现注册 WARP 和 Opera。

没绑 KV 就打开的话,页面会告诉你怎么绑,不会报一堆栈。

部署方式二:命令行

cd worker
npm install
npx wrangler login

# 建 KV,把输出的 id 填进 wrangler.toml
npx wrangler kv namespace create KV

npx wrangler deploy

部署完访问 https://你的worker.workers.dev/ 设密码。 订阅路径也在界面上改,不用动配置文件。

改了代码想重新打包

网页部署用的 dist/worker.js 是从 src/ 打包出来的,改完源码跑一下:

npm run build

访问控制怎么做的

状态页和所有 API 都要密码。客户端拉订阅时带不了 cookie,所以订阅链接里 挂了个签名 token——状态页上显示的那条完整链接直接复制走就行。

路由

路径 说明
/ 首次是设密码页,之后是登录/管理页
/login /logout 登录、退出
你设的订阅路径 默认 /sub,要 ?token=
/api/setup POST,首次设密码
/api/password POST,改密码
/api/sub-path POST,改订阅路径
/api/refresh POST,重新拿 Opera 凭据
/api/reset-warp POST,重注册 WARP 设备

订阅响应带了 profile-update-interval: 4,支持这个头的客户端会自己每 4 小时拉一次, 正好卡在凭据到期点上。

更新是怎么触发的

没有 cron。订阅每次被访问时,Worker 看一眼 expiresAt:

多个客户端同时拉订阅时会加锁,只有一个真去注册,其他的先用旧配置顶着, 免得并发注册一堆账号触发风控。

4 小时这个数来自 opera-proxy 自己的 -refresh 4h 默认值。 SurfEasy 的 API 不返回真实过期时间,所以按这个走,另外留了 10 分钟余量。

Worker 常见问题

打开显示 KV Not Bound — 第 3 步没做,或者绑定的变量名不是 KV。 必须是这两个字母大写。

忘了密码 — 没有找回。去 KV 里把 auth:cred 这条删掉, 刷新页面就回到设密码那步。别的数据不受影响。

订阅链接打开是 404 — token 过期了(7 天),回状态页重新复制一条。 改过密码的话所有旧链接都会失效,这是故意的。

节点全都连不上 — 先点刷新 Opera 凭据。还不行再点重注册 WARP 设备。

导入客户端报错说不认识 masque — 内核不是 mihomo Alpha。见下面那节。

客户端不认 dialer-proxy — Shadowrocket、Stash 这类只支持 masque 不支持链式出站,导进去只有 WARP直连 那组能用,套娃线路会报错。

Proton 落地(可选)

Opera 只有三个大区,想要更多国家可以再挂一层 Proton。免费版 10 个国家: 加拿大、瑞士、日本、墨西哥、荷兰、挪威、波兰、罗马尼亚、新加坡、美国。

链路和 Opera 那条一样:本机 → MASQUE → Proton WireGuard → 目标。

为什么要多绕一圈流水线

Proton 必须账号登录,走的是 SRP 协议。这套在 Worker 里能算对(我验过 A 和 M1 跟官方库逐字节一致),但提交时会被 Proton 的风控拦掉,非官方客户端指纹过不去。

所以让 GitHub Actions 去登录、拿证书,再把结果推给 Worker。 Worker 完全不碰 Proton 账号。

配置步骤

  1. 注册一个 Proton 账号(免费版就行)
  2. 仓库 Settings → Secrets → 加 PROTON_USER(邮箱)和 PROTON_PASS(密码)
  3. Worker 管理页的「Proton 落地」区块,点生成拿到推送地址
  4. 把那个地址加成第三个 secret:WORKER_PUSH_URL
  5. 跑一次 取 Proton 凭据 流水线

之后每 3 天自动续,不用再管。

关于证书有效期

Proton 的证书最长 7 天,Duration 写再长也封顶(实测 43200 min、525600 min 返回的都是 7 天)。所以流水线每 3 天跑一次,留足余量。

推送地址的安全性

令牌在地址里,只能写 Proton 凭据,动不了管理页也拿不到订阅。 泄露了在管理页点「换一个」,旧地址立刻失效。

不配这部分也不影响,其他线路照常工作。

Windscribe 落地(可选)

Windscribe 的浏览器扩展用的是标准 HTTPS 代理,和 Opera 同一个形态, 所以能直接写成静态节点挂在 MASQUE 后面。

注册不需要邮箱,POST /Users 给个随机用户名密码就返回 session。 免费额度每月 2GB(官网说的 10GB 要验证邮箱,匿名号拿不到)。

为什么开户要走流水线

它的认证只有一行 md5(固定secret + 时间戳),本来在 Worker 里就能跑完。 但开户和出口 IP 强相关:一个 IP 开过号之后再开,拿到的是 status=2 的降额账号(traffic_max 只有 1MB),而这种账号连 /ServerCredentials 都取不到:

400  errorCode 1700
     "User unable to generate credentials. status = 2"

也就是说降额号完全不可用,不是"额度小一点"的问题。

Cloudflare Worker 的出口 IP 是整个平台共享的,早被别人拿去开过号, 所以 Worker 里开不出能用的账号。开户放到 GitHub Actions 上做, runner 的 IP 干净。

13 个地区,62 台落地:

美国东部/中部/西部  加拿大东部/西部  英国  法国  德国  荷兰
挪威  瑞士  罗马尼亚  香港

落地是机房 IP,M247 为主。

配置步骤

和 Proton 共用同一个推送地址,不用再加 secret:

  1. 管理页「Proton 落地」那里生成推送地址,配进 WORKER_PUSH_URL
  2. 跑一次 取 Windscribe 账号 流水线

流水线会自己在地址末尾加 /wind。它开完号会先验一次能不能取到代理凭据, 拿到降额号就直接失败退出,不会把不能用的号推给 Worker。

流量用完了怎么办

管理页「Windscribe 落地」区块能看到本月用了多少。用完重跑一次流水线换个号。

偶尔会碰上 runner 的 IP 被别人用过,这时流水线会报 拿到的是降额账号 status=2,重跑一次换台机器就行。

流水线也配了每月 1 号自动跑一次,对上 Windscribe 的月度重置。

跑测试

cd worker && npm test

99 项,覆盖常数时间比较、token 伪造/篡改/过期、登录限速、并发初始化, Proton 凭据推送(令牌校验、坏数据、过期拒绝、换令牌失效), 配置结构(分组完整性、无悬空引用、直连组成员正确), 以及路由层的鉴权(未登录一律 404、订阅 token 校验、按需重建、cookie 安全属性)。

两个坑

WebCrypto 导不出 mihomo 要的私钥格式。 WebCrypto 只能导 PKCS8, mihomo 要 SEC1,直接喂会报 use ParsePKCS8PrivateKey instead。 而且光把 PKCS8 里那段抠出来还不够——WebCrypto 省略了曲线参数, 会接着报 unknown elliptic curve。warp.js 里的 pkcs8ToSec1 重新编了一份带 P-256 OID 的完整 SEC1。

Opera 的 API 用 Digest 认证,而 Digest 要 MD5。 WebCrypto 没有 MD5, 所以 md5.js 是手写的。另外 Workers 的 fetch 不自动管 cookie, SurfEasy 的会话得手工存 Set-Cookie。

跟 Actions 版的区别

Worker 版少一道 mihomo -t 校验——Actions 里会真的下载 mihomo 加载一遍, 确保推出去的配置能用,Worker 里做不到。

换来的是自动更新和一个随时可用的 URL。

warp-masque-actions (byJoey/warp-masque-actions)

Searching Database…

What is this?A GitHub Actions pipeline that generates a Cloudflare WARP (MASQUE) proxy config with 57 nodes, packaged as a mihomo config file, with nothing to install and no server needed to produce it.
Is this an app I install, or just a workflow I run in the cloud?It is a workflow you trigger inside your forked repo's Actions tab; the output is only kept as a downloadable artifact, not an installed app, and you still need a separate mihomo-based client to actually connect with it.
How do I generate and import a config?Fork the repo, open the Actions tab and enable workflows, run the '生成 WARP MASQUE 配置' workflow (takes about a minute), then download the 'warp-masque-config' artifact and import warp-masque.yaml (or the Shadowrocket .txt links) into your client.
Do I need a special client to use the config?Yes — masque only works on mihomo's Alpha kernel branch (used by Clash Verge Rev, ClashMetaForAndroid's prerelease-alpha, or ClashMi); Surge, Quantumult X and Karing don't support it at all.
Can I choose which country I exit from?No — all 57 nodes belong to the same free WARP account and share the same Cloudflare exit IP, just different entry points; picking a country requires WARP+ or Zero Trust, which this repo doesn't support (the optional Opera/Proton/Windscribe pipelines exist for that instead).
Which clients can actually use the generated config?Windows/macOS/Linux via Clash Verge Rev switched to its Alpha kernel, Android via ClashMetaForAndroid's prerelease-alpha build, iOS/macOS/Android/Windows/Linux via ClashMi (bundles mihomo), and any platform via the Shadowrocket masque:// links included in the artifact.
What does the 'Opera over MASQUE' pipeline add?It chains Opera's free SurfEasy VPN behind the WARP MASQUE tunnel so you can pick an exit region (Asia/Europe/Americas) instead of Cloudflare's fixed anycast exit, producing roughly 400 combined route nodes.
Is there a way to get an always-updating subscription instead of running the Action manually?Yes, the worker/ folder is a Cloudflare Worker version you deploy by binding a single KV namespace; it refreshes WARP/Opera credentials on demand whenever the subscription link is accessed and exposes a password-protected admin page.
Why not just use Opera's VPN directly instead of wrapping it in MASQUE?Using Opera alone has your device connect visibly to its 77.111.x.x SurfEasy servers; wrapping it in MASQUE means your machine only ever talks to Cloudflare's 162.159.198.x addresses, hiding the Opera hop inside the QUIC tunnel.
Can I get more exit countries than Opera's three regions?Yes, the Worker version optionally supports Proton (10 free countries, authenticated via a separate GitHub Actions login flow) and Windscribe (13 regions) as additional landing points behind the same MASQUE entry points.
Creator
byJoey
Size
0.2 MB
Stars
1.1K
Updated
CommitSep 07
Age
1mo
Commits · 90 Days