Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 

Repository files navigation

GrainTCPV1

基于 Cloudflare 的高性能代理节点订阅管理系统,采用 GrainTCP 内核引擎。


视频教程

RrainTCP视频教程

🛠 开源代码引用

本项目代码由 Claude Opus AI 辅助生成

引用的开源项目与服务:


目录


项目简介

GrainTCPV1 是一个部署在 Cloudflare 上的代理节点管理系统,提供:

  • 代理隧道(WebSocket → TCP)
  • 自适应订阅分发(自动识别客户端返回对应格式)
  • ECH 加密注入(提升连接隐蔽性)
  • 可视化后台管理面板
  • 多种代理出口方式(Direct / SOCKS5 / HTTP/HTTPS / ProxyIP / TURN/TURNS)
  • CF 用量实时监控(Telegram 仪表盘 + /stats 命令,含 Zone 流量与威胁统计)

支持两种部署方式:Workers(完整版)和 Snippets(精简版)。


功能一览

功能 Workers Snippets 说明
GrainTCP 代理内核 4 路并发竞速建连 + BYOB 零拷贝 + Early Data
TURN/TCP 中继 两版均支持匿名或长期凭证认证、A/AAAA 目标解析、IPv4/IPv6 XOR 地址和事务 ID 校验
TURN TXT/多服务器池 两版均只支持单个服务器,不支持逗号多地址、竞速池或 !txt 地址池
TURNS/TLS 中继 两版控制连接和数据连接均使用 TLS;Worker 还支持域名原生 TLS 与兼容 TLS 回退
SOCKS5 代理 全局/局部模式,支持用户名密码认证
HTTP CONNECT 代理 全局/局部模式,支持 Basic Auth
HTTPS CONNECT 代理 Snippets 通过真实 TLS 连接 HTTPS 代理服务器
ProxyIP 中转 指定优选 IP 作为出口中转
自适应订阅 根据客户端 UA 自动返回对应格式
ECH 加密 DoH 查询自动注入 ECH Config
后台管理面板 可视化管理界面
主题选择与保存 深色/浅色实时预览,支持浏览器保存、取消预览和恢复默认
D1 数据库 持久化存储配置和日志
Telegram 通知 登录/订阅操作实时推送
Desire 裂变 SUB_TOKEN 优选 IP 批量裂变
白名单/访问日志 IP 白名单免登录 + 日志记录
环境变量配置 Dashboard 在线修改配置
CF 用量 TG 仪表盘 Cron 每 30 分钟刷新 Telegram 仪表盘(仅 Worker 版,依赖 D1/Cron)
/stats 命令查询 Telegram 发送 /stats 实时查询用量(仅 Worker 版)
Zone HTTP 统计 区域级请求/威胁/缓存/带宽 + 国家/状态码/设备分布(仅 Worker 版)

文件说明

文件 大小 用途
worker.js ~307 KB Workers/Pages 完整版(可读源码,支持环境变量 + D1)
snippets.js ~32 KB Snippets 精简版(压缩代码,配置写在顶部)

两份文件共同支持 TURN/TCP、TURNS/TLS、SOCKS5、HTTP、ProxyIP、ECH、订阅和后台。Worker 的 TURN/TURNS 支持全局代理、直连失败回落、查询参数、Base64/UTF-8 凭证、DNS 缓存、438 Nonce 更新与 Allocation Refresh;Snippets 的 TURN/TURNS 仅支持全局 :// 路径,但额外实现了真实 HTTPS CONNECT。两版均不支持 TURN 多服务器池或 !txt 地址池。


界面预览

Snippets 版:

image

Snippets管理页面

Worker 版:

Worker登录页

Worker控制台

Worker订阅页面

Worker白名单

Worker日志

Worker网络信息


部署教程

方式一:Cloudflare Workers 部署(推荐)

适合:需要完整功能(D1 数据库、TG 通知、白名单、优选 IP 列表等)。

步骤

  1. 登录 Cloudflare Dashboard
  2. 左侧菜单进入 Workers & Pages → 点击右上角 创建
  3. 选择 Hello World 模板 → 点击 部署

创建Worker

  1. 部署完成后,在 Workers 列表找到刚部署的项目,点击 编辑代码

部署Worker

  1. Ctrl+A 全选 → 删除 → 粘贴 worker.js 全部代码

修改Worker代码

  1. 点击右上角 保存并部署
  2. 回到 Worker 概览页 → 进入 设置 → 变量和机密
  3. 添加环境变量(最少填:UUIDWEB_PASSWORDSUB_PASSWORD
  4. 可选:绑定自定义域名(设置 → 触发器 → 自定义域)

D1 数据库配置(必须,完整步骤)

D1 是 Cloudflare 提供的免费 SQLite 数据库,用于存储配置、白名单、日志和统计数据。Worker 版必须绑定 D1 才能使用后台管理功能。

第一步:创建 D1 数据库

  1. 登录 Cloudflare Dashboard
  2. 左侧菜单找到 Workers & Pages → 点击 D1 SQL 数据库
  3. 点击右上角 创建 按钮
  4. 数据库名称随意填写(如 graintcp_db)→ 点击 创建

第二步:初始化表结构

进入刚创建的数据库 → 点击 控制台 标签 → 粘贴以下 SQL 并点击 执行

CREATE TABLE IF NOT EXISTS config (key TEXT PRIMARY KEY, value TEXT);
CREATE TABLE IF NOT EXISTS whitelist (ip TEXT PRIMARY KEY, created_at INTEGER);
CREATE TABLE IF NOT EXISTS logs (id INTEGER PRIMARY KEY AUTOINCREMENT, time TEXT, ip TEXT, region TEXT, action TEXT);
CREATE TABLE IF NOT EXISTS stats (date TEXT PRIMARY KEY, count INTEGER DEFAULT 0);

执行成功后会看到 4 张表被创建。

第三步:绑定到 Worker

  1. 回到你的 Worker 项目 → 设置变量和机密
  2. 向下滚动找到 D1 数据库绑定 区域
  3. 点击 添加绑定
  4. 变量名称填:DB(必须大写,不可改名)
  5. D1 数据库下拉选择刚创建的数据库
  6. 点击 保存 → 重新部署 Worker

验证是否成功

部署后访问你的 Worker 域名,登录后台 → 如果白名单、日志、统计等功能正常显示,说明 D1 绑定成功。

D1 数据表说明

表名 用途 说明
config 配置存储 后台保存的所有配置(ProxyIP、TG Token 等)
whitelist IP 白名单 免登录 IP 地址列表
logs 访问日志 最近 2000 条操作记录(自动清理)
stats 每日统计 按日期累计访问次数

D1 免费额度

  • 每日读取:5,000,000 行
  • 每日写入:100,000 行
  • 存储空间:5 GB

正常使用远低于这些限制,无需担心。

方式二:Cloudflare Snippets 部署

适合:已有域名接入 Cloudflare、想要极简部署、无需 D1/TG 通知等扩展功能。

步骤

  1. 登录 Cloudflare Dashboard
  2. 选择你已接入的域名

找到有Snippets的域名

  1. 左侧菜单进入 规则 → Snippets → 点击 创建片段

在Snippets页面创建片段

  1. 输入片段名称(随意,如 graintcp

输入创建片段的名字

  1. 粘贴 snippets.js 全部代码
  2. 修改顶部配置区(UUID、密码、ProxyIP 等改成你自己的值)

编辑Snippets代码

  1. 在下方 触发规则 中设置匹配条件:
    • 字段:主机名 (Hostname)
    • 运算符:等于 (equals)
    • 值:你的子域名(如 sub.yourdomain.com

设置自定义筛选表达式

  1. 点击 启用片段规则 保存

启用片段规则

  1. 配置 DNS(重要):前往 DNS 设置页 → 添加 A 记录 → 名称填子域名 → IPv4 填 192.0.2.1 → 代理状态开启橙色云朵

创建新代理DNS记录指向

注意事项

  • Snippets 没有环境变量功能,所有配置直接改代码顶部
  • Snippets 有 32KB 大小限制
  • Snippets 的 CPU 执行时间有限,并发竞速数自动降为 1

方式三:Cloudflare Pages 部署

步骤

  1. worker.js 重命名为 _worker.js
  2. 将该文件放入一个空文件夹(如 graintcp/
  3. 进入 Workers & Pages创建 → 选择 Pages

Cloudflare主页

Pages创建应用程序

方法 A:GitHub 自动同步(推荐)

  1. 选择 导入现有 Git 存储库

选择导入现有git存储库

创建Pages导入现有git存储库

  1. 选择 GitHub 账户 → 选择你 Fork 的项目

选择存储库

  1. 写入项目名称并部署

创建Pages项目名字并部署

部署Pages页面

方法 B:直接上传

  1. 选择 上传部署

选择上传部署

  1. 写入项目名称并创建项目

写入项目名称并创建项目

  1. 上传包含 _worker.js 的 ZIP 压缩包或文件夹 → 点击 部署站点

选择项目zip包并部署

  1. 部署后进入 Pages 项目 设置 → 添加环境变量和 D1 绑定
  2. 重新部署使配置生效

配置说明

Workers 版(环境变量)

Workers 版通过 Cloudflare Dashboard 在线配置环境变量。

配置优先级:环境变量 > D1 数据库 > 代码硬编码

必填配置

变量名 说明 示例值
UUID 节点连接凭证(标准 UUID 格式) a1b2c3d4-1234-5678-abcd-123456789abc
WEB_PASSWORD 后台登录密码 mypassword123
SUB_PASSWORD 订阅路径密码 mysub
PROXYIP 默认 ProxyIP 中转地址 cdn.example.com1.2.3.4:443
SUB_DOMAIN 上游订阅源地址 https://owo.o00o.ooo/

可选配置

变量名 说明 默认值
SUBAPI 订阅转换后端 API https://subapi.cmliussss.net
PS 节点备注后缀(追加到节点名后)
DLS ADDCSV 速度下限筛选(MB/s) 7
CONCUR GrainTCP 并发竞速数(1-16) 4
SUB_TOKEN Desire 裂变 Token(留空不启用)
KEY 动态 UUID 密钥(启用后自动生成时效性 UUID)
UUID_REFRESH UUID 刷新周期(秒) 86400

订阅转换模板

变量名 说明 默认值
CLASH_CONFIG Clash 转换配置文件 URL https://raw.githubusercontent.com/cmliu/ACL4SSR/main/Clash/config/ACL4SSR_Online_Full_MultiMode.ini
SINGBOX_CONFIG_V11 sing-box 1.11 配置模板 URL https://raw.githubusercontent.com/sinspired/sub-store-template/main/1.11.x/sing-box.json
SINGBOX_CONFIG_V12 sing-box 1.12 配置模板 URL https://raw.githubusercontent.com/sinspired/sub-store-template/main/1.12.x/sing-box.json

ECH 配置

变量名 说明 默认值
ECH_ENABLED ECH 开关(truefalse true
ECH_SNI ECH 解析域名 cloudflare-ech.com
ECH_DNS DoH 查询地址 https://odvr.nic.cz/doh

Telegram 通知

变量名 说明 获取方式
TG_BOT_TOKEN Bot Token 找 @BotFather 创建机器人获取
TG_CHAT_ID 你的用户 ID 找 @userinfobot 获取

Cloudflare 统计配置

变量名 说明 配置方式
CF_ID Cloudflare Account ID CF_TOKEN 搭配使用
CF_TOKEN Cloudflare API Token 推荐方式,需具备读取统计权限
CF_EMAIL Cloudflare 账号邮箱 CF_KEY 搭配使用
CF_KEY Cloudflare Global API Key 兼容方式,不推荐长期暴露
CF_ZONE_ID Cloudflare 区域 ID(可选) 用于 Zone HTTP 统计,域名概览页右侧获取

CF Token 需勾选 Account Analytics: Read(Workers 用量);如启用 Zone 统计还需 Zone Analytics: Read

CF 用量监控配置

变量名 说明 默认值
STATS_ENABLED 启用 Cron 定时刷新 TG 仪表盘(true/false false
STATS_CHAT_ID 仪表盘推送目标 Chat ID(留空用 TG_CHAT_ID

优选节点来源

变量名 说明 格式
ADD 本地优选 IP 列表 每行一个:IP:端口#备注名
ADDAPI 远程 TXT 优选列表 URL 每行一个 URL
ADDCSV 远程 CSV 优选列表 URL 配合 DLS 过滤低速

界面链接

变量名 说明 默认值
LOGIN_PAGE_TITLE 登录页浏览器标题 Worker Login
DASHBOARD_TITLE 后台管理页标题 烈火控制台 · Glass LH
TG_GROUP_URL 交流群链接(登录页按钮) https://t.me/zyssadmin
SITE_URL 网站链接(登录页按钮) https://blog.2026565.xyz/
GITHUB_URL 项目地址(登录页按钮) https://github.com/xtgm/stallTCP1.32V2
PROXY_CHECK_URL ProxyIP 检测站链接 https://check.proxyip.cmliussss.net/

白名单配置

变量名 说明 格式
WL_IP 管理员 IP 白名单,命中后可免登录访问后台 多个 IP 用英文逗号分隔

D1 数据库绑定

变量名 类型 说明
DB D1 数据库绑定 必须绑定,变量名必须是 DB,不是普通文本环境变量

Snippets 版(代码顶部配置)

Snippets 版没有环境变量,直接修改代码顶部的值:

const UUID="你的UUID",WP="登录密码",SUB_PWD="订阅密码";
let PIP="你的ProxyIP地址",SUB="https://订阅源地址/";
const PC="https://检测站地址/";
let SUBAPI="https://订阅转换API",SUBINI="订阅转换配置URL";
变量 对应 Workers 版 说明
UUID UUID 节点连接凭证
WP WEB_PASSWORD 后台登录密码
SUB_PWD SUB_PASSWORD 订阅密码(访问 https://域名/密码 获取订阅)
PIP PROXYIP 默认 ProxyIP 中转地址
SUB SUB_DOMAIN 上游订阅源地址
PC PROXY_CHECK_URL ProxyIP 检测站链接
SUBAPI SUBAPI 订阅转换后端 API
SUBINI Clash 配置 URL 订阅转换配置文件

Snippets 版 ECH 配置修改

在代码中搜索替换以下值:

搜索 替换为 说明
ECH=!0 ECH=!1 关闭 ECH(!0=开,!1=关)
odvr.nic.cz/doh 你的 DoH 地址 更换 DoH 查询服务器
cloudflare-ech.com 你的 ECH SNI 更换 ECH 解析域名

代理使用教程

部署完成后,你的 Worker/Snippet 就是一个代理服务器。客户端通过 WebSocket 连接到你的域名,流量被转发到目标地址。

基本使用(直连模式)

客户端直接连接你的域名即可,流量直接从 Cloudflare 出口到目标服务器:

协议: VLESS
地址: 你的域名
端口: 443
UUID: 你配置的 UUID
传输: WebSocket
TLS: 开启
路径: /

以下代理路径会分别标注 Worker 与 Snippets 的实际能力,不能把某一版专属写法直接套用到另一版。v2rayN 的 Path 输入框填写原始路径;导出成 VLESS 链接后出现的 %2F%3A%40 等内容属于正常 URL 编码。

路径能力速查

类型 Worker Snippets 说明
ProxyIP 全局回落路径、查询参数 全局回落路径、查询参数 默认端口 443,必须是兼容本项目的专用 ProxyIP
SOCKS5 全局、局部、?s5= 全局、局部、?s5= 默认端口 1080;GrainTCP Worker 的域名/压缩 IPv6 目标存在旧编码限制
HTTP CONNECT 全局、局部 全局、局部 Worker 应显式填写端口;Snippets 省略端口默认 80
HTTPS CONNECT 不支持真实 TLS 全局、局部 Snippets 省略端口默认 443
TURN/TURNS 全局、回落、查询参数 仅全局 默认端口 3478/5349;均只支持单个服务器

使用 ProxyIP 中转

当直连目标失败时,可以通过 ProxyIP 作为回落出口。ProxyIP 不是 SOCKS5 或 HTTP 代理,必须填写兼容本项目转发方式的 ProxyIP 地址。

方式一:在配置中设置默认 ProxyIP

  • Workers 版:环境变量 PROXYIP 填入地址
  • Snippets 版:修改顶部 PIP 的值;生成订阅时会把它写入 /proxyip=... 路径

配置的默认值同时作为连接层兜底:当客户端路径为纯 /、且未通过任何方式指定代理时,自动使用该地址作为 ProxyIP 出口,并在回落顺序中补入 proxy 步骤。这样即使节点链接不携带 /proxyip=...,也能正常访问需要中转的站点。

兜底只在路径与查询参数完全没有指定代理时生效。已显式配置 ProxyIP、SOCKS5、HTTP/HTTPS 或 TURN 的路径一律按原样执行,不会被兜底值覆盖。

Workers 版兜底值的读取优先级为 环境变量 > D1 数据库 > 代码内置常量,与订阅生成器使用的值保持一致。Snippets 版没有环境变量,直接读取顶部 PIP 常量。

方式二:在客户端路径中指定

/proxyip=1.2.3.4:443
/proxyip/proxy.example.com:443
/ip=proxy.example.com:443
/ip/proxy.example.com:443

方式三:查询参数方式

/?proxyip=1.2.3.4:443

ProxyIP 支持域名、IPv4 和方括号 IPv6,端口默认 443,可以省略:

/proxyip=proxy.example.com
/proxyip=[2001:db8::1]:443

ProxyIP 的连接顺序为:

direct → proxy

mode=proxy 只指定顺序,并不会生成 ProxyIP 地址;完整写法是:

/?proxyip=proxy.example.com:443&mode=proxy

使用 SOCKS5 代理

通过外部 SOCKS5 代理服务器转发流量。两版均支持全局、局部和 ?s5= 查询写法,代理服务器端口省略时默认使用 1080。Snippets 支持域名、IPv4、压缩 IPv6 目标、UTF-8 与 Base64 凭证;Worker 支持无认证、ASCII 用户名密码和 Base64 凭证。

GrainTCP Worker 当前对 IPv4 目标最稳定;域名目标与压缩 IPv6 目标仍受旧 SOCKS5 地址类型编码限制。需要通过 SOCKS5 访问 CDN/域名或完整 IPv6 时优先使用 Snippets。代理服务器地址本身仍可填写域名、IPv4 或方括号 IPv6。

全局 SOCKS5(整个连接走 SOCKS5)

/socks5://用户名:密码@代理服务器地址:端口
/socks5://代理服务器地址:端口

示例:

/socks5://admin:pass123@proxy.example.com:1080
/socks5://proxy.example.com:1080
/socks5://admin:pass123@[2001:db8::1]:1080

/socks://... 是兼容别名,连接协议仍然是 SOCKS5,并非 SOCKS4:

/socks://admin:pass123@proxy.example.com:1080

局部 SOCKS5(作为回落选项)

/s5=用户名:密码@代理服务器地址:端口
/socks5=用户名:密码@代理服务器地址:端口
/socks=用户名:密码@代理服务器地址:端口

或通过查询参数:

/?s5=admin:pass123@proxy.example.com:1080

局部模式的连接顺序为:

direct → s5

如果需要强制只走 SOCKS5,必须同时提供地址:

/?s5=admin:pass123@proxy.example.com:1080&mode=s5

注意:/s5://.../?socks5=... 不属于当前支持的标准写法。

使用 HTTP/HTTPS CONNECT 代理

通过外部 HTTP 或 HTTPS CONNECT 代理服务器转发流量。HTTP 默认端口为 80;HTTPS 默认端口为 443

全局 HTTP 代理(整个连接走 HTTP CONNECT)

/http://用户名:密码@代理服务器地址:端口
/http://代理服务器地址:端口

示例:

/http://admin:pass123@proxy.example.com:8080
/http://proxy.example.com:8080

局部 HTTP 代理(作为回落选项)

/http=用户名:密码@代理服务器地址:端口
/http=代理服务器地址:端口

局部 HTTP 的连接顺序为:

direct → HTTP CONNECT

Snippets 全局 HTTPS 代理(与代理服务器建立真实 TLS)

/https://用户名:密码@代理服务器地址:443
/https://代理服务器地址:443

Snippets 局部 HTTPS 代理

/https=用户名:密码@代理服务器地址:443
/https=代理服务器地址:443

局部 HTTPS 的连接顺序为:

direct → HTTPS CONNECT

两版 HTTP CONNECT 均支持 Basic Auth 和 Base64 凭证;Snippets 额外支持 UTF-8 凭证及真实 HTTPS CONNECT。Worker 当前只提供明文 HTTP CONNECT,必须填写实际代理端口,不要把 /https:// 当作 Worker 的 TLS 代理写法。两版均不支持 /?http=.../?https=... 查询参数;/https=... 仅适用于 Snippets。

使用 TURN/TURNS 中继

TURN/TURNS 通过 RFC 6062 TCP 中继目标连接。TURN 的控制与数据连接使用普通 TCP;TURNS 的控制与数据连接都使用 TLS。两版均只接受一个服务器地址,不支持逗号多地址、竞速池、!txt 地址池、gturn/turnall 等批量写法,也不依赖 ?ed=2560

Worker 与 Snippets 能力区别

版本 全局代理 直连失败回落 查询参数 凭证 默认端口
Worker /turn://.../turns://... /turn=.../turns=...,也接受 /turn=turn://.../turns=turns://... /?turn=.../?turns=...;追加 &global=1&globalproxy=1 可改为全局 无认证、明文、URL 编码、Base64、UTF-8 3478 / 5349
Snippets /turn://.../turns://... 不支持 不支持 无认证、明文或 URL 编码,不支持 TURN 凭证 Base64 3478 / 5349

:// 表示整个连接直接走 TURN/TURNS,不再尝试 Direct、SOCKS5/HTTP 或 ProxyIP;Worker 的 = 与默认查询参数表示 direct → turn,只有直连失败后才使用中继。

Worker 全局代理写法

/turn://用户名:密码@turn.example.com:3478
/turns://用户名:密码@turn.example.com:5349
/turn://18.252.251.20:3478
/turns://[2001:db8::1]:5349

Worker 直连失败回落写法

/turn=用户名:密码@turn.example.com:3478
/turn=turn://用户名:密码@turn.example.com:3478
/turns=用户名:密码@turn.example.com:5349
/turns=turns://用户名:密码@turn.example.com:5349

Worker 查询参数写法

/?turn=用户名:密码@turn.example.com:3478
/?turns=用户名:密码@turn.example.com:5349
/?turn=用户名:密码@turn.example.com:3478&global=1
/?turns=用户名:密码@turn.example.com:5349&globalproxy=1

Snippets 写法

/turn://用户名:密码@turn.example.com:3478
/turns://用户名:密码@turn.example.com:5349

Snippets 的 /turn=.../turns=.../?turn=.../?turns=... 不会启用 TURN/TURNS;需要回落或查询参数时请部署 Worker 版。

认证和地址格式

不需要认证时可以直接填写服务器;两版均接受域名、IPv4 和方括号 IPv6:

/turn://turn.example.com
/turn://18.252.251.20:3478
/turns://[2001:db8::1]:5349

Worker 还可以把 用户名:密码 单独进行 Base64 编码:

/turn://YWRtaW46cGFzczEyMw==@turn.example.com:3478
/turns=YWRtaW46cGFzczEyMw==@turn.example.com:5349

用户名或密码包含中文、@: 等特殊字符时应进行 URL 编码。Snippets 不识别 TURN 凭证 Base64,只能使用明文或 URL 编码后的 用户名:密码@地址

解析、认证和 TLS 机制

  • Worker:目标域名依次使用 AliDNS、Cloudflare DNS、Google DNS 查询 A/AAAA;成功结果缓存 180 秒,空结果缓存 30 秒,最多 400 条,并合并同域名并发查询。
  • Snippets:目标域名查询 A/AAAA,并在 Cloudflare DNS 与 Google DNS 之间回退,不使用 Worker 的 DNS 缓存层。
  • 两版:支持 IPv4/IPv6 XOR-PEER-ADDRESS、Allocate、CreatePermission、Connect、ConnectionBind、401 长期凭证认证和全部事务 ID 校验。
  • Worker:额外处理 438 Stale Nonce、严格顺序事务、Allocation Refresh、分段/粘包响应、连接超时及失败连接清理。
  • Worker TURNS:域名优先使用 Cloudflare 原生 TLS;原生 TLS 失败或服务器为 IP 时使用自定义 TLS 兼容层,控制连接与数据连接都会加密。
  • Snippets TURNS:控制连接与数据连接均使用 Cloudflare 原生 TLS。

Worker 的自定义 TLS 兼容层用于提升 IP 与特殊 TURNS 服务兼容性,但不执行完整证书链和主机名验证。敏感场景应优先使用可信域名,让连接走 Cloudflare 原生 TLS。

在 v2rayN 的 Path 输入框中应填写原始路径:

/turn://admin:password@relay.example.com:3478

导出成 VLESS 链接后,客户端会自动编码为类似下面的形式:

path=%2Fturn%3A%2F%2Fadmin%3Apassword%40relay.example.com%3A3478

%3A%2F%2F 是 VLESS URL 中的正常编码表现,不需要在 v2rayN 的 Path 输入框中手动填写。

连接回落顺序

全局 :// 路径只走指定代理。没有命中全局代理时,两版默认都从 Direct 开始;Snippets 的普通顺序为 direct → s5 → proxy,其中 s5 可承载 SOCKS5、HTTP 或 HTTPS CONNECT。Worker 的 s5 只承载 SOCKS5/HTTP,并额外支持 TURN/TURNS 回落。

路径为纯 /(未指定任何代理)时,两版都会把配置中的默认 ProxyIP 作为兜底出口注入,实际顺序为 direct → proxy

方式 Worker Snippets
direct GrainTCP 竞速直连(默认 4 路并发) GrainTCP Snippets 直连
s5 SOCKS5 或 HTTP CONNECT SOCKS5、HTTP 或 HTTPS CONNECT
turn TURN/TURNS 中继 不支持查询参数回落
proxy ProxyIP 中转 ProxyIP 中转

Worker 使用 /turn=.../turns=... 时固定执行:

direct → TURN/TURNS

Worker 与 Snippets 均可通过查询参数顺序调整自身支持的回落步骤。例如:

/?direct&s5=admin:pass123@proxy.example.com:1080&proxyip=proxyip.example.com:443
/?direct&proxyip=proxyip.example.com:443&s5=admin:pass123@proxy.example.com:1080

分别对应:

direct → SOCKS5 → ProxyIP
direct → ProxyIP → SOCKS5

Worker 还可以把 TURN/TURNS 插入顺序:

/?direct&s5=admin:pass123@proxy.example.com:1080&turn=user:pass@turn.example.com:3478&proxyip=proxyip.example.com:443

对应:

direct → SOCKS5 → TURN → ProxyIP

Snippets 会忽略 turn/turns 查询回落项;其 TURN/TURNS 只能使用全局 :// 路径。mode 只控制顺序,不会自动生成代理地址,必须同时提供对应的 s5turnproxyip 实际值。

代理凭证 Base64 编码

两版 SOCKS5、HTTP,以及 Worker TURN/TURNS 都可以只对 用户名:密码 做 Base64 编码,代理服务器地址不参与编码:

/s5=YWRtaW46cGFzczEyMw==@proxy.example.com:1080
/http=YWRtaW46cGFzczEyMw==@proxy.example.com:8080
/turn=YWRtaW46cGFzczEyMw==@turn.example.com:3478

Snippets 的真实 HTTPS CONNECT 也支持:

/https=YWRtaW46cGFzczEyMw==@proxy.example.com:443

Snippets TURN/TURNS 不识别 Base64 凭证。用户名或密码包含中文、@: 等特殊字符时应进行 URL 编码;Worker 的旧 SOCKS5/HTTP 认证建议使用 ASCII,Worker TURN/TURNS 与 Snippets SOCKS5/HTTP/HTTPS 支持 UTF-8。


订阅使用教程

什么是订阅

订阅是一个 URL 链接,客户端软件通过访问这个链接获取节点配置信息。你只需将订阅链接添加到客户端,客户端会自动解析并生成可用节点。

获取订阅链接

部署完成后,有两种方式获取订阅:

方式一:通过订阅密码路径

https://你的域名/你的订阅密码

例如订阅密码是 mysub123

https://example.com/mysub123

方式二:通过 /sub 路径 + UUID 验证

https://你的域名/sub?uuid=你的UUID

方式三:通过后台管理面板

登录后台 → 找到"快速订阅"卡片 → 点击复制按钮。

自适应订阅(自动识别客户端)

系统会根据客户端发送的 User-Agent 自动判断返回什么格式,你不需要手动指定格式,直接把同一个订阅链接添加到不同客户端即可:

客户端软件 自动返回格式
Clash / Clash Meta / Mihomo Clash YAML 配置
FlClash / Stash Clash YAML 配置
NekoBox(ClashMeta 格式) Clash YAML 配置
Sing-box / SFI Sing-box JSON 配置
Hiddify / Karing Sing-box JSON 配置
Surge Surge 配置
Quantumult X QuanX 配置
Loon Loon 配置
V2rayN / V2rayNG Base64 编码节点列表
Shadowrocket Base64 编码节点列表
浏览器直接打开 明文节点列表

手动指定输出格式

如果自动识别不准确,可以在订阅 URL 后追加 ?target=格式名 强制指定:

https://你的域名/订阅密码?target=clash
https://你的域名/订阅密码?target=singbox
https://你的域名/订阅密码?target=surge
https://你的域名/订阅密码?target=quanx
https://你的域名/订阅密码?target=loon

在各客户端中添加订阅

Clash / Mihomo / FlClash

  1. 打开客户端 → 配置/Profiles
  2. 点击添加 → 输入订阅 URL → 保存
  3. 选中该配置 → 启动代理

V2rayN

  1. 订阅分组 → 添加订阅
  2. 地址填入订阅 URL
  3. 更新订阅 → 节点列表出现节点

Shadowrocket

  1. 首页右上角 + → 类型选 Subscribe
  2. URL 填入订阅地址 → 保存
  3. 下拉刷新更新节点

Sing-box / Hiddify / Karing

  1. 添加订阅/配置文件
  2. URL 填入订阅地址
  3. 保存并更新

配合 WorkerVless2sub 优选订阅生成器

WorkerVless2sub 是一个独立部署的订阅生成器,功能是把你的单节点批量替换成多个优选 IP 节点。

使用流程

  1. 部署 WorkerVless2sub 到另一个 Worker(如 sub.example.com
  2. 在 WorkerVless2sub 配置中添加优选 IP 列表
  3. 将你的 GrainTCPV1 节点信息粘贴到 WorkerVless2sub 前端页面
  4. 生成的订阅链接格式为:
https://sub.example.com/sub?uuid=UUID&sni=域名&host=域名&fp=chrome&alpn=h3&ech=...&type=ws&path=/proxyip%3D中转IP
  1. 将该链接添加到客户端

注意:WorkerVless2sub 可能不传递 fpech 参数(取决于其版本),如果 ECH 未生效请直接使用 GrainTCPV1 自身的订阅链接。


ECH 加密使用教程

什么是 ECH

ECH(Encrypted Client Hello)是一种 TLS 扩展,对 TLS 握手中的 SNI(服务器名称)进行加密。开启后,中间人无法通过 SNI 嗅探你连接的目标域名。

ECH 默认状态

部署后 ECH 默认开启,无需额外操作。

开启/关闭 ECH

Workers 版

  • 环境变量 ECH_ENABLED 设为 true(开启)或 false(关闭)

Snippets 版

  • 搜索 ECH=!0 替换为 ECH=!1 即可关闭
  • 搜索 ECH=!1 替换为 ECH=!0 即可开启

ECH 对各客户端的影响

ECH 开启后,系统自动对订阅内容做以下处理:

客户端 ECH 处理方式 用户是否需要操作
Clash / Mihomo / FlClash / Stash 自动注入 ech-opts + DNS 配置 否,自动
NekoBox 自动注入 ech-opts,内核自动 DNS 查询 否,自动
Sing-box / Hiddify / Karing 自动注入 tls.ech PEM 配置 否,自动
V2rayN / V2rayNG 节点 URI 追加 &ech=SNI+DNS 参数 否,自动
Shadowrocket 节点 URI 追加 &ech=SNI+DNS 参数 否,自动
Surge / Loon / Quantumult X 不注入(这些客户端不支持 ECH)

ECH 开启后的自动变化

  1. 指纹(Fingerprint):ECH 开启和关闭时均使用 chrome
  2. Clash 订阅:自动添加 DNS nameserver-policy 段 + 节点 ech-opts 配置
  3. Sing-box 订阅:自动添加 tls.ech 字段和 utls 指纹配置
  4. Base64 订阅:ECH 开启时为节点 URI 自动追加 &ech=,并统一使用 fp=chrome

更换 ECH 的 DoH 服务器

默认使用 https://odvr.nic.cz/doh。如需更换:

Workers 版:环境变量 ECH_DNS 填入新地址

Snippets 版:在代码中搜索 odvr.nic.cz/doh 替换为你的 DoH 地址

可选的公共 DoH 服务器:

  • https://odvr.nic.cz/doh
  • https://223.5.5.5/dns-query
  • https://dns.google/dns-query
  • https://cloudflare-dns.com/dns-query

验证 ECH 是否生效

  1. 订阅后打开客户端节点详情
  2. 检查是否有以下字段:
    • Clash:节点下方有 ech-opts: enable: true
    • Sing-box:tls 下有 ech: { enabled: true, config: "..." }
    • V2rayN:节点参数中有 ech=cloudflare-ech.com%2B...
  3. 如果没有,检查 ECH 开关是否开启,或尝试重新订阅

后台管理面板

进入后台

  1. 浏览器访问 https://你的域名
  2. 输入登录密码(Workers 版为 WEB_PASSWORD,Snippets 版为 WP
  3. 点击登录按钮进入管理面板

功能模块详解

快速自适应订阅

  • 显示你的自适应订阅链接(https://域名/订阅密码
  • 点击 复制 → 链接复制到剪贴板
  • 点击 测试 → 验证订阅链接是否正常返回数据

手动订阅链接

  • 显示带完整参数的订阅链接(含 UUID、SNI、path 等)
  • 可直接复制给客户端使用
  • 点击 更新链接 → 根据当前配置重新生成

ProxyIP 检测

  • 点击 检测 按钮 → 打开 ProxyIP 检测站
  • 验证当前 ProxyIP 地址是否可用、延迟如何

订阅源测试

  • 输入上游订阅源 URL
  • 点击 测试 → 系统 fetch 验证是否可连通

ECH 加密配置

  • 显示当前 ECH 状态(开启/关闭)
  • 显示 ECH DNS 地址和 ECH SNI 域名
  • Workers 版可在此修改配置

白名单管理(Workers 版)

  • 添加 IP 到白名单 → 该 IP 访问无需登录密码
  • 支持 IPv4 和 IPv6 地址
  • 点击删除可移除白名单条目

自定义节点(Workers 版)

  • ADD:手动添加优选 IP(格式 IP:端口#备注,每行一个)
  • ADDAPI:填入远程 TXT 文件 URL(每行一个 URL)
  • ADDCSV:填入远程 CSV 文件 URL
  • DLS:速度下限筛选(用于 ADDCSV,单位 MB/s)

访问日志(Workers 版)

  • 显示最近 50 条访问记录
  • 包含时间、IP、路径、User-Agent 信息

右上角工具栏

  • 主题设置:打开深色/浅色主题选择框
  • TG 通知:配置 Bot Token / Chat ID;含「CF 用量仪表盘」开关、推送 Chat ID、一键设置 Webhook 按钮(Workers 版)
  • CF 统计:配置 Account ID / API Token(或 Email + Global Key)+ Zone ID(区域统计用)
  • 退出登录:清除 Cookie 退出会话

主题设置说明

本功能适用于 Workers 版后台,默认使用深色主题。

  • 点击右上角 🌗 按钮打开“主题设置”选择框。
  • 支持 深色主题浅色主题 实时预览。
  • 点击 保存主题 后写入当前浏览器的 localStorage,刷新页面或重新打开浏览器仍然生效。
  • 点击 取消 会恢复打开选择框之前的主题。
  • 点击 恢复默认 会清除已保存记录并切回默认深色主题。
  • 主题偏好不会写入 Worker、D1 或账号配置,不同浏览器、设备及域名之间不会自动同步。

CF 用量实时监控

通过 Telegram 实时查看 Cloudflare 用量,支持定时刷新仪表盘命令查询两种方式。

功能说明

方式 触发 行为
定时仪表盘 Cron 每 30 分钟 自动刷新同一条 TG 消息(不刷屏)
命令查询 TG 发送 /stats 实时返回当前用量(额外显示分布详情)

显示内容

Workers 调用量(对应免费额度 10 万/天):

  • 进度条 + 百分比 + 状态灯(🟢 <50% / 🟡 50-80% / 🔴 >80%)
  • Workers / Pages 分项、剩余额度、较上次趋势(▲▼)

Zone 区域流量(需配 CF_ZONE_ID):

  • 总请求 / 威胁拦截🛡️ / 缓存命中率 / 带宽流量

分布详情(仅 /stats 命令,各 Top5):

  • 🌍 国家分布 / 📊 状态码分布 / 📱 设备分布

配置步骤(Workers 版)

  1. 配 CF 凭证:后台 ☁️ → 填 CF_ID+CF_TOKEN(或 CF_EMAIL+CF_KEY)+ Zone ID
    • Token 需勾选 Account Analytics: Read + Zone Analytics: Read
  2. 开启仪表盘:后台 🤖 → 勾选「CF 用量仪表盘」开关 →(可选填推送 Chat ID)→ 保存
  3. 设 Cron Trigger:CF Workers 后台 → Settings → Triggers → Cron Triggers → 添加 */30 * * * *
  4. 设 Webhook(命令查询用):后台 🤖 → 点「设置 Webhook」按钮(自动注册 /tg/webhook
  5. 测试:等 Cron 刷新,或在 TG 给 Bot 发 /stats

资源占用

  • CPU 消耗极低(亚毫秒级 JSON 解析;主要耗时在等网络,不计入 CPU)
  • Cron 每 30 分钟一次 = 48 次/天;分布维度 limit 5 锁定数据量
  • 实测总 CPU ~4-5ms,远低于免费版 10ms 墙,不会触发功耗墙

Snippets / Pages 说明

  • Snippets:CF 用量监控功能未在 Snippets 版实现(依赖 D1 数据库存储仪表盘状态 + Cron 定时触发,Snippets 均不支持)。此功能仅 Worker 版可用。
  • Pages/stats 命令查询可用;Cron 定时刷新需 Pages 支持 scheduled。

GrainTCP 内核参数

参数说明

参数 Workers 默认 Snippets 默认 说明
concur 4 1(自动降级) 并发竞速建连数
chunk 64 KB 64 KB BYOB 读取块大小
dnPack 32 KB 32 KB 下行打包阈值
upPack 16 KB 16 KB 上行合并阈值
upQMax 256 KB 256 KB 上行队列上限
maxED 8 KB 8 KB Early Data 最大长度

修改 concur(并发竞速数)

  • Workers 版:环境变量 CONCUR 设为 1-16 之间的数字
  • Snippets 版:自动为 1,无法修改(CPU 预算限制)

内核技术特性

特性 说明
raceSprout 竞速 同时建立 N 个 TCP 连接(N=concur),取最快的一个,关闭其余
concur 自适应 自动检测运行环境:Snippets 强制 1,Workers 默认 4
mkDn 下行打包 把多个小包合并后再发送,减少 WebSocket 帧数量
mill BYOB 读取 零拷贝方式读取 TCP 数据,大块直发,小块复用 buffer
mkQ 上行队列 多个上行小 chunk 合并为一次 TCP write,减少系统调用
Early Data 首个数据包通过 sec-websocket-protocol 头传递,省 1 个 RTT
半开连接 allowHalfOpen: true,一方关闭写入后另一方仍可读
无 import 语句 避免 Cloudflare Snippets 环境的代码检测问题
TURN/TURNS TCP 中继(Workers 与 Snippets) 两版支持 Allocate/CreatePermission/Connect/ConnectionBind、401 长期凭证认证、MESSAGE-INTEGRITY、IPv4/IPv6 XOR 地址和事务 ID 校验;Worker 另有 438 重试、刷新、DNS 缓存与 TLS 兼容回退

常见问题

部署相关

Q: Workers 和 Snippets 怎么选?

Workers Snippets
大小限制 1MB(免费版) 32KB
环境变量 支持 不支持
D1 数据库 支持 不支持
TG 通知 支持 不支持
白名单/日志 支持 不支持
需要自定义域名 是(或用 workers.dev) 否(用已有域名)
部署复杂度 中等 简单

总结:想要完整功能用 Workers;只要代理+订阅+后台基本功能用 Snippets。

Q: 部署后打开域名是空白/报错?

  1. 确认代码已完整粘贴(不能截断)
  2. 确认已点击"保存并部署"
  3. Workers 版:确认域名已绑定(设置 → 触发器 → 自定义域)
  4. Snippets 版:确认触发规则匹配正确

Q: 出现 Cloudflare 1101 错误?

1101 是 Cloudflare 检测到代码中的敏感特征。本项目已做反检测处理:

  • 敏感词使用字符串拆分(如 'so'+'cks5'
  • Snippets 版无 import 语句
  • 无高密度 atob 调用

如果触发:

  • 检查你是否在修改时引入了明文敏感词
  • 检查 Snippets 是否超过 32KB

连接相关

Q: 节点连不上?

  1. UUID 是否正确(客户端必须与服务端完全一致)
  2. 域名是否已接入 Cloudflare CDN(DNS 记录橙色云朵开启)
  3. 传输方式是否为 WebSocket + TLS
  4. 端口是否为 443(Cloudflare 支持的 HTTPS 端口)
  5. 路径是否正确(默认 /

Q: 能连但某些网站打不开?

  1. 尝试添加 ProxyIP:路径改为 /proxyip=你的ProxyIP地址:443
  2. 或在后台/配置中设置 ProxyIP
  3. 后台有 ProxyIP 检测按钮,可验证 ProxyIP 是否可用

配置了默认 ProxyIP 后,即使路径为纯 / 也会自动使用该地址作为兜底出口,无需在每个节点链接里手动写 /proxyip=...

Q: 用第三方订阅面板生成的节点连不上?

部分第三方面板(如 EDT)勾选「启用自动获取」ProxyIP 后,生成的节点链接路径是纯 /,不携带 /proxyip=... 参数。

本项目已支持这种情况:路径为空时自动回落到配置中的默认 ProxyIP。只需确认已正确配置:

  • Workers 版:环境变量 PROXYIP 已填写(或后台已保存到 D1)
  • Snippets 版:顶部 PIP 已填写

如果仍连不上,检查这个地址本身是否可用(后台 ProxyIP 检测按钮),以及客户端的 UUID、传输方式(WebSocket + TLS)、端口(443)是否与服务端一致。

Q: 速度慢?

  1. Workers 版尝试增加 CONCUR 值(如 4→8)
  2. 使用优选 IP:配置 ADD/ADDAPI/ADDCSV 添加更快的 CDN IP
  3. 更换 ProxyIP 为延迟更低的地址
  4. 确认客户端选择了延迟最低的节点

订阅相关

Q: 订阅后没有节点?

  1. 确认订阅 URL 正确(域名 + 订阅密码)
  2. 浏览器直接打开订阅 URL 看是否有内容返回
  3. 确认 UUID 已正确配置
  4. Workers 版确认环境变量已保存并重新部署

Q: 节点格式不对/客户端报错?

  1. 尝试手动指定格式:?target=clash?target=singbox
  2. 确认客户端版本支持当前节点格式
  3. 如果用的是 Sing-box,v1.11 和 v1.12 配置模板不同,系统会自动切换

Q: ECH 没有生效?

  1. 确认 ECH 开关已开启
  2. 确认客户端支持 ECH(Surge/Loon/QuanX 不支持)
  3. 重新订阅获取最新节点配置
  4. 检查节点详情中是否有 ech 相关字段
  5. 使用 WorkerVless2sub 时:该生成器可能不传递 ECH 参数,建议直接用本项目的订阅链接

后台相关

Q: 忘记登录密码?

  • Workers 版:在 Cloudflare Dashboard 修改 WEB_PASSWORD 环境变量
  • Snippets 版:修改代码顶部 WP 的值

Q: 复制按钮没反应?

浏览器剪贴板 API 要求 HTTPS 环境。确认通过 https:// 访问后台。

Q: 后台打不开?

  1. 确认域名解析正常
  2. 清除浏览器缓存后重试
  3. 尝试无痕/隐私模式打开
  4. 检查浏览器控制台是否有 JS 错误

TURN 相关

Q: TURN/TURNS 怎么用?

  • Worker 全局代理:/turn://用户:密码@地址:3478/turns://用户:密码@地址:5349
  • Worker 直连失败回落:/turn=用户:密码@地址:3478/turns=用户:密码@地址:5349
  • Worker 查询参数:/?turn=.../?turns=...,追加 &global=1 可强制全局。
  • Snippets:只使用 /turn://.../turns://... 全局路径。

Q: 什么时候用 TURN?

  • 直连、ProxyIP 或常规代理出口不可用时。
  • 企业网、校园网或其他需要 TCP 中继的环境。
  • TURN 本质是通过第三方服务器中继目标 TCP 连接。

Q: TURN 和 TURNS 区别?

  • TURN:控制连接和数据连接使用普通 TCP,默认端口 3478。
  • TURNS:控制连接和数据连接都使用 TLS,默认端口 5349。
  • Worker 与 Snippets 都实现真实 TURNS;Worker 额外提供原生 TLS 失败时的兼容 TLS 回退。

Q: 是否必须添加 ?ed=2560

不需要。两版 TURN/TURNS 都不依赖 Early Data 参数;在 v2rayN Path 中直接填写文档列出的原始路径即可。

Q: 哪里获取 TURN 服务器?

  • 自建:使用 coturn 等开源 TURN 服务器
  • 第三方:部分云服务商提供 TURN 服务

优选 IP 相关

Q: 怎么配合优选 IP?

Workers 版支持三种来源:

  1. ADD(手动列表):
1.2.3.4:443#美国节点1
5.6.7.8:443#日本节点1
cdn.example.com:443#CDN节点
  1. ADDAPI(远程 TXT):
https://example.com/ips.txt

TXT 文件内容格式同 ADD。

  1. ADDCSV(远程 CSV):
https://example.com/speed.csv

CSV 需包含 IP、端口、TLS 列,配合 DLS 环境变量过滤低速节点(单位 MB/s,默认 7)。

Snippets 版只支持单个 ProxyIP(PIP 配置项)。

CF 用量监控相关

Q: TG 仪表盘不自动刷新?

  1. 确认已在 CF Workers 后台添加 Cron Trigger:*/30 * * * *
  2. 确认后台「CF 用量仪表盘」开关已开启并保存
  3. 确认 TG_BOT_TOKEN + 推送 Chat ID(或 TG_CHAT_ID)已配置
  4. 此功能仅 Worker 版支持(依赖 D1 + Cron),Snippets 版未实现

Q: 发 /stats 没反应?

  1. 确认已点后台「设置 Webhook」按钮(注册 /tg/webhook
  2. 确认发命令的 Chat ID 与配置的推送 Chat ID 一致(白名单校验)
  3. 确认 Bot Token 正确

Q: 显示「查询失败」或 Zone 数据为空?

  1. CF Token 需勾选 Account Analytics: Read(Workers 用量)
  2. Zone 统计还需 Zone Analytics: Read + 正确的 CF_ZONE_ID
  3. 分布查询失败不影响基础统计——基础数据照常显示

Q: 担心仪表盘消耗 CPU / 触发功耗墙?

不会。实测单次 ~4-5ms CPU,远低于免费版 10ms 墙;主要耗时在等网络(不计 CPU),分布维度已用 limit 5 锁定数据量。


免责声明

本项目仅供技术交流与学习使用,请遵守当地法律法规。使用本程序产生的任何后果由使用者自行承担。

About

这是一个基于AK源代码的GrainTCP制作的一个后台版项目,由于GrainTCP使用手搓订阅对于小白很不友好以及懵懂。故此创建了这个项目,通过D1数据库后端去支持所有的功能,支持ECH、turn完整,核心使用GrainTCP。支持worker部署以及snippets部署。

Resources

Stars

61 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages