up readme

This commit is contained in:
2026-07-07 19:43:48 +08:00
parent 3c076785f6
commit 6074dd5a73
2 changed files with 348 additions and 1 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ APP_BUNDLE = $(APP_NAME).app
GO = go
CGO_ENABLED = 1
GIT_HASH = $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
VERSION = 0.3.6-$(GIT_HASH)
VERSION = 0.3.7-$(GIT_HASH)
LDFLAGS = -s -w -X lmvpn/internal/version.Version=$(VERSION)
.PHONY: all build app run daemon clean vet tidy fmt icon icon-windows build-windows installer-windows
+347
View File
@@ -0,0 +1,347 @@
# LMVPN Client
LMVPN 是一个基于 WebSocket 隧道与 TUN 虚拟网卡的**三层(网络层)VPN 客户端**。客户端通过 WebSocket`ws://`/`wss://`)连接服务端,完成认证后在本地 TUN 虚拟网卡与 WebSocket 连接之间双向转发原始 IP 数据包,实现透明隧道。
客户端使用 [Go](https://go.dev/) + [Fyne](https://fyne.io/) 开发,支持 macOS、Windows、Linux 三大桌面平台。
---
## 目录
- [功能特性](#功能特性)
- [系统要求](#系统要求)
- [各平台编译](#各平台编译)
- [通用前置依赖](#通用前置依赖)
- [macOS](#macos)
- [Windows(交叉编译)](#windows交叉编译)
- [Linux](#linux)
- [Make 目标速查表](#make-目标速查表)
- [运行使用](#运行使用)
- [配置与数据目录](#配置与数据目录)
- [架构概览](#架构概览)
- [开发指南](#开发指南)
- [注意事项](#注意事项)
---
## 功能特性
- **双进程架构**GUI`lmvpn`,普通用户)+ 守护进程(`lmvpnd`,root/管理员),自动拉起与生命周期管理
- **多种认证**:JWT 令牌 / 用户名密码
- **隧道模式**:全量隧道、分流隧道(按目标绕过)、自定义隧道
- **多服务器管理**:配置文件 + SQLite 存储多个服务器配置(Profile)
- **国际化**:中文(简体)、英文,跟随系统语言
- **安全存储**macOS Keychain / Windows Credential Manager 加密保存凭据
- **系统集成**:系统托盘图标、Dock 显隐、开机自启
- **日志轮转**:基于 lumberjack 的文件日志自动轮转
---
## 系统要求
| 平台 | 最低版本 | 架构 | 备注 |
|------|---------|------|------|
| macOS | 11.0Big Sur | amd64 / arm64 | 需 Xcode Command Line Tools |
| Windows | 10 | x86_64 | 仅支持 64 位,需 WinTun 驱动(已内置) |
| Linux | 现代发行版 | amd64 / arm64 | 需 OpenGL/GLFW/libdbus 开发库 |
**所有平台均要求 `CGO_ENABLED=1`**Fyne 依赖 OpenGL/GLFW 的 CGO 绑定,不可关闭)。
---
## 各平台编译
### 通用前置依赖
- **Go 1.26** 或更高版本(见 `go.mod`
- **Git**:用于在编译时注入版本号,格式为 `0.3.7-<git短哈希>`(如 `0.3.7-019df7b`
- **C 编译器**GCCLinux/Windows 交叉编译)或 clangmacOS),由 CGO 调用
- **网络访问**:首次构建需拉取 Go 模块依赖
版本号通过 `-ldflags "-X lmvpn/internal/version.Version=$(VERSION)"` 在链接期注入到 `internal/version` 包,GUI 与守护进程共享同一版本字符串。
### macOS
#### 依赖
- **Xcode Command Line Tools**:提供 clangCGO)、Cocoa 框架、`sips``iconutil`(图标生成)
```bash
xcode-select --install
```
- 最低部署目标 macOS 11.0(见 `resources/Info.plist` 的 `LSMinimumSystemVersion`
#### 编译命令
```bash
# 默认目标:编译二进制并组装 LMVPN.app bundle
make # 等价于 make app
# 仅编译裸二进制(build/lmvpn、build/lmvpnd),不打包 .app
make build
# 重新生成 macOS 图标 resources/icon.icns(需要 icon.png 或 logo.svg
make icon
# 编译并直接运行 GUI
make run
```
`make app` 会将 `build/lmvpn`、`build/lmvpnd` 连同 `resources/Info.plist`、`resources/icon.icns` 组装成 `LMVPN.app/`。
#### 运行
守护进程创建 TUN 网卡与修改路由需要 root 权限,GUI 通过 `osascript ... with administrator privileges` 弹出系统授权对话框提权拉起守护进程。日常使用直接双击 `LMVPN.app` 即可。
---
### Windows(交叉编译)
Windows 版本从 macOS 或 Linux **交叉编译**生成(Fyne 无法用 `CGO_ENABLED=0` 构建,因此必须借助 mingw-w64 提供 C 交叉编译器)。仅支持 **x86_64** 架构。
#### 依赖
- **mingw-w64 工具链**:提供 `x86_64-w64-mingw32-gcc`C 编译器)与 `x86_64-w64-mingw32-windres`(资源编译器)
```bash
# macOS
brew install mingw-w64
```
- **Inno Setup 6**(仅打包安装程序时需要):用于生成 `.exe` 安装包
- 原生 Windows:将 `ISCC` 加入 `PATH`
- macOS/Linux:通过 Wine 调用,需安装 Wine 并将 Inno Setup 6 装到 Wine 的 `C:\Program Files (x86)\Inno Setup 6\`
#### 编译命令
```bash
# 1. 生成 Windows 图标与资源(.ico + .syso),并交叉编译 exe
make build-windows
# 2. 单独生成图标资源(生成 resource_windows_amd64.syso,会被 go build 自动链接)
make icon-windows
# 3. 编译并打包 Inno Setup 安装程序
make installer-windows
```
`make build-windows` 实际执行:
```bash
# GUI(带 -H windowsgui,无控制台窗口)
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc \
go build -ldflags "-s -w -X ... -H windowsgui" -o build/lmvpn.exe ./cmd/lmvpn
# 守护进程(控制台程序)
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc \
go build -ldflags "-s -w -X ..." -o build/lmvpnd.exe ./cmd/lmvpnd
```
产物:`build/lmvpn.exe``build/lmvpnd.exe`,安装包 `build/LMVPN-Setup-<version>.exe`
#### 关于 WinTun
Windows 版使用 [WinTun](https://www.wintun.net/) 驱动创建虚拟网卡。`wintun.dll` 在编译期通过 `//go:embed` 嵌入二进制,运行时释放到 exe 同级目录;安装包也会单独安装一份 `wintun.dll`
#### 运行
守护进程需要管理员权限,GUI 通过 UAC(`ShellExecuteW` + `runas`)提权拉起。
---
### Linux
Linux 没有独立的 Make 目标,使用平台无关的 `make build` 原生编译。
#### 依赖
- **GCC**CGO 编译器)
- **OpenGL 与 GLFW 开发库**Fyne 依赖):`libgl``libglfw``libx11`、xorg 开发头
- **libdbus-1 开发库**(系统托盘,经 `godbus/dbus`):`libdbus-1-dev` 或对应开发包
> 请根据所用发行版(apt / dnf / pacman 等)自行安装上述开发库。
#### 编译命令
```bash
# 原生编译(平台无关,直接产出 build/lmvpn、build/lmvpnd
make build
# 编译并运行 GUI
make run
# 以 root 运行守护进程(调试用)
make daemon
```
#### 运行
- TUN 网卡创建与路由配置需要 **root 或 `CAP_NET_ADMIN`** 能力
- 提权方式:`pkexec``internal/ui/elevation_other.go`
- 系统命令依赖:`ip``ip route``internal/route/route_linux.go``internal/tun/tun_linux.go`
- **密钥链**:Linux 暂使用内存存储(不持久化),重启后凭据丢失,后续需接入 Secret Service 等后端
---
### Make 目标速查表
| 目标 | 说明 |
|------|------|
| `make` / `make all` / `make app` | 编译并组装 macOS `LMVPN.app` bundle(默认) |
| `make build` | 仅编译 `lmvpn` + `lmvpnd` 裸二进制(macOS/Linux 原生) |
| `make run` | 编译并运行 GUI |
| `make daemon` | 编译并以 `sudo` 运行守护进程 |
| `make build-windows` | 交叉编译 Windows x64 exe(含图标资源生成) |
| `make icon-windows` | 生成 Windows `.ico``.syso` 资源文件 |
| `make installer-windows` | 编译 exe 并打包 Inno Setup 安装程序 |
| `make icon` | 由 `icon.png`/`logo.svg` 重新生成 macOS `icon.icns` |
| `make vet` | 运行 `go vet ./...` |
| `make fmt` | 运行 `go fmt ./...` |
| `make tidy` | 运行 `go mod tidy` |
| `make clean` | 清理 `build/``LMVPN.app/` |
---
## 运行使用
GUI 会自动管理守护进程的生命周期(拉起、停止),无需手动启动 `lmvpnd`
- **macOS**:双击 `LMVPN.app`,首次连接时系统弹出授权对话框输入密码以提权守护进程
- **Windows**:运行安装包或直接运行 `lmvpn.exe`,首次连接时 UAC 弹窗确认提权
- **Linux**`make run` 或运行编译好的 `lmvpn`,首次连接时 `pkexec` 弹窗输入密码提权
GUI 与守护进程通过本地 IPC 通信:macOS/Linux 使用 Unix socket `/tmp/lmvpn.sock`Windows 使用 TCP `127.0.0.1:18923`(因 Windows 上 AF_UNIX 有完整性级别校验,会阻止非提权 GUI 访问提权守护进程的 socket)。
---
## 配置与数据目录
各平台的数据目录布局(Bundle ID 为 `com.lmvpn.client`):
| 平台 | 配置/数据 | 缓存 | 日志 |
|------|----------|------|------|
| macOS | `~/Library/Application Support/com.lmvpn.client/` | `~/Library/Caches/com.lmvpn.client/` | `~/Library/Logs/com.lmvpn.client/` |
| Windows | `%APPDATA%\com.lmvpn.client\` | `%LOCALAPPDATA%\com.lmvpn.client\` | 同数据目录下 `log/` |
| Linux | `~/.local/share/com.lmvpn.client/` | `~/.cache/com.lmvpn.client/` | `~/.local/state/com.lmvpn.client/log/` |
- 配置文件支持 TOML 与 YAML 两种格式(`internal/config`
- 服务器配置(Profile)存储于 SQLite 数据库(`internal/db`,使用纯 Go 的 `modernc.org/sqlite`,无需 CGO
- 凭据保存于系统密钥链(macOS Keychain / Windows Credential Manager / Linux 内存)
---
## 架构概览
### 双进程设计
```
┌──────────────┐ IPC (Unix socket / TCP) ┌──────────────┐
│ lmvpn │ ◄─────────────────────────► │ lmvpnd │
│ (GUI) │ 控制命令 / 状态 │ (守护进程) │
│ Fyne UI │ │ WebSocket │
│ 普通用户 │ │ TUN 网卡 │
│ │ │ root/管理员 │
└──────────────┘ └──────┬───────┘
WebSocket (ws/wss)
┌──────────────┐
│ LMVPN 服务端 │
└──────────────┘
```
拆分 GUI 与守护进程的原因:避免 Fyne(及其 locale/字体初始化)加载进 root 进程,同时让提权范围最小化——仅守护进程需要 root 权限操作网卡与路由。
### 目录结构
```
lmvpn_client/
├── cmd/
│ ├── lmvpn/ # GUI 入口
│ └── lmvpnd/ # 守护进程入口
├── internal/
│ ├── auth/ # 认证(JWT / 用户名密码)
│ ├── config/ # 配置文件解析(TOML / YAML
│ ├── daemon/ # 守护进程生命周期、IPC、提权拉起
│ ├── db/ # SQLite 存储、Profile、日志记录
│ ├── i18n/ # 国际化(en / zh-Hans
│ ├── ipc/ # GUI ↔ 守护进程 IPC 协议
│ ├── keychain/ # 密钥链(darwin/windows/other
│ ├── log/ # 日志(lumberjack 轮转)
│ ├── model/ # 数据模型
│ ├── paths/ # 平台路径解析(darwin/windows/other
│ ├── protocol/ # 与服务端的 WebSocket 协议
│ ├── route/ # 路由管理(全量/分流/自定义)
│ ├── stats/ # 流量统计
│ ├── transport/ # WebSocket 传输层
│ ├── tun/ # TUN 虚拟网卡(darwin/linux/windows
│ ├── ui/ # Fyne 界面、托盘、提权、Dock
│ ├── version/ # 版本号(链接期注入)
│ └── vpn/ # VPN 会话管理
├── resources/ # 图标、Info.plist、wintun.dll、资源生成器
├── installer/ # Inno Setup 安装脚本(lmvpn.iss
├── docs/ # 开发文档(协议规范)
└── Makefile
```
### 平台适配约定
项目使用 Go 文件后缀构建约束实现平台适配,主要分布:
| 模块 | macOS | Windows | Linux |
|------|-------|---------|-------|
| `tun` | `tun_darwin.go`water/utun | `tun_windows.go`wintun + embed dll | `tun_linux.go`water/tun |
| `route` | `route_darwin.go``route` | `route_windows.go``route` | `route_linux.go``ip route` |
| `keychain` | `keychain_darwin.go`Keychain | `keychain_windows.go`Credential Manager | `keychain_other.go`(内存) |
| `paths` | `paths_darwin.go` | `paths_windows.go` | `paths_other.go`XDG |
| `daemon` 提权 | `launch_unix.go` + osascript | `launch_windows.go` + UAC runas | `launch_unix.go` + pkexec |
| `ui` Dock | `dock_darwin.go`Cocoa CGO | `dock_other.go`no-op | `dock_other.go`no-op |
---
## 开发指南
```bash
# 静态检查
make vet
# 格式化
make fmt
# 整理依赖
make tidy
# 清理构建产物
make clean
```
### 添加新平台适配
如需适配新的平台能力,参考现有约定新增带构建约束的文件,例如:
- TUN 实现 → `internal/tun/tun_<os>.go`
- 路由命令 → `internal/route/route_<os>.go`
- 密钥存储 → `internal/keychain/keychain_<os>.go`
- 路径解析 → `internal/paths/paths_<os>.go`
### 协议规范
客户端与服务端的完整通信协议见 [`docs/client-development.md`](docs/client-development.md)(含认证、握手、数据面、心跳、错误码等)。
---
## 注意事项
- **不支持移动端**:虽 Fyne 支持 Android/iOS,本项目未配置移动端构建目标与适配代码
- **Windows 仅 x64**:交叉编译仅目标 `GOARCH=amd64`,内置的 `wintun.dll` 为 x64 版本
- **Linux 密钥链待完善**:当前为内存存储,凭据不持久化,生产环境建议接入 Secret Service
- **无 CI/CD**:所有构建均为本地手动执行,无自动化构建矩阵
- **CGO 必开**:任何平台都不可关闭 CGO,否则 Fyne 无法编译
- **版本一致性**:GUI 与守护进程共享同一版本字符串,若版本不一致通常意味着旧守护进程仍在运行
---
## 许可证
详见仓库 LICENSE 文件。