ab81e081004fa4f04ab0a992ec39b7f4bc229d2d
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 30s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 47s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 47s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 1m3s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 58s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 51s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m6s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 50s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 59s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 51s
GoTunnel
一个轻量级、高性能的内网穿透工具,采用服务端集中化管理模式,支持 TLS 加密通信。
项目简介
GoTunnel 是一个类似 frp 的内网穿透解决方案,核心特点是服务端集中管理配置和零配置 TLS 加密。客户端只需提供认证信息即可自动获取映射规则,无需在客户端维护复杂配置。
与 frp 的主要区别
| 特性 | GoTunnel | frp |
|---|---|---|
| 配置管理 | 服务端集中管理 | 客户端各自配置 |
| TLS 证书 | 自动生成,零配置 | 需手动配置 |
| 管理界面 | 内置 Web 控制台 (naive-ui) | 需额外部署 Dashboard |
| 客户端部署 | 仅需 2 个参数 | 需配置文件 |
| 客户端 ID | 可选,服务端自动分配 | 需手动配置 |
架构设计
┌──────────────┐ ┌──────────────────────┐
│ Client │ Control Channel │ Server │
│ │ ◄────────────────►│ │
│ ┌────────┐ │ (Yamux Mux) │ ┌────────────────┐ │
│ │ Agent │ │ │ │ Control Manager│ │
│ └────────┘ │ │ └────────────────┘ │
│ │ │ │ │ │
│ ▼ │ Data Streams │ ▼ │
│ ┌────────┐ │ ◄────────────────►│ ┌────────────────┐ │
│ │ Proxy │ │ │ │ Proxy Listener │ │
│ └────────┘ │ │ │ :8080,:9090 │ │
│ │ │ │ └────────────────┘ │
│ ▼ │ │ ▲ │
│ ┌────────┐ │ │ │ │
│ │Local:80│ │ │ External Users │
│ └────────┘ │ │ │
└──────────────┘ └──────────────────────┘
功能特性
核心功能
- 服务端集中管理 - 所有客户端的映射规则由服务端统一配置,客户端零配置
- 多路复用 - 基于 Yamux 实现控制通道与数据通道分离,高效复用单一 TCP 连接
- 多客户端支持 - 支持多个客户端同时连接,每个客户端独立的映射规则
- 端口冲突检测 - 自动检测系统端口占用和客户端间端口冲突
- SOCKS5/HTTP 代理 - 支持通过客户端网络访问任意网站
安全性
- TLS 加密 - 默认启用 TLS 加密,证书自动生成,零配置
- Token 认证 - 基于 Token 的身份验证机制
- 客户端白名单 - 仅配置的客户端 ID 可以连接
可靠性
- 心跳检测 - 可配置的心跳间隔和超时时间,及时发现断线
- 断线重连 - 客户端自动重连机制,网络恢复后自动恢复服务
- 优雅关闭 - 客户端断开时自动释放端口资源
Web 管理
- Web 控制台 - 内置 Web 管理界面,可视化管理客户端和规则
- 实时状态 - 查看客户端在线状态
- 动态配置 - 在线添加/修改客户端规则
快速开始
安装
从源码编译:
git clone https://github.com/your-repo/gotunnel.git
cd gotunnel
go build -o server ./cmd/server
go build -o client ./cmd/client
下载预编译二进制:
从 Releases 页面下载对应平台的二进制文件。
服务端启动
# 零配置启动(自动生成 Token,启用 TLS 和 Web 控制台)
./server
# 或指定配置文件
./server -c server.yaml
首次启动会自动:
- 生成随机 Token(打印在日志中)
- 启用 TLS 加密(证书在内存中自动生成)
- 启动 Web 控制台(默认 http://localhost:7500)
- 创建 SQLite 数据库存储客户端配置
客户端启动
# 最简启动(ID 由服务端自动分配)
./client -s <服务器IP>:7000 -t <Token>
# 指定客户端 ID
./client -s <服务器IP>:7000 -t <Token> -id <客户端ID>
# 禁用 TLS(需服务端也禁用)
./client -s <服务器IP>:7000 -t <Token> -no-tls
参数说明:
| 参数 | 说明 | 必填 |
|---|---|---|
-s |
服务器地址 (ip:port) | 是 |
-t |
认证 Token | 是 |
-id |
客户端 ID | 否(服务端自动分配) |
-no-tls |
禁用 TLS 加密 | 否 |
配置系统
服务端使用 YAML 配置文件 + SQLite 数据库管理。YAML 配置服务端参数,SQLite 存储客户端规则。
配置文件示例
# server.yaml
server:
bind_addr: "0.0.0.0" # 监听地址
bind_port: 7000 # 监听端口
token: "your-secret-token" # 认证 Token(不配置则自动生成)
heartbeat_sec: 30 # 心跳间隔(秒)
heartbeat_timeout: 90 # 心跳超时(秒)
db_path: "gotunnel.db" # 数据库路径
tls_disabled: false # 是否禁用 TLS(默认启用)
web:
enabled: true # 启用 Web 控制台
bind_addr: "0.0.0.0"
bind_port: 7500
username: "admin" # 可选,设置后启用认证
password: "password"
配置参数说明
Server 配置:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
bind_addr |
string | 0.0.0.0 | 服务端监听地址 |
bind_port |
int | 7000 | 服务端监听端口 |
token |
string | 自动生成 | 客户端认证 Token |
heartbeat_sec |
int | 30 | 心跳发送间隔(秒) |
heartbeat_timeout |
int | 90 | 心跳超时时间(秒) |
db_path |
string | gotunnel.db | SQLite 数据库路径 |
tls_disabled |
bool | false | 是否禁用 TLS |
Web 配置:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled |
bool | true | 是否启用 Web 控制台 |
bind_addr |
string | 0.0.0.0 | Web 监听地址 |
bind_port |
int | 7500 | Web 监听端口 |
username |
string | - | 认证用户名(可选) |
password |
string | - | 认证密码(可选) |
代理规则类型
通过 Web 控制台配置客户端规则时,支持以下类型:
内置类型
| 类型 | 说明 | 示例用途 |
|---|---|---|
tcp |
TCP 端口转发(默认) | SSH、MySQL、Web 服务 |
udp |
UDP 端口转发 | DNS、游戏服务器、VoIP |
http |
HTTP 代理 | 通过客户端网络访问 HTTP/HTTPS |
https |
HTTPS 代理 | 同 HTTP,支持 CONNECT 方法 |
插件类型
| 类型 | 说明 | 示例用途 |
|---|---|---|
socks5 |
SOCKS5 代理(官方插件) | 通过客户端网络访问任意地址 |
规则配置示例(通过 Web API):
{
"id": "client-a",
"nickname": "办公室电脑",
"rules": [
{"name": "web", "type": "tcp", "local_ip": "127.0.0.1", "local_port": 80, "remote_port": 8080},
{"name": "dns", "type": "udp", "local_ip": "127.0.0.1", "local_port": 53, "remote_port": 5353},
{"name": "socks5-proxy", "type": "socks5", "remote_port": 1080},
{"name": "http-proxy", "type": "http", "remote_port": 8888}
]
}
项目结构
GoTunnel/
├── cmd/
│ ├── server/main.go # 服务端入口
│ └── client/main.go # 客户端入口
├── internal/
│ ├── server/
│ │ ├── tunnel/ # 隧道服务
│ │ ├── config/ # 配置管理
│ │ ├── db/ # 数据库存储
│ │ ├── app/ # Web 服务
│ │ └── router/ # API 路由
│ └── client/
│ └── tunnel/ # 客户端隧道
├── pkg/
│ ├── protocol/ # 通信协议
│ ├── crypto/ # TLS 加密
│ ├── proxy/ # 代理服务器
│ ├── relay/ # 数据转发
│ ├── auth/ # JWT 认证
│ ├── utils/ # 工具函数
│ └── plugin/ # 插件系统核心
│ ├── builtin/ # 内置插件 (socks5)
│ ├── wasm/ # WASM 运行时 (wazero)
│ └── store/ # 插件持久化 (SQLite)
├── web/ # Vue 3 + naive-ui 前端
├── scripts/ # 构建脚本
│ └── build.sh # 跨平台构建脚本
└── go.mod
插件系统
GoTunnel 支持基于 WASM 的插件系统,可扩展代理协议支持。
架构设计
- 内置类型: tcp, udp, http, https 直接在 tunnel 代码中处理,无需插件
- 官方插件: SOCKS5 作为官方插件提供
- WASM 插件: 自定义插件可通过 wazero 运行时动态加载
- 混合分发: 内置插件离线可用;WASM 插件可从服务端下载
开发自定义插件
插件需实现 ProxyHandler 接口:
type ProxyHandler interface {
Metadata() PluginMetadata
Init(config map[string]string) error
HandleConn(conn net.Conn, dialer Dialer) error
Close() error
}
参考实现:pkg/plugin/builtin/socks5.go
Web API
Web 控制台提供 RESTful API 用于管理客户端和配置。配置了 username 和 password 后,API 需要 JWT 认证。
认证
# 登录获取 Token
POST /api/auth/login
Content-Type: application/json
{"username": "admin", "password": "password"}
# 响应
{"token": "eyJhbGciOiJIUzI1NiIs..."}
# 后续请求携带 Token
Authorization: Bearer <token>
客户端管理
# 获取所有客户端
GET /api/clients
# 获取单个客户端
GET /api/client/{id}
# 更新客户端(昵称和规则)
PUT /api/client/{id}
Content-Type: application/json
{"nickname": "办公室电脑", "rules": [...]}
# 删除客户端
DELETE /api/client/{id}
客户端控制
# 推送配置到在线客户端(客户端会立即应用新规则)
POST /api/client/{id}/push
# 断开客户端连接
POST /api/client/{id}/disconnect
插件管理
# 获取已注册的插件列表
GET /api/plugins
# 响应示例
[
{
"name": "socks5",
"version": "1.0.0",
"description": "SOCKS5 proxy plugin",
"source": "builtin"
}
]
服务状态
# 获取服务状态
GET /api/status
# 获取配置
GET /api/config
# 更新配置
PUT /api/config
Content-Type: application/json
{"server": {"heartbeat_sec": 30}, "web": {"enabled": true}}
# 重载配置
POST /api/config/reload
使用场景
场景一:暴露内网 Web 服务
# 服务端配置客户端规则(通过 Web 控制台或 API)
curl -X POST http://server:7500/api/clients \
-H "Content-Type: application/json" \
-d '{"id":"home","rules":[{"name":"web","type":"tcp","local_ip":"127.0.0.1","local_port":80,"remote_port":8080}]}'
# 客户端连接
./client -s server:7000 -t <token> -id home
# 访问:http://server:8080 -> 内网 127.0.0.1:80
场景二:SOCKS5 代理访问内网
# 配置 SOCKS5 代理规则
{"name":"proxy","type":"socks5","remote_port":1080}
# 使用代理
curl --socks5 server:1080 http://internal-service/
常见问题
Q: 客户端连接后如何设置昵称?
A: 在 Web 控制台点击客户端详情,进入编辑模式即可设置昵称。
Q: 如何禁用 TLS?
A: 服务端配置 tls_disabled: true,客户端使用 -no-tls 参数。
Q: 端口被占用怎么办?
A: 服务端会自动检测端口冲突,请检查日志并更换端口。
Q: 客户端 ID 是如何分配的?
A: 如果客户端未指定 -id 参数,服务端会自动生成 16 位随机 ID。
构建
使用构建脚本可以一键构建前后端:
# 构建当前平台
./scripts/build.sh current
# 构建所有平台
./scripts/build.sh all
# 仅构建 Web UI
./scripts/build.sh web
# 清理构建产物
./scripts/build.sh clean
# 指定版本号
VERSION=1.0.0 ./scripts/build.sh all
构建产物输出到 build/<os>_<arch>/ 目录。
架构时序图
1. 连接建立阶段
┌────────┐ ┌────────┐ ┌──────────┐
│ Client │ │ Server │ │ Database │
└───┬────┘ └───┬────┘ └────┬─────┘
│ │ │
│ 1. TCP/TLS Connect│ │
│──────────────────>│ │
│ │ │
│ 2. AuthRequest │ │
│ {token, id?} │ │
│──────────────────>│ │
│ │ 3. 验证 Token │
│ │ 4. 查询/创建客户端 │
│ │───────────────────>│
│ │<───────────────────│
│ │ │
│ 5. AuthResponse │ │
│ {ok, client_id} │ │
│<──────────────────│ │
│ │ │
│ 6. Yamux Session │ │
│<═════════════════>│ │
│ │ │
│ 7. ProxyConfig │ │
│ {rules[]} │ │
│<──────────────────│ │
│ │ │
2. TCP 代理数据流
┌──────────┐ ┌────────┐ ┌────────┐ ┌───────────────┐
│ External │ │ Server │ │ Client │ │ Local Service │
└────┬─────┘ └───┬────┘ └───┬────┘ └───────┬───────┘
│ │ │ │
│ 1. Connect │ │ │
│ :remote │ │ │
│─────────────>│ │ │
│ │ │ │
│ │ 2. Yamux │ │
│ │ Stream │ │
│ │────────────>│ │
│ │ │ │
│ │ 3. NewProxy │ │
│ │ {port} │ │
│ │────────────>│ │
│ │ │ │
│ │ │ 4. Connect │
│ │ │ local:port │
│ │ │────────────────>│
│ │ │ │
│ 5. Relay (双向数据转发) │ │
│<════════════>│<═══════════>│<═══════════════>│
│ │ │ │
3. SOCKS5/HTTP 代理数据流
┌──────────┐ ┌────────┐ ┌────────┐ ┌─────────────┐
│ External │ │ Server │ │ Client │ │ Target Host │
└────┬─────┘ └───┬────┘ └───┬────┘ └──────┬──────┘
│ │ │ │
│ 1. SOCKS5 │ │ │
│ Handshake │ │ │
│─────────────>│ │ │
│ │ │ │
│ │ 2. Proxy │ │
│ │ Connect │ │
│ │ {target} │ │
│ │────────────>│ │
│ │ │ │
│ │ │ 3. Dial target │
│ │ │───────────────>│
│ │ │ │
│ │ 4. Result │ │
│ │<────────────│ │
│ │ │ │
│ 5. Relay (双向数据转发) │ │
│<════════════>│<═══════════>│<══════════════>│
│ │ │ │
4. 心跳保活机制
┌────────┐ ┌────────┐
│ Client │ │ Server │
└───┬────┘ └───┬────┘
│ │
│ │ 1. Ticker (30s)
│ │
│ 2. Heartbeat │
│<──────────────────│
│ │
│ 3. HeartbeatAck │
│──────────────────>│
│ │
│ │ 4. 更新 LastPing
│ │
│ ... 循环 ... │
│ │
│ │ 5. 超时检测 (90s)
│ │ 无响应则断开
│ │
核心组件说明
| 组件 | 职责 |
|---|---|
| Client | 连接服务端、转发本地服务、响应心跳 |
| Server | 认证、管理会话、监听端口、路由流量 |
| Yamux | 单连接多路复用,承载控制和数据通道 |
| Plugin | 处理 SOCKS5/HTTP 等代理协议 |
| PortManager | 端口分配与释放管理 |
| Database | 持久化客户端配置和规则 |
许可证
本项目采用 MIT License 开源许可证。
Languages
Go
72.7%
Vue
19.2%
TypeScript
4%
PowerShell
1.8%
Shell
1.2%
Other
0.9%