# 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 Handler(Gin 接入层) │ │ - 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 // 签发者节点 ID(Ed25519 公钥) // 自动生成 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:" ``` --- ## 数据模型 ### 核心表 | 表名 | 说明 | 核心字段 | |------|------|---------| | **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*