Skip to content

Commit

Permalink
新增ss、ssr、vmess、sip002订阅,优化clash以及ssr、ss节点部分
Browse files Browse the repository at this point in the history
  • Loading branch information
Tidra committed Mar 5, 2024
1 parent d126d3f commit 6023ef3
Show file tree
Hide file tree
Showing 11 changed files with 525 additions and 355 deletions.
150 changes: 141 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
<a href="https://goreportcard.com/report/github.com/Tidra/EasyGetProxy">
<img src="https://goreportcard.com/badge/github.com/Tidra/EasyGetProxy?style=flat-square">
</a>
<a href="https://github.com/Tidra/EasyGetProxy/blob/main/LICENSE">
<img alt="GitHub License" src="https://img.shields.io/github/license/Tidra/EasyGetProxy">
</a>
<a href="https://goreportcard.com/report/github.com/Tidra/EasyGetProxy">
<img alt="GitHub Actions Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Tidra/EasyGetProxy/release.yml">
</a>
<a href="https://github.com/Tidra/EasyGetProxy/releases">
<img src="https://img.shields.io/github/release/Tidra/EasyGetProxy/all.svg?style=flat-square">
</a>
Expand All @@ -28,36 +34,162 @@

## 待办

- [x] 提供surge配置文件
- [] 从数据库读取缓存信息
- [] 增加信息源获取方式
- [] 提供surge配置文件
- [] 更改网页页面
- [] snell、vless支持
- [x] 提供ss、ssr、vmess、sip002订阅
- [x] docker构建

## 安装

### 从源码编译
### 1. 从源码编译

需要 [安装 Golang](https://golang.org/doc/install) , 然后拉取代码,
需要 [安装 Golang](https://golang.org/doc/install) , 然后拉取代码

```bash
go get -u -v github.com/Tidra/EasyGetProxy@latest
```

或者,拉取代码的另一种方式
```
```bash
git clone https://github.com/Tidra/EasyGetProxy.git
cd EasyGetProxy
go get
go build
```
then edit `config/config.yaml` and `config/source.yaml` and run it
```

修改 `config/config.yaml``config/source.yaml` 后运行
```bash
./EasyGetProxy -c ./config/config.yaml
```
或者从源代码运行
```
```bash
go run main.go -c ./config/config.yaml
```

### 2. 下载预编译程序

[git releases页下载](https://github.com/Tidra/EasyGetProxy/releases) 预编译程序,需要指定 `config.yaml` 配置文件或者在同目录下创建 `config/config.yaml`

### 3. docker安装

运行下面命令下载 EasyGetProxy 镜像
```bash
docker pull ghcr.io/tidra/easygetproxy:latest
```

下载 `config.yaml``source.yaml``${config_path}`
```bash
wget -P ${config_path} https://raw.githubusercontent.com/Tidra/EasyGetProxy/main/config/config.yaml
wget -P ${config_path} https://raw.githubusercontent.com/Tidra/EasyGetProxy/main/config/source.yaml
```
然后运行 EasyGetProxy 即可
```bash
docker run -d --restart=always \
--name=easygetproxy \
-p 12580:12580 \
-v ${config_path}:/config \
ghcr.io/tidra/easygetproxy:latest \
-c ${config_path}/config.yaml
```

> 使用 `-p` 参数映射配置文件里的端口
> 使用 `-v` 参数指定配置文件夹位置(配置文件要自行下载放到目录,方便修改)
> 使用 `-c` 参数指定配置文件路径,支持http链接
## 使用说明

### 1. 外置参数

目前只保留设置 `配置文件` 参数,可使用以下两种方法设置
1. 直接用 `-c` 调用
```bash
./EasyGetProxy -c ./config/config.yaml
```
2. 配置环境变量
```bash
# 配置在环境变量文件或直接执行
export CONFIG_FILE=${file_path}

# 执行程序
./EasyGetProxy
```

### 2. 配置文件 `config.yaml`

> 配置文件需要为yaml格式文件
配置文件主要如下参数
```yaml
# ======= 留空使用default值 ======= #
# ==== 日志相关 ==== #
log:
console-level: # default info
file-level: # default no log file
file-path: # default log/run.log

# ==== 网页相关 ==== #
web:
domain: example.com:12580 # or example.com:9443 for reserve proxy server
port: # default 12580

# ==== 代理源配置文件 ==== #
source-files:
# use local file
- config/source.yaml
# use web file
# - https://example.com/config/source.yaml

# ==== 爬取设置 ==== #
crawl-interval: # default 60 (minutes)
healthcheck:
url: # default http://www.gstatic.com/generate_204
timeout: # default 5 (seconds)
max-conn: # default 500. The number of health check connections simultaneously

# ==== 测速相关 ==== #
speedtest:
is_used: true # default false. Warning: this will consume large network resources.
interval: # default 720 (min)
timeout: # default 10 (seconds).
max-conn: # default 5. The number of speed test connections simultaneously
```
### 3. 配置源 `source.yaml`

> 信息源文件需要为yaml格式文件

配置可以为:
1. V2ray、SSR、SS、Trojan、clash等订阅链接或文件
2. vmess、ss、ssr、trojan等节点信息
3. 网页中的节点或订阅信息

```yaml
# clash节点信息
- type: clash
options:
url: https://xxxxx/xxxx.yaml # 也可以是文件路径
# 订阅节点
- type: subscribe
options:
url: https://xxxxx/xxxx..txt # 也可以是文件路径
- type: crawl
options:
url: https://xxxx.org
subs:
- type: url # 子链接
xpath: //div[2]/h2/a # 链接对应的xpath
subs:
- type: subscribe # 订阅节点链接
xpath: //div/p[1] # 对应的xpath
- type: clash # clash订阅链接
xpath: //div/p[2] # 对应的xpath
- type: fuzzy # 模糊匹配xpath下所有的节点信息,与url同级,所以是https://xxxx.org下的内容
xpath: //div/div/pre/code # 对应的xpath
```

## 致谢

- [ssrlive/proxypool](https://github.com/ssrlive/proxypool)
Expand Down
8 changes: 5 additions & 3 deletions unit/check/var.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package check

import "time"

const retryInterval = time.Second * 1
const maxRetryGet = 3
const downloadSize = 100
const (
retryInterval = time.Second * 1
maxRetryGet = 3
downloadSize = 100
)
9 changes: 2 additions & 7 deletions unit/getter/clash.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package getter

import (
"io"
"sync"

"github.com/Tidra/EasyGetProxy/unit/log"
Expand All @@ -19,12 +18,8 @@ type Clash struct {

// Get implements Getter.
func (c *Clash) Get() proxy.ProxyList {
resp, err := tool.GetHttpClient().Get(c.Url)
if err != nil {
return nil
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
// 支持链接以及本地文件
body, err := tool.ReadFile(c.Url)
if err != nil {
return nil
}
Expand Down
9 changes: 2 additions & 7 deletions unit/getter/subscribe.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package getter

import (
"io"
"strings"
"sync"

Expand All @@ -20,12 +19,8 @@ type Subscribe struct {

// Get implements Getter.
func (s *Subscribe) Get() proxy.ProxyList {
resp, err := tool.GetHttpClient().Get(s.Url)
if err != nil {
return nil
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
// 支持链接以及本地文件
body, err := tool.ReadFile(s.Url)
if err != nil {
return nil
}
Expand Down
90 changes: 66 additions & 24 deletions unit/proxy/clash.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,30 +101,52 @@ func ExplodeClash(clash string) (ProxyList, error) {
case "ss":
cipher = tool.SafeAsString(singleProxy, "cipher")
password = tool.SafeAsString(singleProxy, "password")
pluginOpts := new(PluginOpts)
// pluginOpts := new(PluginOpts)
pluginOpts := ""

if singleProxy["plugin"] != nil {
switch tool.SafeAsString(singleProxy, "plugin") {
case "obfs":
plugin = "obfs-local"
if singleProxy["plugin-opts"] != nil {
pluginOpts.Mode = tool.SafeAsString(singleProxy, "plugin-opts", "mode")
pluginOpts.Host = tool.SafeAsString(singleProxy, "plugin-opts", "host")
pluginOpts = "obfs=" + tool.SafeAsString(singleProxy, "plugin-opts", "mode")
if host := tool.SafeAsString(singleProxy, "plugin-opts", "host"); host != "" {
pluginOpts += ";obfs-host=" + host
}
// pluginOpts.Mode = tool.SafeAsString(singleProxy, "plugin-opts", "mode")
// pluginOpts.Host = tool.SafeAsString(singleProxy, "plugin-opts", "host")
}
case "v2ray-plugin":
plugin = "v2ray-plugin"
if singleProxy["plugin-opts"] != nil {
pluginOpts.Mode = tool.SafeAsString(singleProxy, "plugin-opts", "mode")
pluginOpts.Host = tool.SafeAsString(singleProxy, "plugin-opts", "host")
pluginOpts.Tls = tool.SafeAsBool(singleProxy, "plugin-opts", "host")
pluginOpts.Path = tool.SafeAsString(singleProxy, "plugin-opts", "path")
pluginOpts.Mux = tool.SafeAsBool(singleProxy, "plugin-opts", "mux")
pluginOpts = "obfs=" + tool.SafeAsString(singleProxy, "plugin-opts", "mode")
if tool.SafeAsBool(singleProxy, "plugin-opts", "tls") {
pluginOpts += ";tls"
}
if host := tool.SafeAsString(singleProxy, "plugin-opts", "host"); host != "" {
pluginOpts += ";host=" + host
}
if path := tool.SafeAsString(singleProxy, "plugin-opts", "path"); path != "" {
pluginOpts += ";path=" + path
}
if tool.SafeAsBool(singleProxy, "plugin-opts", "mux") {
pluginOpts += ";mux=4"
}
// pluginOpts.Mode = tool.SafeAsString(singleProxy, "plugin-opts", "mode")
// pluginOpts.Host = tool.SafeAsString(singleProxy, "plugin-opts", "host")
// pluginOpts.Tls = tool.SafeAsBool(singleProxy, "plugin-opts", "tls")
// pluginOpts.Path = tool.SafeAsString(singleProxy, "plugin-opts", "path")
// pluginOpts.Mux = tool.SafeAsBool(singleProxy, "plugin-opts", "mux")
}
}
} else if singleProxy["obfs"] != nil {
plugin = "obfs-local"
pluginOpts.Mode = tool.SafeAsString(singleProxy, "obfs")
pluginOpts.Host = tool.SafeAsString(singleProxy, "obfs-host")
pluginOpts = "obfs=" + tool.SafeAsString(singleProxy, "plugin-opts", "mode")
if host := tool.SafeAsString(singleProxy, "plugin-opts", "host"); host != "" {
pluginOpts += ";obfs-host=" + host
}
// pluginOpts.Mode = tool.SafeAsString(singleProxy, "obfs")
// pluginOpts.Host = tool.SafeAsString(singleProxy, "obfs-host")
}

//support for go-shadowsocks2
Expand Down Expand Up @@ -201,22 +223,42 @@ func ProxieToClash(node Proxy) map[string]any {
// TODO: 判断协议是否符合
clashNode["cipher"] = node.EncryptMethod
clashNode["password"] = node.Password
clashNode["plugin"] = node.Plugin
if node.PluginOption.Path != "" || node.PluginOption.Tls || node.PluginOption.SkipCertVerify || node.PluginOption.Mux {
clashNode["plugin-opts"] = map[string]interface{}{
"mode": node.PluginOption.Mode,
"host": node.PluginOption.Host,
"tls": node.PluginOption.Tls,
"path": node.PluginOption.Path,
"skip-cert-verify": node.PluginOption.SkipCertVerify,
"mux": node.PluginOption.Mux,
}
} else {
clashNode["plugin-opts"] = map[string]interface{}{
"mode": node.PluginOption.Mode,
"host": node.PluginOption.Host,
pluginString := strings.ReplaceAll(node.PluginOption, ";", "&")
switch node.Plugin {
case "simple-obfs", "obfs-local":
clashNode["plugin"] = "obfs"
pluginOpts := make(map[string]interface{})
pluginOpts["mode"] = tool.GetUrlArg(pluginString, "obfs")
pluginOpts["host"] = tool.GetUrlArg(pluginString, "obfs-host")
clashNode["plugin-opts"] = pluginOpts
case "v2ray-plugin":
clashNode["plugin"] = "v2ray-plugin"
pluginOpts := make(map[string]interface{})
pluginOpts["mode"] = tool.GetUrlArg(pluginString, "mode")
pluginOpts["host"] = tool.GetUrlArg(pluginString, "host")
pluginOpts["path"] = tool.GetUrlArg(pluginString, "path")
pluginOpts["tls"] = strings.Contains(pluginString, "tls")
pluginOpts["mux"] = strings.Contains(pluginString, "mux")
if node.SkipCertVerify {
pluginOpts["skip-cert-verify"] = node.SkipCertVerify
}
clashNode["plugin-opts"] = pluginOpts
}
// if node.PluginOption.Path != "" || node.PluginOption.Tls || node.PluginOption.SkipCertVerify || node.PluginOption.Mux {
// clashNode["plugin-opts"] = map[string]interface{}{
// "mode": node.PluginOption.Mode,
// "host": node.PluginOption.Host,
// "tls": node.PluginOption.Tls,
// "path": node.PluginOption.Path,
// "skip-cert-verify": node.PluginOption.SkipCertVerify,
// "mux": node.PluginOption.Mux,
// }
// } else {
// clashNode["plugin-opts"] = map[string]interface{}{
// "mode": node.PluginOption.Mode,
// "host": node.PluginOption.Host,
// }
// }
case "vmess":
clashNode["uuid"] = node.UUID
clashNode["alterId"] = node.AlterID
Expand Down
Loading

0 comments on commit 6023ef3

Please sign in to comment.