【订阅转换】自建订阅转换平台

本文最后更新于:2022年11月4日 下午

笔者的订阅转换链接:https://sub.pawswrite.xyz

订阅转换是说,把一份配置文件/节点列表中的节点提取出来,配上一些好用的分流规则,适配Clash|ClashR|QuantumultX|ShadowRocket|Surge等等客户端。

  • 机场可能提供了纯v2节点列表或者小火箭的配置文件,但你需要用在Clash或者Surge等其他的客户端,但机场没给现成的。

  • 你不满意机场提供的分流规则,想换成别的。机场给的配置文件也不能够涵盖你的需求。

  • 你用一键脚本自建翻墙节点,需要转换成不同客户端的配置文件。

这个时候就需要用到订阅转换。现在有一些大佬做了订阅转换的网站,比如说边缘订阅转换。这些都是公益免费很方便。但问题就在于,用别人的后端转换订阅,存在一定的数据隐患,那还有甚者说自己的订阅已经被盗用,流量也是不正常。(当然我没出现过这种问题,一般来说人家也不屑于。。。)

偷订阅这种事情,除了当事人,没人知道到底有没有。实在不行,那咱们就自己建一个订阅转换。毕竟前后端都已经开源了。

前期需求

  • 一台拥有公网IP的服务器(没有公网IP就自己研究内网穿透啊什么的)
  • 一个域名

项目地址

前端项目地址:https://github.com/CareyWang/sub-web
后端项目地址:https://github.com/tindy2013/subconverter

域名解析

作者使用的是CloudFlare进行解析。解析两个域名,分别给前端和后端。

  1. 前端 我们使用 sub.你的域名 进行解析
  2. 后端 我们使用 suc.你的域名 进行解析

开启CDN代理会更安全

前端

使用uname -a看一下自己的服务器架构,如果是amd,直接使用官方镜像,如果是arm则需要自己构建镜像或者使用笔者构建的镜像:docker push techfever/sub-web:latest

【amd架构】Docker运行

1
docker run -d -p 58080:80 --restart always --name subweb careywong/subweb:latest

若需要对代码进行修改,你需要在本地构建镜像并运行。
注:每次修改代码,你都需要重新执行 docker build 来执行打包操作。

1
2
3
docker build -t subweb-local:latest .

docker run -d -p 58080:80 --restart always --name subweb subweb-local:latest

【arm架构】利用GitHub Actions自行build镜像并push到DockerHub

因为笔者用的是arm架构的服务器,而作者的 careywong/subweb:latest 并不支持。因此可以自己编译镜像【推荐】。

也可以用笔者的镜像:

1
docker run -d -p 58080:80 --restart always --name subweb techfever/sub-web:latest

下面讲解如何自行编译镜像:

自行编译镜像

注册DockerHub

先注册DockerHub,记住账号密码。

添加Secrets

先登录自己的账号 fork 项目sub-web,然后打开Settings,在Secrets-Actions下添加两个Secret,分别是 DOCKER_USERNAMEDOCKER_PASSWORD。请注意 DOCKER_USERNAME 需要全部小写

打开项目,点击Actions,选择New workflow,选择 set up a workflow yourself ,然后将下面的代码复制进去,你也可以选择复制我的yml文件

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
name: Docker Image CI

on:
push:
branches: [ master ]

jobs:

Docker:

runs-on: ubuntu-latest


steps:
- name: Check out the repo
uses: actions/checkout@v2

- uses: docker/setup-qemu-action@v1

- uses: docker/setup-buildx-action@v1

- uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build and push Docker images
uses: docker/build-push-action@v2
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: 你的DockerHub用户名/sub-web:latest

记得写入你的DockerHub用户名

保存以后,会自动运行actions(如果没有运行的话需要进入actions选择``enable workflow`),然后你的DockerHub就会出现新的镜像。

修改镜像

  1. 如果你是上一小节说的方法自行编译镜像,那么每次对镜像进行任何修改,都只需要将改变提交到GitHub,然后GitHub actions就会自动编译新的镜像并且推送到DockerHub,你只需要pull新镜像即可。
  2. 如果你是使用别人的镜像,那么你需要先进入容器:
    1
    docker exec -it subweb bash
    之后在容器里进行修改。

运行镜像

运行自己的镜像:

1
docker run -d -p 58080:80 --restart always --name subweb 你的dockerhub名字/sub-web:latest

预览前端

到目前为止,浏览器访问 http://服务器ip:58080/ 应该可以进行前端 sub-web 的预览了。

如果需要用域名来访问,而不是ip:端口的形式来访问,那我们就需要反代前端,该内容在后面小节有提到。

前端修改

前端默认的后端地址是https://api.wcc.best,可以用,但我们的目的是为了数据安全,要自建后端,当然需要修改。

本节进行了修改以后,都需要删除原来的容器,并用修改后的镜像来运行。

  • 【推荐】如果你是通过 GitHub Actions 进行构建,那么直接修改以后push到GitHub,之后把Actions构建并推送到Docker Hub的最新镜像pull下来即可。
    1
    2
    3
    docker stop subweb && docker rm subweb
    docker rmi techfever/sub-web:latest && docker pull techfever/sub-web:latest
    docker run -d -p 127.0.0.1:58080:80 --restart always --name subweb techfever/sub-web:latest
  • 如果你是在本地构建镜像并运行。每次修改代码,你都需要重新执行 docker build 来执行打包操作。

修改默认后端地址

如果你是使用自己构建Docker镜像的方式,首先打开sub-web/.env文件修改下面这项,把https://api.wcc.best改成你自己的后端地址(后面会配置,比如笔者的是https://suc.pawswrite.xyz):

1
2
3
4
5
# API 后端
VUE_APP_SUBCONVERTER_DEFAULT_BACKEND = "https://api.wcc.best"

# 文本托管后端
VUE_APP_CONFIG_UPLOAD_BACKEND = "https://api.wcc.best"

增加远程配置【可选】

找到 sub-web/src/views/Subconverter.vue 文件,找到 259 行 remoteConfig: [(写博客的时候是这行),敲下回车,插入下面内容。有不清楚的就参照我的Subconverter.vue

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
{
label: "ACL4SSR",
options: [
{
label: "ACL4SSR_Online 默认版 分组比较全 (与Github同步)",
value:
"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online.ini"
},
{
label: "ACL4SSR_Online_AdblockPlus 更多去广告 (与Github同步)",
value:
"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_AdblockPlus.ini"
},
{
label: "ACL4SSR_Online_NoAuto 无自动测速 (与Github同步)",
value:
"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_NoAuto.ini"
},
{
label: "ACL4SSR_Online_NoReject 无广告拦截规则 (与Github同步)",
value:
"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_NoReject.ini"
},
{
label: "ACL4SSR_Online_Mini 精简版 (与Github同步)",
value:
"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini.ini"
},
{
label: "ACL4SSR_Online_Mini_AdblockPlus.ini 精简版 更多去广告 (与Github同步)",
value:
"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_AdblockPlus.ini"
},
{
label: "ACL4SSR_Online_Mini_NoAuto.ini 精简版 不带自动测速 (与Github同步)",
value:
"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_NoAuto.ini"
},
{
label: "ACL4SSR_Online_Mini_Fallback.ini 精简版 带故障转移 (与Github同步)",
value:
"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_Fallback.ini"
},
{
label: "ACL4SSR_Online_Mini_MultiMode.ini 精简版 自动测速、故障转移、负载均衡 (与Github同步)",
value:
"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_MultiMode.ini"
},
{
label: "ACL4SSR_Online_Full 全分组 重度用户使用 (与Github同步)",
value:
"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full.ini"
},
{
label: "ACL4SSR_Online_Full_NoAuto.ini 全分组 无自动测速 重度用户使用 (与Github同步)",
value:
"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_NoAuto.ini"
},
{
label: "ACL4SSR_Online_Full_AdblockPlus 全分组 重度用户使用 更多去广告 (与Github同步)",
value:
"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_AdblockPlus.ini"
},
{
label: "ACL4SSR_Online_Full_Netflix 全分组 重度用户使用 奈飞全量 (与Github同步)",
value:
"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_Netflix.ini"
},
{
label: "ACL4SSR 本地 默认版 分组比较全",
value: "config/ACL4SSR.ini"
},
{
label: "ACL4SSR_Mini 本地 精简版",
value: "config/ACL4SSR_Mini.ini"
},
{
label: "ACL4SSR_Mini_NoAuto.ini 本地 精简版+无自动测速",
value: "config/ACL4SSR_Mini_NoAuto.ini"
},
{
label: "ACL4SSR_Mini_Fallback.ini 本地 精简版+fallback",
value: "config/ACL4SSR_Mini_Fallback.ini"
},
{
label: "ACL4SSR_BackCN 本地 回国",
value: "config/ACL4SSR_BackCN.ini"
},
{
label: "ACL4SSR_NoApple 本地 无苹果分流",
value: "config/ACL4SSR_NoApple.ini"
},
{
label: "ACL4SSR_NoAuto 本地 无自动测速 ",
value: "config/ACL4SSR_NoAuto.ini"
},
{
label: "ACL4SSR_NoAuto_NoApple 本地 无自动测速&无苹果分流",
value: "config/ACL4SSR_NoAuto_NoApple.ini"
},
{
label: "ACL4SSR_NoMicrosoft 本地 无微软分流",
value: "config/ACL4SSR_NoMicrosoft.ini"
},
{
label: "ACL4SSR_WithGFW 本地 GFW列表",
value: "config/ACL4SSR_WithGFW.ini"
}
]
},

nginx反代前端

为了之后再用nginx进行反代,可以停止之前的容器,再重新启动:

1
2
docker stop subweb && docker rm subweb
docker run -d -p 127.0.0.1:58080:80 --restart always --name subweb techfever/sub-web:latest

创建新的nginx配置文件:

1
vim /etc/nginx/conf.d/subconverter.conf

输入下列配置,将其中 sub.pawswrite.xyz 部分改成你的域名::

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
server {
listen 80;
listen [::]:80;
server_name sub.pawswrite.xyz;

return 301 https://$host$request_uri;
}

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
# Replace bark.app.dev with your real domain name.
server_name sub.pawswrite.xyz;

# ssl_certificate /path/to/signed_cert_plus_intermediates;
# ssl_certificate_key /path/to/private_key;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;

# modern configuration
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;

# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;

# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;

# verify chain of trust of OCSP response using Root CA and Intermediate certs
# ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;

# replace with the IP address of your resolver
#resolver 127.0.0.1;

location / {

log_not_found on;
proxy_pass http://127.0.0.1:58080;

proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;

proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
}
}

之后就可以用域名来访问前端面板了。

后端

下载

先在GitHub上找到最新的后端发布版本,选择适配你服务器架构的压缩文件,如果不知道你服务器的架构,采用命令 uname -m 来查看,比如笔者就是 aarch64 。然后复制你对应的压缩文件链接:

在服务器上下载并解压后端程序:

1
2
3
cd /root
wget https://github.com/tindy2013/subconverter/releases/download/v0.7.2/subconverter_aarch64.tar.gz
tar -zxvf subconverter_aarch64.tar.gz

修改配置文件参数

现在我们需要修改后端配置文件中的一些参数。

复制一份配置文件到本地:

1
cp  /root/subconverter/pref.example.ini /root/subconverter/pref.ini

找到如下参数进行修改:

1
2
3
api_access_token=123123dfsdsdfsdfsdf            #随意设置自己知道就行
managed_config_prefix=https://suc.v2rayssr.com #设置成我们刚刚解析的后端域名
listen=127.0.0.1 #这里改成 127.0.0.1 进行反代

创建服务进程并启动
接下来我们需要创建一个服务,让VPS每次重启或是开机自动运行后端程序

找到VPS目录 /etc/systemd/system,创建一个名为 sub.service 的文件

打开文件,贴入以下内容,保存。

1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=A API For Subscription Convert
After=network.target

[Service]
Type=simple
ExecStart=/root/subconverter/subconverter
WorkingDirectory=/root/subconverter
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

检查运行状态以及设置开机自启

1
2
3
4
systemctl daemon-reload
systemctl start sub
systemctl enable sub
systemctl status sub

到这里,后端也就搭建完毕了,我们现在可以在浏览器里面访问我们的后端了 https://suc.pawswrite.xyz (正常的话,会返回下面的图例)

nginx反代后端

创建新的nginx配置文件:

1
vim /etc/nginx/conf.d/subconverter2.conf

输入下列配置,将其中 suc.pawswrite.xyz 部分改成你的域名:

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
server {
listen 80;
listen [::]:80;
server_name suc.pawswrite.xyz;

return 301 https://$host$request_uri;
}

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
# Replace bark.app.dev with your real domain name.
server_name suc.pawswrite.xyz;

# ssl_certificate /path/to/signed_cert_plus_intermediates;
# ssl_certificate_key /path/to/private_key;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;

# modern configuration
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;

# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;

# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;

# verify chain of trust of OCSP response using Root CA and Intermediate certs
# ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;

# replace with the IP address of your resolver
#resolver 127.0.0.1;

location / {

log_not_found on;
proxy_pass http://127.0.0.1:58080;

proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;

proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
}
}

安装cerbot申请证书

安装certbot的步骤参照:https://certbot.eff.org

申请证书使用命令:

1
certbot --nginx

按照步骤来即可


【订阅转换】自建订阅转换平台
https://pawswrite.xyz/posts/4014.html
作者
Rainbow
发布于
2022年5月25日
许可协议