Compare commits
6 Commits
v0.1.0-alp
...
main
Author | SHA1 | Date |
---|---|---|
Nite07 | 036907fba4 | |
Nite07 | 3e720ec14d | |
Nite07 | b73a02bdbf | |
Nite07 | 25e47453cb | |
Nite07 | 3330412243 | |
Nite07 | 35deaa015f |
|
@ -0,0 +1,55 @@
|
|||
name: docker
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
jobs:
|
||||
prepare-and-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
nite07/sub2clash
|
||||
ghcr.io/nitezs/sub2clash
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=match,pattern=(alpha|beta|rc),group=1
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
build-args: |
|
||||
"version=${{ github.ref_name }}"
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
|
@ -0,0 +1,28 @@
|
|||
name: release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v5
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
args: release --clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@ -4,4 +4,5 @@ subs
|
|||
logs
|
||||
data
|
||||
.env
|
||||
.vscode/settings.json
|
||||
.vscode/settings.json
|
||||
test
|
|
@ -28,3 +28,5 @@ archives:
|
|||
- LICENSE
|
||||
- README.md
|
||||
- templates
|
||||
release:
|
||||
draft: true
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"program": "${workspaceFolder}/main.go",
|
||||
"program": "${workspaceFolder}",
|
||||
"output": "${workspaceFolder}/dist/main.exe",
|
||||
"buildFlags": "-ldflags '-X sub2clash/constant.Version=dev'"
|
||||
}
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
when:
|
||||
- event: tag
|
||||
ref: refs/tags/v*
|
||||
|
||||
steps:
|
||||
- name: prepare-tags
|
||||
image: bash
|
||||
commands:
|
||||
- |
|
||||
echo "${CI_COMMIT_TAG##v}" > .tags
|
||||
if ! echo "${CI_COMMIT_TAG}" | grep -Eq "beta|alpha"; then
|
||||
echo "latest" > .tags
|
||||
fi
|
||||
- name: build
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
platforms: linux/amd64
|
||||
repo: nite07/sub2clash
|
||||
username: nite07
|
||||
password:
|
||||
from_secret: docker_password
|
|
@ -1,20 +0,0 @@
|
|||
when:
|
||||
- event: tag
|
||||
ref: refs/tags/v*
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: goreleaser/goreleaser:latest
|
||||
commands:
|
||||
- goreleaser release --clean --skip publish
|
||||
- mkdir release
|
||||
- mv dist/*.tar.gz release/
|
||||
- mv dist/*.zip release/
|
||||
- name: release
|
||||
image: woodpeckerci/plugin-gitea-release
|
||||
settings:
|
||||
files: release/*
|
||||
api_key:
|
||||
from_secret: forgejo_token
|
||||
base-url: https://git.nite07.com
|
||||
draft: true
|
42
README.md
42
README.md
|
@ -1,29 +1,31 @@
|
|||
# sub2clash
|
||||
|
||||
> Sing-box 用户?看看另一个项目 [sub2sing-box](https://github.com/nitezs/sub2sing-box)
|
||||
|
||||
将订阅链接转换为 Clash、Clash.Meta 配置
|
||||
[预览](https://www.nite07.com/sub)
|
||||
|
||||
## 特性
|
||||
|
||||
- 开箱即用的规则、策略组配置
|
||||
- 自动根据节点名称按国家划分策略组
|
||||
- 支持多订阅合并
|
||||
- 支持添加自定义 Rule Provider、Rule
|
||||
- 支持多种协议
|
||||
- Shadowsocks
|
||||
- ShadowsocksR
|
||||
- Vmess
|
||||
- Vless (Clash.Meta)
|
||||
- Trojan
|
||||
- Hysteria (Clash.Meta)
|
||||
- Hysteria2 (Clash.Meta)
|
||||
- 开箱即用的规则、策略组配置
|
||||
- 自动根据节点名称按国家划分策略组
|
||||
- 多订阅合并
|
||||
- 自定义 Rule Provider、Rule
|
||||
- 支持多种协议
|
||||
- Shadowsocks
|
||||
- ShadowsocksR
|
||||
- Vmess
|
||||
- Vless (Clash.Meta)
|
||||
- Trojan
|
||||
- Hysteria (Clash.Meta)
|
||||
- Hysteria2 (Clash.Meta)
|
||||
|
||||
## 使用
|
||||
|
||||
### 运行
|
||||
### 部署
|
||||
|
||||
- [docker compose](./docker-compose.yml)
|
||||
- 运行[二进制文件](https://github.com/nitezs/sub2clash/releases/latest)
|
||||
- [docker compose](./docker-compose.yml)
|
||||
- 运行[二进制文件](https://github.com/nitezs/sub2clash/releases/latest)
|
||||
|
||||
### 配置
|
||||
|
||||
|
@ -49,11 +51,11 @@
|
|||
可以通过变量自定义模板中的策略组代理节点
|
||||
具体参考下方默认模板
|
||||
|
||||
- `<all>` 为添加所有节点
|
||||
- `<countries>` 为添加所有国家策略组
|
||||
- `<地区二位字母代码>` 为添加指定地区所有节点,例如 `<hk>` 将添加所有香港节点
|
||||
- `<all>` 为添加所有节点
|
||||
- `<countries>` 为添加所有国家策略组
|
||||
- `<地区二位字母代码>` 为添加指定地区所有节点,例如 `<hk>` 将添加所有香港节点
|
||||
|
||||
#### 默认模板
|
||||
|
||||
- [Clash](./templates/template_clash.yaml)
|
||||
- [Clash.Meta](./templates/template_meta.yaml)
|
||||
- [Clash](./templates/template_clash.yaml)
|
||||
- [Clash.Meta](./templates/template_meta.yaml)
|
||||
|
|
|
@ -135,3 +135,29 @@ func GetRawConfHandler(c *gin.Context) {
|
|||
// 返回响应内容
|
||||
c.String(http.StatusOK, string(all))
|
||||
}
|
||||
|
||||
func GetRawConfUriHandler(c *gin.Context) {
|
||||
// 获取动态路由参数
|
||||
hash := c.Query("hash")
|
||||
password := c.Query("password")
|
||||
|
||||
if strings.TrimSpace(hash) == "" {
|
||||
c.String(http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 查询数据库中的短链接
|
||||
shortLink, err := database.FindShortLinkByHash(hash)
|
||||
if err != nil {
|
||||
c.String(http.StatusNotFound, "未找到短链接或密码错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 校验密码
|
||||
if shortLink.Password != "" && shortLink.Password != password {
|
||||
c.String(http.StatusNotFound, "未找到短链接或密码错误")
|
||||
return
|
||||
}
|
||||
|
||||
c.String(http.StatusOK, shortLink.Url)
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ var staticFiles embed.FS
|
|||
func SetRoute(r *gin.Engine) {
|
||||
r.Use(middleware.ZapLogger())
|
||||
|
||||
// 使用内嵌的模板文件
|
||||
tpl, err := template.ParseFS(staticFiles, "static/*")
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing templates: %v", err)
|
||||
|
@ -33,9 +32,6 @@ func SetRoute(r *gin.Engine) {
|
|||
r.GET(
|
||||
"/", func(c *gin.Context) {
|
||||
version := constant.Version
|
||||
if len(constant.Version) > 7 {
|
||||
version = constant.Version[:7]
|
||||
}
|
||||
c.HTML(
|
||||
200, "index.html", gin.H{
|
||||
"Version": version,
|
||||
|
@ -48,4 +44,5 @@ func SetRoute(r *gin.Engine) {
|
|||
r.GET("/s/:hash", handler.GetRawConfHandler)
|
||||
r.POST("/short", handler.GenerateLinkHandler)
|
||||
r.PUT("/short", handler.UpdateLinkHandler)
|
||||
r.GET("/short", handler.GetRawConfUriHandler)
|
||||
}
|
||||
|
|
|
@ -105,15 +105,17 @@ func ParseVless(proxy string) (model.Proxy, error) {
|
|||
result.Alpn = alpn
|
||||
result.Sni = sni
|
||||
result.AllowInsecure = insecureBool
|
||||
result.Fingerprint = fp
|
||||
result.ClientFingerprint = fp
|
||||
}
|
||||
|
||||
if security == "reality" {
|
||||
result.TLS = true
|
||||
result.Servername = sni
|
||||
result.RealityOpts = model.RealityOptions{
|
||||
PublicKey: pbk,
|
||||
ShortID: sid,
|
||||
}
|
||||
result.ClientFingerprint = fp
|
||||
}
|
||||
|
||||
if _type == "ws" {
|
||||
|
@ -133,7 +135,9 @@ func ParseVless(proxy string) (model.Proxy, error) {
|
|||
|
||||
if _type == "grpc" {
|
||||
result.Network = "grpc"
|
||||
result.Servername = serviceName
|
||||
result.GrpcOpts = model.GrpcOptions{
|
||||
GrpcServiceName: serviceName,
|
||||
}
|
||||
}
|
||||
|
||||
if _type == "http" {
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParser(t *testing.T) {
|
||||
// res, err := parser.ParseTrojan("trojan://Abse64hhjewrs@test.com:8443?type=ws&path=%2Fx&host=test.com&security=tls&fp=&alpn=http%2F1.1&sni=test.com#test")
|
||||
// if err != nil {
|
||||
// t.Log(err.Error())
|
||||
// t.Fail()
|
||||
// }
|
||||
// bytes, err := yaml.Marshal(res)
|
||||
// if err != nil {
|
||||
// t.Log(err.Error())
|
||||
// t.Fail()
|
||||
// }
|
||||
// t.Log(string(bytes))
|
||||
t.Log(strings.SplitN("123456", "/?", 2))
|
||||
|
||||
}
|
Loading…
Reference in New Issue