Files
Meshray-Manager/docs/README.md
T
2026-06-30 15:14:37 +08:00

516 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MeshRay - 去中心化 P2P 组网平台
## 项目简介
MeshRay 是一个基于 WireGuard 的去中心化 P2P 组网平台,支持 STUN/TURN 穿透、9 层降级传输策略、Mesh 中继等高级功能。采用 **单进程单端口** 架构部署,ctr 调度中心与 Core 建连层通过直接函数调用集成(无需 gRPC)。
### 核心特性
-**去中心化架构**:无中心服务器,设备间直接 P2P 通信
-**智能穿透**STUN + TURN 自动打洞,支持多种 NAT 类型
-**9 层降级传输**:从 Direct-UDP 到 WS/WSS,链路不通自动切换
-**Mesh 中继**:支持设备间中继转发,突破网络限制
-**安全加密**WireGuard 官方库 + Ed25519 签名 + AES-256-GCM
-**DDNS 动态域名**:支持 Cloudflare、阿里云、腾讯云 DNS 自动同步
-**Web 管理面板**:Go embed 内嵌静态资源,单文件部署
-**完整通知系统**WebSocket 实时推送 + 持久化存储
### 核心术语
| 术语 | 含义 | 说明 |
|------|------|------|
| **ctr** | MeshRay-Control | 调度中心,负责 WG 设备管理和信令中转 |
| **Core** | MeshRay-Core | 建连层,负责点对点传输 |
| **Route ID** | 路由标识 | 派生自 peerKey 的哈希值,用于 Relay 数据转发 |
| **MeshSeed** | 组网凭证 | 加密的组网配置载体(含 NetworkSecret |
| **NetworkID** | 组网 ID | 雪花算法生成的唯一标识(uint64) |
| **Bind** | 绑定接口 | Engine 为 Peer 开启本地监听端口,截获 WG 密文包 |
| **Layer** | 传输层 | 9 种传输协议之一(如 Direct-UDP、TURN-TCP |
| **WG 设备** | WireGuard Interface | wg0/wg1 等虚拟网卡,由 wgctrl 管理 |
| **AllowedIPs** | WG 路由表 | WireGuard 的路由规则,决定哪些流量走 WG 隧道 |
### 快速开始
```bash
# 克隆项目
git clone https://git.zkcoi.com/zkcoi/meshray.git
# 安装 Go 依赖
go mod download
# 直接编译运行
go build -o meshray.exe ./cmd/meshray
./meshray.exe
# 访问管理后台
http://localhost:9531
```
> **注意**:前端已内嵌到 Go 二进制中,无需单独编译前端或安装 Node.js。
---
## 核心架构
### 项目目录结构
```
meshray/
├── cmd/ # 可执行文件入口
│ ├── meshray/ # 主程序(Windows 服务 + 系统托盘)
│ ├── checkdb/ # 数据库检查工具
│ ├── reset-password/ # 管理员密码重置工具
│ └── testembed/ # Embed 测试工具
├── core/ # MeshRay-Core 模块(建连层)
│ ├── connect/ # 9 层传输工厂
│ │ ├── strategy.go # 策略调度器
│ │ ├── direct.go # Direct-UDP 直连
│ │ ├── fake_tcp.go # FakeTCP 连接实现
│ │ ├── real_tcp.go # RealTCP 连接实现
│ │ ├── turn.go # TURN 客户端(UDP/TCP/TLS
│ │ ├── turn_quic.go # TURN-QUIC 扩展
│ │ ├── stun.go # STUN 探测
│ │ ├── ice.go # ICE 协商(WebRTC
│ │ └── ws.go # WebSocket 客户端
│ ├── transport/ # 传输层
│ │ ├── conn_manager.go # Peer 连接管理器
│ │ ├── relay.go # 数据转发器(本地端口 ↔ 远端)
│ │ └── plugin.go # ProtocolPlugin 接口
│ ├── plugins/wg/ # WireGuard 插件实现
│ │ └── wgparse.go # WG 协议解析
│ ├── core.go # Core 主实例(管理多个 Engine
│ ├── engine.go # Engine 引擎(一个组网一个实例)
│ └── metrics.go # 监控指标采集
├── internal/ # 内部实现(不对外暴露)
│ ├── api/ # REST API 层
│ │ ├── handler/ # API 处理器
│ │ ├── middleware/ # 中间件(JWT 认证、CORS、日志)
│ │ ├── dto/ # 数据传输对象
│ │ ├── api.go # API 包定义
│ │ └── server.go # Gin 服务器(路由注册、静态文件服务)
│ ├── ctr/ # MeshRay-Control(调度中心)
│ │ ├── ctr.go # 调度中心主逻辑
│ │ ├── interface.go # WG 接口管理
│ │ └── wg.go # WireGuard CLI 封装
│ ├── config/ # 配置管理(Viper + 自动生成密钥)
│ │ └── config.go # Config 结构体 + Load 函数
│ ├── dnsprovider/ # DNS Provider 抽象(Cloudflare/阿里云/腾讯云)
│ ├── handler/ # 通用处理器(备份、DDNS 统计、通知、更新)
│ ├── logging/ # 日志系统(Zap 封装)
│ ├── model/ # 数据模型(GORM 定义)
│ ├── scheduler/ # 后台任务调度(DDNS 自动更新)
│ ├── service/ # 业务逻辑层
│ ├── store/ # 数据库访问层(SQLite)
│ └── tray/ # 系统托盘(Windows 交互模式)
├── pkg/ # 公共工具库(可复用)
│ ├── idutil/ # 雪花算法 ID 生成
│ ├── meshseed/ # MeshSeed 加密/签名
│ └── shortid/ # 短 ID 编码器
├── web/ # 前端静态资源
│ ├── embed.go # Go embed 定义(`//go:embed all:static`
│ └── static/ # 静态文件目录
│ ├── index.html # SPA 入口
│ └── js/app.js # 前端应用
├── config.yaml # 运行配置文件(自动生成)
├── configs/
│ └── config.example.yaml # 配置示例模板
├── deploy/ # 部署相关
│ ├── docker/ # Docker 镜像构建
│ ├── scripts/ # 安装脚本
│ └── systemd/ # Systemd 服务单元
└── docs/ # 技术文档
├── README.md # 项目介绍(本文档)
├── QUICKSTART.md # 快速入门指南
├── ARCHITECTURE.md # 架构详解
└── ...
```
**模块职责**
| 目录 | 作用 | 是否对外暴露 |
|------|------|-------------|
| **cmd/** | 可执行文件入口 | ✅ 是(编译产物) |
| **core/** | 建连层核心逻辑 | ❌ 否(内部使用) |
| **internal/** | 业务逻辑实现 | ❌ 否(Go 约定) |
| **pkg/** | 公共工具库 | ✅ 是(可复用) |
| **web/** | 前端静态资源(内嵌) | ❌ 否(构建到二进制) |
---
### 架构总览
MeshRay 采用三层架构:
```
┌─────────────────────────────────────────────┐
│ Web UI(静态 HTML/JS
└────────────────┬────────────────────────────┘
│ REST API / WebSocket
┌────────────────▼────────────────────────────┐
│ API HandlerGin 接入层) │
│ - JWT 认证中间件 │
│ - 路由注册 │
└────────────────┬────────────────────────────┘
│ 函数调用
┌────────────────▼────────────────────────────┐
│ Service Layer(业务层) │
│ - NetworkService / DeviceService │
│ - DDNSService / PolicyService │
│ - UserService / SettingsService │
│ - NotificationService / BackupService │
└────────┬──────────────────┬─────────────────┘
│ │ 函数调用(直接集成,无 gRPC)
┌────────▼──────┐ ┌──────▼─────────────────┐
│ Store Layer │ │ meshray-ctr (调度中心) │
│ (SQLite) │ │ │
│ │ │ ┌──────────────────┐ │
│ │ │ │ wgctrl 管理 WG 设备│ │
│ │ │ └──────────────────┘ │
│ │ │ │
│ │ │ ┌──────────────────┐ │
│ │ │ │ Core (建连层) │ │
│ │ │ │ Engine → 9 层策略 │ │
│ │ │ │ ConnManager + Relay│ │
│ │ │ └──────────────────┘ │
│ │ │ │
│ │ │ ┌──────────────────┐ │
│ │ │ │ Core 集成在 ctr │ │
│ │ │ │ 进程中直接调用 │ │
│ │ │ └──────────────────┘ │
│ │ │ │
│ │ │ ⚡ 直接函数调用 │
│ │ │ 无需 gRPC 通信 │
│ │ │ 无网络开销 │
│ └───┘ │
└────────────────────────────────────────────┘
```
**职责边界**
| 组件 | 做什么 | 不做什么 |
|------|--------|---------|
| **ctr** | 调度 WG 设备、控制面信令中转(通过数据库)、读写数据库 | 不碰数据面、不做建连/传输 |
| **Core** | 数据面直连、建连、策略调度、Bind 端口转发 | 不读数据库、不依赖 internal/、不管路由决策 |
| **wgctrl** | 管理 WireGuard 设备(增删 Peer、改 Endpoint) | 不负责建立连接、不处理 NAT 穿透 |
---
## 关键机制
### 1. 雪花算法 ID 生成
所有主键使用雪花算法(Snowflake)生成 uint64 ID
- **结构**1bit 符号 + 41bits 时间戳 + 10bits 节点 ID + 12bits 序列号
- **前端精度问题**:JavaScript 无法精确表示超大数字,框架层自动处理
- **实现**`pkg/idutil/snowflake.go`
### 2. Engine.Bind 模型 - 9 层传输的核心
Engine 为每个 Peer 开启一个本地 UDP 监听端口,通过 `Bind()` 方法注册到 Relay
```
WG 加密包 → Engine.Bind() 监听本地端口 → Relay 提取 Route ID → 选择链路 → 发送
Direct-UDP → FakeTCP → RealTCP → TURN-UDP → ...
```
**流程**
1. `engine.Bind(peerKey, port)` → 监听 `127.0.0.1:port`
2. `relay.RegisterLocalPort(routeID, conn)` → 注册到转发器
3. WG 将 Peer 的 Endpoint 设为 `127.0.0.1:port`(回环地址)
4. WG 发出的密文包被本地端口截获 → Relay 处理 → 策略调度器选择最优传输层发送
### 3. 9 层传输策略
```
性能好(穿透力弱) 穿透力强(兜底)
Direct-UDP → FakeTCP → RealTCP → TURN-UDP → TURN-TCP → TURN-TLS → WebRTC → WS/WSS
```
**三种使用模式**
- **自动切换**(默认):按优先级自动尝试
- **自定义策略**:用户自定义顺序
- **手动指定**:强制使用单一链路
### 4. Mesh 中继
Mesh 中继是 **WG 设备层的静态路由拓扑配置**
- ctr 通过 wgctrl 配置中继节点的 AllowedIPs
- WG 设备自身负责解密 → 路由 → 重加密 → 转发
- **Core 对中继行为完全无感知**,只负责点对点传输
**系统要求**Linux 需开启 `ip_forward=1` 和 iptables NAT
### 5. ExternalService 服务管理
统一管理所有外部依赖服务,通过 `category` + `serviceType` + JSON Config 实现:
| 服务类型 | 用途 | 示例 |
|---------|------|------|
| STUN | NAT 地址探测 | stun.l.google.com:19302 |
| TURN | 中继转发(UDP/TCP/TLS | turn.example.com:3478 |
| DDNS | 动态域名解析 | Cloudflare / 阿里云 / 腾讯云 |
| TUN | 虚拟网卡服务 | 自定义隧道 |
**数据模型**`model.Service`(轻量级统一结构,JSON Config 扩展)
---
## MeshSeed 机制
MeshSeed 是组网的统一凭证载体,一套参数同时支持:新设备加入、旧设备同步、全链路鉴权。
### 数据结构
```go
type MeshSeed struct {
NetworkName string // 组网名称
NetworkSecret string // 高熵密钥(派生 NetworkID,绝不公开)
Subnet string // CIDR 格式,如 10.0.0.0/24
IssuerNodeID string // 签发者节点 IDEd25519 公钥)
// 自动生成
SeedID string // 16 字节随机 Base64
NetworkID uint64 // 雪花算法 ID
Signature []byte // Ed25519 签名(内层签名)
IssuedAt time.Time // 签发时间
ExpiresAt time.Time // 过期时间
}
```
### 双层安全机制
| 层次 | 算法 | 作用 |
|------|------|------|
| **外层加密** | AES-256-GCM | 保证机密性(DDNS 存储时加密) |
| **内层签名** | Ed25519 | 保证完整性与来源(防篡改) |
### DDNS TXT 记录格式
```
_meshray.home.example.com. IN TXT "meshray-ddns:<base64(nonce + ciphertext)>"
```
---
## 数据模型
### 核心表
| 表名 | 说明 | 核心字段 |
|------|------|---------|
| **networks** | 组网配置 | ID, Name, Subnet, Mode, PolicyID, DDNSEnabled |
| **devices** | 设备信息 | ID, NetworkID, PublicKey, Endpoint, Status |
| **policies** | 传输策略 | ID, Name, Type, LayerConfig, GlobalParams |
| **services** | 外部服务 | ID, Name, Type, Address, Port, Config (JSON) |
| **external_services** | 统一服务注册表 | ID, Category, ServiceType, Name, Config (JSON) |
| **mesh_seeds** | 组网凭证 | SeedID, NetworkID, JoinToken, Signature |
| **users** | 用户认证 | Username, PasswordHash (bcrypt), Role |
| **ddns_providers** | DDNS 服务商配置 | Provider, Domain, AccessKey |
| **ddns_usages** | DDNS 用途定义 | UsageType, RecordType, RecordPrefix |
| **notifications** | 通知消息 | UserID, Type, Priority, Title, IsRead |
| **audit_logs** | 审计日志 | Action, OperatorIP, Detail (JSON) |
| **system_settings** | 系统设置 | ServerIP, TURNMode, Theme, Language |
| **pending_joins** | 待审核加入 | SeedID, DeviceName, Status, ExpireAt |
---
## API 概览
所有 API 通过 `http://localhost:9531/api/v1/` 访问(端口可在 `config.yaml` 中配置)。
### 认证接口
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/api/v1/auth/login` | 登录获取 Token |
| POST | `/api/v1/auth/refresh` | 刷新 Token |
### 组网管理
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/v1/networks` | 组网列表 |
| POST | `/api/v1/networks` | 创建组网 |
| POST | `/api/v1/networks/preview` | 预览 MeshSeed |
| POST | `/api/v1/networks/join` | 加入组网 |
| GET | `/api/v1/networks/:id` | 组网详情 |
| PUT | `/api/v1/networks/:id` | 更新组网 |
| DELETE | `/api/v1/networks/:id` | 删除组网 |
| POST | `/api/v1/networks/:id/start` | 启动组网 |
| POST | `/api/v1/networks/:id/stop` | 停止组网 |
| POST | `/api/v1/networks/:id/switch-mode` | 切换传输模式 |
| POST | `/api/v1/networks/:id/meshseed` | 生成 MeshSeed |
### 设备管理
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/v1/devices` | 设备列表 |
| POST | `/api/v1/devices` | 创建设备 |
| GET | `/api/v1/devices/:id` | 设备详情 |
| PUT | `/api/v1/devices/:id` | 更新设备 |
| DELETE | `/api/v1/devices/:id` | 删除设备 |
| GET | `/api/v1/devices/:id/config` | 生成 WG 配置 |
### 策略管理
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/v1/policies` | 策略列表 |
| POST | `/api/v1/policies` | 创建策略 |
| GET | `/api/v1/policies/:id` | 策略详情 |
| PUT | `/api/v1/policies/:id` | 更新策略 |
| DELETE | `/api/v1/policies/:id` | 删除策略 |
### 外部服务
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/v1/services` | 服务列表 |
| POST | `/api/v1/services` | 新增服务 |
| GET | `/api/v1/services/:id` | 服务详情 |
| PUT | `/api/v1/services/:id` | 更新服务 |
| DELETE | `/api/v1/services/:id` | 删除服务 |
| POST | `/api/v1/services/:id/test` | 测试连通性 |
| GET | `/api/v1/services/schema` | 获取表单 Schema |
### DDNS
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/v1/ddns/config` | DDNS 配置 |
| PUT | `/api/v1/ddns/config` | 更新 DDNS 配置 |
| POST | `/api/v1/ddns/test` | 测试连通性 |
| POST | `/api/v1/ddns/sync` | 手动同步 |
| GET | `/api/v1/ddns/detect-ip` | IP 检测 |
| GET | `/api/v1/ddns/stats` | 统计信息 |
| POST | `/api/v1/ddns/usages` | 创建用法 |
| GET | `/api/v1/ddns/usages/available` | 可用用法列表 |
| GET | `/api/v1/ddns/check-prefix` | 检查前缀占用 |
### 系统管理
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/v1/admin/profile` | 管理员信息 |
| PUT | `/api/v1/admin/profile` | 更新管理员 |
| POST | `/api/v1/admin/change-password` | 修改密码 |
| GET | `/api/v1/dashboard/stats` | 仪表盘统计 |
| GET | `/api/v1/dashboard/logs` | 最近日志 |
| GET | `/api/v1/dashboard/system-info` | 系统信息 |
| GET | `/api/v1/dashboard/link-distribution` | 链路分布 |
| POST | `/api/v1/system/backup` | 创建备份 |
| GET | `/api/v1/system/backups` | 备份列表 |
| POST | `/api/v1/system/restore` | 恢复备份 |
| DELETE | `/api/v1/system/backup` | 删除备份 |
| GET | `/api/v1/system/backup/download` | 下载备份 |
| GET | `/api/v1/system/update/check` | 检查更新 |
| POST | `/api/v1/system/restart-core` | 重启核心 |
| POST | `/api/v1/system/change-password` | 修改密码 |
| GET | `/api/v1/settings` | 系统设置 |
| PUT | `/api/v1/settings` | 更新设置 |
### 通知系统
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/v1/notifications` | 通知列表 |
| GET | `/api/v1/notifications/unread-count` | 未读数量 |
| POST | `/api/v1/notifications/:id/read` | 标记已读 |
| POST | `/api/v1/notifications/read-all` | 全部已读 |
| DELETE | `/api/v1/notifications/:id` | 删除通知 |
| POST | `/api/v1/notifications/test` | 测试通知 |
### 待审核加入
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/v1/pending-joins` | 待审核列表 |
| POST | `/api/v1/pending-joins/:id/approve` | 批准 |
| POST | `/api/v1/pending-joins/:id/reject` | 拒绝 |
| GET | `/api/v1/pending-joins/count` | 待审数量 |
| POST | `/api/v1/pending-joins/cleanup` | 清理过期 |
---
## 技术栈
### 后端
| 组件 | 技术 | 版本 | 用途 |
|------|------|------|------|
| **语言** | Go | 1.21+ | 主要编程语言 |
| **Web 框架** | Gin | v1.9+ | HTTP 服务器和路由 |
| **ORM** | GORM | v2.5+ | 数据库操作 |
| **数据库** | SQLite (glebarez/go-sqlite) | v3 | 嵌入式数据库(零 CGO 依赖) |
| **日志** | Zap | v1.26+ | 结构化日志 |
| **配置** | Viper | v1.18+ | 配置管理 |
| **WireGuard** | golang.zx2c4.com/wireguard | latest | 用户态 WG 实现 |
| **DNS** | libdns | latest | 多云 DNS Provider |
| **认证** | bcrypt + golang-jwt | v5 | 密码加密 + JWT |
| **NAT 穿透** | pion/turn, pion/webrtc | latest | STUN/TURN/ICE |
### 前端
| 组件 | 技术 | 用途 |
|------|------|------|
| **UI** | 纯 JavaScript (ES6+) | 管理面板 |
| **静态资源** | Go embed (`//go:embed all:static`) | 内嵌到二进制 |
前端为纯静态 HTML/JS,无 Node.js 依赖,无需额外构建步骤。
---
## 部署方式
### 开发环境
```bash
# 编译并运行
go build -o meshray.exe ./cmd/meshray && ./meshray.exe
# 访问管理面板
http://localhost:9531
```
### 生产环境
| 方式 | 说明 |
|------|------|
| **直接运行** | 单 exe 文件部署,适合 Windows/Linux |
| **Windows 服务** | `meshray.exe install``meshray.exe start` |
| **Systemd** | 使用 `deploy/systemd/meshray.service` |
| **Docker** | 使用 `deploy/docker/docker-compose.yml` |
### 首次启动
首次启动会自动:
1. 生成 `config.yaml` 配置文件(如不存在)
2. 生成 JWT Secret 和加密密钥
3. 创建 SQLite 数据库 `data/meshray.db`
4. 创建管理员账户(用户名:`admin`,密码在控制台输出中)
---
## 版本记录
| 版本 | 核心变更 |
|------|---------|
| v2.0.0 | 初始版本 |
| v2.0.x | 重构 Core 模块,9 层传输策略实现 |
| v2.1.x | 去 gRPC 化,ctr 与 Core 直接函数调用 |
| v2.2.x | DDNS 完整功能、通知系统、备份恢复 |
| v2.3.x | 前端静态化、Embed 集成、重构完成 |
---
*MeshRay | MIT License | v2.3.x*