# Wormhole

内网穿透 + 反向代理网关，带 Web 管理台。控制面自研（Go + SQLite），数据面支持 HTTP/HTTPS 域名反代、TCP/UDP 隧道与 Agent 长连接。


服务端与 Agent 为**同一应用**，配置均在 Web 管理台完成，无需手写配置文件。管理台支持**简体中文、英文**两种界面语言，可在顶栏随时切换。

## 界面预览

以下为 Web 管理台主要页面（点击可查看原图）。

| 登录 | 监控大盘 |
|:---:|:---:|
| ![登录页](docs/image/登陆页.png) | ![监控大盘](docs/image/概览-仪表盘.png) |
| 默认密码 `admin`，首次登录后请修改 | 流量统计、请求 IP 与资源概览 |

| 客户端 | 隧道 |
|:---:|:---:|
| ![客户端](docs/image/穿透-客户端.png) | ![隧道](docs/image/穿透-隧道.png) |
| Agent 注册、在线状态与 verify_key | TCP/UDP 端口映射、启停与导入导出 |

| 域名反代 | 访客验证 |
|:---:|:---:|
| ![域名反代](docs/image/穿透-域名.png) | ![访客验证](docs/image/访客验证.png) |
| HTTP/HTTPS Host 路由、TLS 与请求头 | Basic / 表单 / 回调，资源级访问控制 |

| IP 规则 | 请求 IP |
|:---:|:---:|
| ![IP 规则](docs/image/安全-IP规则.png) | ![请求 IP](docs/image/安全-请求IP.png) |
| 精确 / CIDR / 正则白黑名单 | 访客 IP 监控、一键拉黑 |

| 访客用户 | 系统设置 |
|:---:|:---:|
| ![访客用户](docs/image/系统-访客用户.png) | ![系统设置](docs/image/系统-系统设置.png) |
| 受保护资源的访客账号管理 | 端口、认证、JWT、导入导出 |

## 功能概览

| 模块 | 说明 |
|------|------|
| 客户端 | Agent 注册、在线状态、verify_key 管理 |
| 隧道 | TCP/UDP 端口映射，支持访客登录与导入导出 |
| 域名反代 | HTTP/HTTPS Host 路由、TLS 证书、代理请求头 |
| 访客验证 | Basic / 表单 / 回调认证，按资源授权访客 |
| IP 安全 | 精确 / CIDR / 正则白黑名单，请求 IP 监控与一键拉黑 |
| 监控大盘 | 流量统计、Top 请求 IP、资源与隧道概览 |
| 系统设置 | 监听端口、JWT、登录限流、数据导入导出 |
| OpenAPI | 仪表盘可打开 `/api/openapi.json` |

## 架构

```
公网用户 → HTTP/HTTPS 反代 (8081/8443) ──→ 后端服务 / Agent 隧道
                    ↑
            Agent Bridge (8528) ←── 内网 Agent（smux 长连接）
                    ↑
         Wormhole 控制面 (REST API + Vue UI :8529)
                    ↓
            SQLite + 内存缓存
```

## 快速开始（开发）

### 依赖

- Go 1.24+（见 `go.mod`）
- Node.js 20+（仅开发/构建前端）

依赖镜像（已写入 `go.env`、`web/.npmrc`，国内网络友好）：

- Go：`GOPROXY=https://goproxy.cn,direct`
- npm：`registry=https://registry.npmmirror.com`

海外用户可将 `GOPROXY` 改为 `https://proxy.golang.org,direct`，npm 使用默认 registry 即可。

### 启动

```bash
make install   # 安装前端依赖

# 终端 1：后端
make run

# 终端 2：前端（Vite 代理 /api → :8529）
make dev-web
```

访问 http://localhost:5173 ，默认密码 `admin`（**首次登录后请立即修改**）。

```bash
go test ./...  # 运行单元测试
make build     # 构建 bin/wormhole
```

### Agent

在管理台「客户端」页面获取 `verify_key`，于内网机器启动 Agent：

```bash
./bin/wormhole agent -server <服务端IP>:8528 -key <verify_key>
```

## 部署

镜像由 Gitea Actions 自动构建并发布到 Container Registry，**无需自行编译**。直接拉取运行即可。

```bash
docker pull git.rc707blog.top/rose_cat707/wormhole:latest
```

| Tag | 说明 |
|-----|------|
| `latest` | `main` / `master` 分支最新构建 |
| `sha-xxxxxxx` | 对应 commit 短 SHA |
| `v1.2.3` | 推送 Git tag `v1.2.3` 时发布 |

### docker run

```bash
docker pull git.rc707blog.top/rose_cat707/wormhole:latest

# 服务端
docker run -d --name wormhole \
  --restart unless-stopped \
  -p 8529:8529 -p 8528:8528 -p 8081:8081 -p 8443:8443 \
  -v wormhole-data:/app/data \
  git.rc707blog.top/rose_cat707/wormhole:latest

# Agent（同一镜像；与 Server 分开部署）
docker run -d --name wormhole-agent \
  --restart=unless-stopped \
  --network host \
  git.rc707blog.top/rose_cat707/wormhole:latest \
  agent -server <服务端IP>:8528 -key <verify_key>
```

> **注意**：Agent 容器必须与 Server 分开部署。更新 Server 镜像时勿在同一 compose 中重建 Agent；Agent 需 `--restart=unless-stopped`，否则收到 `SIGTERM` 后容器会保持 `Exited` 状态。

### 本地自行构建

```bash
docker build \
  --build-arg IMAGE_PREFIX=docker.1panel.live/library/ \
  --build-arg GOPROXY=https://goproxy.cn,direct \
  -t wormhole:local .
```

**端口（默认）**

| 服务 | 端口 | 说明 |
|------|------|------|
| 管理 API / Web UI | 8529 | 浏览器访问管理台 |
| Agent Bridge | 8528 | 内网 Agent 长连接 |
| HTTP 域名反代 | 8081 | 公网 HTTP 入口 |
| HTTPS 域名反代 | 8443 | 公网 HTTPS 入口（需配置 TLS 证书） |

端口可在管理台「系统设置」中修改；**监听地址变更需重启服务**。

若通过域名 + HTTPS 访问管理台，可在前面加 Nginx/Caddy 反代到 `8529`。**勿将 Agent Bridge 8528 无防护暴露公网**；建议 VPN、IP 白名单或防火墙限制。

## 数据目录

数据默认存储在 `./data/wormhole.db`（SQLite），Docker 部署时挂载为 `/app/data`：

```
data/
└── wormhole.db    # 客户端、隧道、域名、规则、用户、设置
```

可在「系统设置」中导入/导出配置，便于迁移与备份。

## 使用攻略（简要）

### 1. 首次登录

1. 打开 `http://<主机>:8529`
2. 默认账号 `admin` / `admin`，登录后进入「系统设置」修改密码
3. 顶栏切换界面语言（中文 / English）

### 2. 接入 Agent

1. 「客户端」→ 查看或复制 `verify_key`
2. 在内网机器运行 `wormhole agent -server <IP>:8528 -key <verify_key>`
3. 客户端上线后即可创建隧道或域名

### 3. 配置隧道

1. 「隧道」→「新建」，选择客户端、协议（TCP/UDP）与本地目标地址
2. 保存并启动；公网通过 `<服务器IP>:<映射端口>` 访问
3. 可选开启「访客登录」，适用于需认证的 Web 服务

### 4. 配置域名反代

1. 「域名」→「新建」，填写 Host、上游地址与 TLS（可选）
2. DNS 将域名解析到服务器公网 IP
3. 按需配置代理请求头（X-Forwarded-For 等）与访客验证

### 5. IP 安全

1. 「IP 规则」添加白名单 / 黑名单（支持 CIDR、正则）
2. 「请求 IP」查看访客来源，可疑 IP 可一键拉黑
3. 规则可按全局或指定资源（隧道/域名）生效

### 6. API 与自动化

- OpenAPI 规范：`http://<主机>:8529/api/openapi.json`
- 登录获取 Token：`POST /api/auth/login`
- 管理端 API 前缀：`/api`，请求头 `Authorization: Bearer <token>`

### 7. 日常运维

| 操作 | 位置 |
|------|------|
| 查看流量与请求 | 监控大盘 |
| 管理 Agent | 客户端 |
| 启停隧道 / 域名 | 隧道、域名 |
| 导出配置备份 | 系统设置 |
| 修改端口 | 系统设置（需重启） |

## 命令行

| 命令 | 说明 |
|------|------|
| `wormhole server` | 启动服务端（默认 `-data ./data`） |
| `wormhole agent -server <地址> -key <verify_key>` | 启动 Agent |

## 项目结构

```
cmd/wormhole/        # 进程入口（server / agent）
internal/
  api/               # HTTP 层与 OpenAPI
  bridge/            # Agent 长连接与 Bridge
  proxy/             # HTTP/TCP/UDP 反代与隧道
  auth/              # JWT、访客认证、IP 转发
  store/             # SQLite 与仓储
  config/            # 配置模型与默认值
  server/            # 服务编排
web/                 # Vue 3 管理台
  src/i18n/          # 多语言资源
  src/views/         # 页面
docs/
  image/             # README 界面截图
  UI-DESIGN-SYSTEM.md
.gitea/workflows/    # Gitea Actions CI
```

## CI / 镜像发布

推送 `main` / `master` 或 tag `v*` 时，Gitea Actions 构建多架构镜像并推送到 Registry。工作流与 Dockerfile 约定见 [.gitea/README.md](.gitea/README.md)；act_runner 部署参考见 [.gitea/act-runner/](.gitea/act-runner/)。

## 许可

[Wormhole 采用 MIT License](LICENSE)。
