up readme
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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.0(Big 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 编译器**:GCC(Linux/Windows 交叉编译)或 clang(macOS),由 CGO 调用
|
||||
- **网络访问**:首次构建需拉取 Go 模块依赖
|
||||
|
||||
版本号通过 `-ldflags "-X lmvpn/internal/version.Version=$(VERSION)"` 在链接期注入到 `internal/version` 包,GUI 与守护进程共享同一版本字符串。
|
||||
|
||||
### macOS
|
||||
|
||||
#### 依赖
|
||||
|
||||
- **Xcode Command Line Tools**:提供 clang(CGO)、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 文件。
|
||||
Reference in New Issue
Block a user