13 KiB
VPN 专线管理平台
Gin + Vue3 + SQLite 的多协议 VPN 专线 Web 管理平台:单二进制交付、配置简单、管理便捷、可扩展自定义协议。
支持协议
| 协议 | 实现方式 | 场景 |
|---|---|---|
| WireGuard | 系统 wg / wg-quick,多 Peer、NAT/MTU、流量累计 |
内部接入、移动办公(首选) |
| IPSec | StrongSwan swanctl,厂商模板一键套用 |
第三方对接、站点互联 |
| IKEv2 远程接入 | StrongSwan Road Warrior,PSK + EAP-MSCHAPv2 | 员工手机/笔记本原生拨号 |
| L2TP/IPSec | StrongSwan + xl2tpd,支持多拨号用户 | 手机/老设备兼容 |
| FRP | 直接管理 frps / frpc(TOML),含 STCP/XTCP |
内网穿透、端口映射 |
| GRE | Linux ip tunnel 管理标准 GRE 隧道 |
点对点网站互联 |
| OpenVPN | 进程管理 + PKI;UDP/TCP 可切换;证书/密码 + TOTP MFA | 老项目兼容 |
| 自定义协议 | 插件命令钩子(Create/Start/Stop/Status/Config) | 任意协议扩展 |
核心功能
- 专线列表:名称/协议/状态/流量/到期时间,一键启停、编辑、删除、下载配置、WireGuard 二维码
- 创建向导:选协议 → 依赖检测门控(未就绪不可选,引导下载/安装)→ 填参数(高级折叠)→ 必填校验
- 在线会话:跨协议统一展示在线用户、公网 IP、VPN IP、连接时长、流量;支持踢下线
- 流量审计:连接审计日志(connect/disconnect/auth_fail)、异常突发流量告警、管理员手动踢下线
- 流量配额:隧道级配额(GB)、超额动作(告警/停止/限速)、周期重置(日/月)
- 协议引擎管理:FRP/OpenVPN 支持平台一键下载部署;WireGuard/StrongSwan 显示系统包安装命令
- WireGuard Peer 管理:详情内增删 Peer、按设备下载配置/二维码
- 拨号用户:OpenVPN / L2TP / IKEv2 共用用户表;支持从平台用户导入、批量创建、LDAP 浏览导入
- IPSec 第三方对接专页:设备模板预置 Phase1/Phase2 参数、双方参数一致性检查、一键连通性测试
- 节点管理:多中继节点,远程节点支持 SSH 凭证验证(密码/私钥、即时测试连接)
- 专线日志:操作栏「更多 → 查看日志」SSE 实时输出实例进程日志
- 安全:PSK/私钥 AES-GCM 加密存储、配置文件 0600 权限、操作审计
- 访问控制:admin / operator / viewer;首登强制改密;登录防爆破;TOTP MFA + 备用码;LDAP
快速开始
桌面客户端位于 client/:Rust + Tauri v2 管理拨号用户登录、线路与设备登记,打包的 Go WireGuard 网络栈提供出口诊断和仅供主动配置的应用使用的本地 SOCKS5 代理。macOS/Linux 的整机 VPN目前仍依赖本机 wg/wg-quick;Windows 整机隧道未实现。客户端功能和操作见 客户端说明,免安装系统隧道的设计与待验收项目见 SDD-003。
OpenVPN 飞书 / OIDC 浏览器认证
在「创建专线 → OpenVPN → 认证方式」选择「第三方 OAuth2 / OIDC(飞书登录)」。引导页会展示飞书应用准备、OIDC 信息、公网回调与客户端试连四步。该模式由 openvpn-auth-oauth2 接管 OpenVPN 的 WebAuth 认证;不会将飞书登录转交给已有的 LDAP 密码校验,也不会将现有 LDAP 用户自动关联为飞书用户。应用的可用范围应在飞书或身份代理侧明确限定。
- 在 飞书开放平台 创建并发布企业自建应用,启用网页登录,限定可用人员。内置方案:通过可信 HTTPS 管理入口打开「设置 → 飞书身份」,只在此处保存飞书 App ID、轮换后的 App Secret 与允许的
tenant_key,把页面所示https://<公网域名>/id/feishu/callback登记到飞书应用。启用后系统通过https://<公网域名>/id提供标准 OIDC 发现文档、JWKS 和令牌签发。在专线新建或编辑页选择「内置飞书身份」,发行者与 VPN Client ID 自动引用,VPN Client Secret 由服务端自动配置,不会回显。也可以继续使用外部标准 OIDC issuer:此时飞书 App 凭据留在外部代理,专线填写代理生成的 VPN Client ID/Secret。 - 在 Linux VPN 主机安装 OpenVPN 2.6.2 或更新版本及
openvpn-auth-oauth2可执行文件(置于 PATH 或data/bin/openvpn-auth-oauth2)。内置方案在向导中选择内置 issuer,公网认证入口可复用管理域名(已有证书);独立服务端口默认19090。外部 OIDC 方案仍需手动填写发行者、VPN 客户端凭据与独立 HTTPS 入口。每条专线的认证入口和本机端口必须唯一。 - 内置方案在设置页同步身份公网路由,Nginx 只转发固定
/id/端点;启动唯一一条使用该管理域名的测试 OpenVPN OIDC 专线后再次同步,Nginx 才将/oauth2/转给本机认证组件。该https://<公网域名>/oauth2/callback属于 OpenVPN 组件,不是飞书应用的回调。外部发行者方案仍需在外部 OIDC 客户端登记此 VPN 回调。公网只开放 HTTPS 与 VPN 协议端口,认证端口127.0.0.1:19090+和 OpenVPN 管理 socket 不对公网开放。 - 启动专线时平台会运行独立的 OpenVPN 和认证服务进程;OIDC 凭据在数据库加密保存,认证服务的
openvpn-auth-oauth2.yaml与管理密码文件在data/instances/<ID>-openvpn/内以0600保存。未安装二进制、OpenVPN 版本不足或认证服务启动失败都会报错并停止该专线。浏览器登录失败时不回退到 LDAP 或本地密码。 - 下载
.ovpn并在支持 WebAuth 的客户端试连。上游客户端兼容性说明列出 Windows OpenVPN Community Client 2.6+、macOS Tunnelblick 4.0 beta 10+ 和 Viscosity;OpenVPN Connect v3 仅部分兼容,应先实测。客户端需要在 VPN 建立之前访问公网 HTTPS 入口及身份源。用授权用户与未授权用户分别测试登录和拒绝,验证断线重连。
首次上线先创建独立测试隧道;不要直接切换现有密码隧道。OIDC 登录身份的授权由飞书应用范围或身份代理规则控制,管理端的 VPN 拨号用户列表目前仍是独立的数据模型。需要将飞书身份与 LDAP 用户逐一绑定时,应增加按稳定 sub 映射的授权设计,不能只按相同邮箱/用户名匹配。服务日志位于实例目录的 oidc.log,可能包含认证诊断信息,按敏感日志管理。
本地构建与运行
./run.sh run # 构建并运行(默认 admin / admin123)
./run.sh dev # 开发模式(前后端分离)
./run.sh restart # 重新构建并重启
./run.sh stop # 停止服务
管理后台的视觉和交互规范见 管理端 UI 实施说明。前端沿用 Vue 3 + Element Plus:路由元数据统一生成侧栏与页标题,颜色和间距集中在 frontend/src/styles/tokens.css,列表与图表明确展示加载、空数据和失败重试。单独预览前端可在 frontend/ 运行 npm run dev;默认代理 /api 到本机 8080,需要启动后端才能测试登录及真实数据。
Linux 服务器部署
现有服务器的构建、升级、备份与 OIDC 入口配置参见 部署手册。
# 1. 交叉编译 Linux 二进制(在 macOS 上)
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o opsx-vpn ./backend
# 2. 上传到服务器
scp opsx-vpn user@server:/opt/opsx-vpn/
cd /opt/opsx-vpn && chmod +x opsx-vpn
# 3. 安装系统依赖(按需)
apt install -y wireguard-tools openvpn easy-rsa strongswan strongswan-swanctl iproute2 iptables xl2tpd
# FRP 无需系统包 —— 平台 UI 内点「下载部署」自动从 GitHub 下载到 data/bin/
# 4. 启动(生产建议用 systemd 管理)
VPN_LISTEN_ADDR=:18080 ./opsx-vpn # 生产管理端口 :18080,数据目录 ./data
systemd 服务(生产推荐)
# /etc/systemd/system/opsx-vpn.service
[Unit]
Description=VPN Management Platform
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/opsx-vpn
ExecStart=/opt/opsx-vpn/opsx-vpn
Restart=always
RestartSec=5
# 环境变量按需调整
Environment=VPN_LISTEN_ADDR=:18080
Environment=VPN_DATA_DIR=/opt/opsx-vpn/data
# WireGuard/OpenVPN 需要 root 权限(创建 TUN 设备 + iptables)
# 如需降权,需配置 NET_ADMIN capability
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now opsx-vpn
journalctl -u opsx-vpn -f # 查看日志
防火墙 / 安全组端口
部署到云服务器时,需开放以下端口:
VPN 数据通道(对公网开放)
| 端口 | 协议 | 类型 | 用途 |
|---|---|---|---|
| UDP 51820 | WireGuard | UDP | WG 默认监听端口(可在创建时改) |
| UDP 1194 | OpenVPN | UDP | OpenVPN 默认端口(可改 TCP) |
| TCP 1194 | OpenVPN | TCP | OpenVPN TCP 模式(如选 TCP) |
| UDP 500 | IPSec / IKEv2 / L2TP | UDP | IKE 密钥交换 |
| UDP 4500 | IPSec / IKEv2 / L2TP | UDP | NAT-T 穿透 |
| UDP 1701 | L2TP | UDP | L2TP 隧道 |
| TCP 7000 | FRP | TCP | frps 绑定端口(客户端连接用) |
| IP 协议 47 | GRE | GRE | GRE 封装(无 TCP/UDP 端口) |
管理(仅限你的 IP 或内网)
| 端口 | 协议 | 类型 | 用途 |
|---|---|---|---|
| TCP 18080 | 管理平台 | TCP | Web UI + API(勿对公网开放,建议 Nginx HTTPS 后改 443) |
| TCP 22 | SSH | TCP | 远程管理 |
安全组配置示例
# VPN 数据通道(对公网开放)
UDP 500/4500 0.0.0.0/0 # IPSec/IKEv2/L2TP 密钥交换 + NAT-T
UDP 51820 0.0.0.0/0 # WireGuard
UDP 1194 0.0.0.0/0 # OpenVPN UDP
TCP 1194 0.0.0.0/0 # OpenVPN TCP(如启用)
UDP 1701 0.0.0.0/0 # L2TP
TCP 7000 0.0.0.0/0 # FRP server
# GRE 不是 TCP/UDP 端口,需在安全组中放行 GRE / IP 协议 47
GRE 协议 47 对端公网 IP/32 # 建议只允许对端地址
# 管理(仅限你的 IP)
TCP 18080 你的IP/32 # 管理 UI
TCP 22 你的IP/32 # SSH
注意:IPSec 必须同时开放 UDP 500 + 4500(缺一个连不上)。GRE 需要本端、对端及中间云安全组双向允许 IP 协议 47,不是端口号;Linux 端依赖
iproute2的ip tunnel。管理端口 18080 切勿对公网开放。仅用 WireGuard 最简部署只需 3 个端口:UDP 51820 + TCP 18080 + TCP 22。
协议依赖安装
| 协议 | 安装方式 | 平台下载 |
|---|---|---|
| WireGuard | apt install -y wireguard-tools |
❌ 系统包 |
| OpenVPN | apt install -y openvpn easy-rsa(easy-rsa 用于生成 PKI,缺了无法下发客户端配置) |
✅ GitHub Release / 系统包 |
| StrongSwan (IPSec/IKEv2/L2TP) | apt install -y strongswan strongswan-swanctl |
❌ 系统包 |
| GRE | apt install -y iproute2(多数系统默认已安装) |
❌ 系统包 |
| FRP | 无需系统包 | ✅ 平台 UI「下载部署」自动从 GitHub 下载 |
在「总览 → 协议引擎状态」表中,未就绪的协议会显示「下载部署」或「安装命令」按钮。
环境变量
| 变量 | 默认 | 说明 |
|---|---|---|
VPN_LISTEN_ADDR |
:18080 |
监听地址 |
VPN_DATA_DIR |
./data |
数据目录(SQLite、密钥、实例配置、下载的二进制) |
常用命令
| 命令 | 说明 |
|---|---|
./run.sh run |
构建并后台运行单二进制(默认) |
./run.sh build |
全量构建(前端 + 后端二进制) |
./run.sh dev |
开发模式(前后端分离) |
./run.sh stop |
停止所有服务 |
./run.sh restart |
重新构建并重启 |
./run.sh status |
查看服务状态 |
项目结构
frontend/ # Vue3 + Element Plus 前端
backend/
main.go # Gin 入口(内嵌前端 embed.FS)
internal/
api/ # REST 路由与鉴权
core/ # Protocol 统一接口 + 注册中心
model/ # GORM 数据模型
store/ # SQLite + AES-GCM 密钥存储
service/ # 协议实现
wireguard/ ipsec/ ikev2/ l2tp/ frp/ openvpn/
custom/ # 自定义协议插件
monitor/ # 状态/流量/会话/配额采集引擎
sessionmgr/ # 在线会话同步 + 连接审计
trafficmgr/ # 流量配额 + 异常检测 + 限速
binmgr/ # 协议二进制下载部署 + 安装引导
sshutil/ # SSH 连接测试(节点验证)
交付形态
- 单二进制:前端构建后通过
go:embed内嵌进 Go 二进制,./opsx-vpn单文件即可运行(含 SPA + REST API + SQLite) - 不依赖 Docker、不依赖外部数据库
- 纯静态编译:
CGO_ENABLED=0可交叉编译到任意 Linux/Windows