Sub-Store搭建
本文最后更新于 2026-07-21,文章内容可能已经过时。
一.什么是Sub-Store?:
Sub-Store 是网络代理圈(尤其是 iOS 网络工具用户)中极负盛名的“瑞士军刀”。
简单来说,它是一个高级订阅管理工具,专门解决多个代理订阅格式不统一、节点重复、筛选困难以及需要重命名等痛点。
二.搭建准备:
1.首先我们这次服务器搭建,所以最基础的准备就是一台可以上网的Linux主机,可以使用家里不使用的电脑安装Linux系统,或者在网上购买一台云主机,我这里使用直接的本地Linux小主机搭建(Ubuntu系统)
2.为了让搭建好的Sub-Store可以随时使用,那么需要去购买一个域名
以上两个就是我们这次搭建需要的核心东西,准备好就可以开始下一步
三.搭建:
1.安装1Panel面板:
1Panel 是一个界面现代化、深度集成 Docker、开源免费且安全易用的 Linux 服务器运维面板,能让你像操作手机App一样轻松管理服务器
首先连接你的Linux主机,输入:
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && bash quick_start.sh
然后按照指示步骤一步一步来执行安装
这里输入2选择中文:

这里直接回车(默认)

这个镜像加速根据直接的情况来定

端口,安全入口,账号密码,根据自己喜欢的填,需要自己能记住的,完成设置后记得保存命令行返回的信息

根将ip地址输入浏览器进行访问,并输入刚刚设置的账号密码

2.安装OpenResty:
进入后打开应用商店,下载Openresty
安装 OpenResty,是为了给面板提供高性能的网站运行引擎和流量网关,从而让你能够通过图形化界面轻松地创建网站、配置反向代理、自动管理 SSL 证书以及实现基础的 Web 安全防护。

全部默认即可

当显示"已启动"即可

3.为1Panel添加第三方库
1Panel原本自带的应用商店较少,需要自行添加第三方库
打开左侧的"计划任务"点击创建任务,任务类型选择shell脚本,然后将一下脚本复制粘贴到脚本内容中:
# 创建临时存放目录
git clone -b localApps https://github.com/okxlin/appstore /opt/1panel/resource/apps/local/appstore-localApps
# 将下载的应用移动到 1Panel 本地应用目录
cp -rf /opt/1panel/resource/apps/local/appstore-localApps/apps/* /opt/1panel/resource/apps/local/
# 删除临时目录
rm -rf /opt/1panel/resource/apps/local/appstore-localApps任务名称随意,执行周期按照自己的情况来

完成后点击确定,再点击执行,然后查看报告

当"执行中"变为成功即可

完成后回到应用商店界面,点击"更新应用列表",可以看到应用数量从232条变成577条

4.开始安装Sub-Store:
在应用商店处搜索Sub-Store,

注意,由于我们最终的效果是使用自己的域名进行访问,而且也要防止别人随意使用自己的Sub-Store,前端后端路径需要设置一复杂自己记得住的
我这里使用/King888为例:

填写完后点击确认等待安装完成即可:

5.在 Cloudflare 控制台配置 Tunnel
这是将你的域名与服务器内网 40232 端口打通的关键
访问https://cloudflare.com/(根据自己的情况来),登陆完成后,点击左侧的Zero Trust

再次点击左侧的网络->连接器->创建隧道

隧道类型我们选Cloudflared,隧道名称随便取一个自己记得住的,我这里使用"test-sub"为例

点击确认后,再操作系统的位置,我们选择Docker,这时下方会给问你一串"命令"我们将他复制到Linux终端回车执行.当终端显示类似于这样

且在Cloudflare上下方显示出连接器id已连接的时候就可以下一步了

点击下一步后根据自己的喜好填写Subdomain-子域名,域填写自己的域名

服务类型选http,URL填写局域网内网IP:40232(40232为最开始安装Sub-Store时填写的端口,请根据自己的情况来)

点击完成后,我们还需要去1Panel控制面板的容器.找到刚刚的cloudflare的docker容器,如果分辨不出来可以看镜像那一栏,一般都是cloudflare/cloudflared:latest,找到后点击右侧的更多->编辑,下滑找到重启规则,找到一直重启,这样当你的主机在重启后,该服务将会自动启动

然后就可以通过你的域名去访问网站了,例如我的是test-sub.king818.xyz
6.Sub-Store设置
首次打开,需要在后端连接配置中输入你的后端路径或地址,也就是我们刚刚三.4 部分所填写的前端后端路径,我填写的/King888,那我直接填入King888即可登录成功,首次打开网站,订阅处,啥也没有,需要我们自己去动手添加.
(1).点击立即添加,在点击单条订阅

(2).输入对应名称,选择远程订阅(下方的常用配置和节点操作可以根据自己的使用情况进行设置)设置完成后点击保存即可

保存成功后会在下方显示流量信息

(3).组合订阅的使用:
组合订阅,顾名思义,就是2个及以上的订阅服务,所以我们需要再添加一个订阅,添加完成后,就可以点击左上角的加号添加组合订阅了
名字随便取,在手动选择的订阅 里面将刚刚添加的两个订阅添加上去

其实勾选完成后,你就已经可以开始组成使用了,Sub-Store已经将你的所有机场汇总到一起,但是呢为了让你有更好的使用体验,我们可以在最下方添加2个脚本和1个旗帜操作。首先我们点击脚本操作,点击远程连接,并将下面这串地址复制粘贴上去:
https://raw.githubusercontent.com/Keywos/rule/main/rename.js解释一下这段脚本的作用是:
这是Github上Keywos大佬的规则,简单来说就是
用于对机场节点进行智能化清洗、格式标准化与信息整理:
智能地区识别与转换:自动识别节点名中的中英文地名、缩写或图标,并统一按需输出为中文、英文或 Emoji 国旗。
规范重命名与序列号:去除原始混乱名称,自动按地区进行分组并追加补零序号(如
🇯🇵 日本 01),且支持自动移除单节点地区的冗余编号。节点信息杂质清理:自动扫描并过滤掉机场订阅中混入的广告、官网网址、到期时间、剩余流量等非节点杂项。
关键标识提取与保留:精准识别并保留节点的倍率(如
0.5x、2x)、专线类型(如IPLC、IEPL、家宽)及自定义关键词,同时支持对关键属性进行重命名替换。
接下来添加一个旗帜操作

最后再添加一个脚本操作,点击脚本操作,点击本地内容,将以下内容直接复制粘贴上去:
// 合并组合订阅中单条订阅的流量 仅做流量加法
async function operator(proxies = [], targetPlatform, context) {
const SUBS_KEY = 'subs'
const COLLECTIONS_KEY = 'collections'
const $ = $substore
const { source } = context
const { _collection: collection } = source
if (!collection || Object.keys(source).length > 1) throw new Error('暂时仅支持组合订阅, 请在组合订阅中使用此脚本')
const allSubs = $.read(SUBS_KEY) || []
let uploadSum = 0
let downloadSum = 0
let totalSum = 0
let expire
let args = $arguments || {}
const { parseFlowHeaders, getFlowHeaders, flowTransfer, getRmainingDays } = flowUtils
const subnames = [...collection.subscriptions]
let subscriptionTags = collection.subscriptionTags
if (Array.isArray(subscriptionTags) && subscriptionTags.length > 0) {
allSubs.forEach(sub => {
if (
Array.isArray(sub.tag) &&
sub.tag.length > 0 &&
!subnames.includes(sub.name) &&
sub.tag.some(tag => subscriptionTags.includes(tag))
) {
subnames.push(sub.name)
}
})
}
for await (const sub of allSubs) {
if (subnames.includes(sub.name)) {
let subInfo
if (sub.source === 'local' && !['localFirst', 'remoteFirst'].includes(sub.mergeSources)) {
if (sub.subUserinfo) {
if (/^https?:\/\//.test(sub.subUserinfo)) {
subInfo = await getFlowHeaders(undefined, undefined, undefined, sub.proxy, sub.subUserinfo)
} else {
subInfo = sub.subUserinfo
}
}
} else {
let url = `${sub.url}`
.split(/[\r\n]+/)
.map(i => i.trim())
.filter(i => i.length)?.[0]
let urlArgs = {}
const rawArgs = url.split('#')
url = url.split('#')[0]
if (rawArgs.length > 1) {
try {
// 支持 `#${encodeURIComponent(JSON.stringify({arg1: "1"}))}`
urlArgs = JSON.parse(decodeURIComponent(rawArgs[1]))
} catch (e) {
for (const pair of rawArgs[1].split('&')) {
const key = pair.split('=')[0]
const value = pair.split('=')[1]
// 部分兼容之前的逻辑 const value = pair.split('=')[1] || true;
urlArgs[key] = value == null || value === '' ? true : decodeURIComponent(value)
}
}
}
args = { ...urlArgs, ...args }
if (!args.noFlow) {
if (sub.subUserinfo) {
if (/^https?:\/\//.test(sub.subUserinfo)) {
subInfo = await getFlowHeaders(undefined, undefined, undefined, sub.proxy, sub.subUserinfo)
} else {
subInfo = sub.subUserinfo
}
} else {
subInfo = await getFlowHeaders(url)
}
}
}
if (subInfo) {
const {
total,
usage: { upload, download },
expires,
} = parseFlowHeaders(subInfo)
if (upload > 0) uploadSum += upload
if (download > 0) downloadSum += download
if (total > 0) totalSum += total
if (expires && expires * 1000 > Date.now()) {
expire = expire ? Math.min(expire, expires) : expires
}
}
}
}
const subUserInfo = `upload=${uploadSum}; download=${downloadSum}; total=${totalSum}${
expire ? ` ; expire=${expire}` : ''
}`
// 旧版需要写入, 返回响应头里使用这个
const allCols = $.read(COLLECTIONS_KEY) || []
for (var index = 0; index < allCols.length; index++) {
if (collection.name === allCols[index].name) {
// 写入订阅流量信息
allCols[index].subUserinfo = subUserInfo
break
}
}
$.write(allCols, COLLECTIONS_KEY)
// 新版直接可以加到响应头里
if ($options) {
$options._res = {
headers: {
'subscription-userinfo': subUserInfo,
},
}
}
return proxies
}这个脚本的作用就是汇总组合订阅中的流量与过期时间,以上操作都完成后,点击保存,那么组合订阅就完工了.
四.导入工具
点击保存好的组合连接

会弹出以下窗口,点击通用订阅右边的复制按钮

打开工具(我这里以Clash Verge为例),点击订阅,将刚刚复制好的内容粘贴到上方输入窗口,再点击订阅,多出来一个订阅选项就代表我们成功了

- 感谢你赐予我前进的力量

