Files
opsx-vpn/docs/deploy.md
T

9.2 KiB

opsx-vpn 部署与升级

本文件根据服务器上的 /home/ubuntu/depoly.md 整理;以代码仓库中的步骤为准,实际主机、端口、访问凭据和安全组规则按环境调整。不要将管理员密码、SQLite 数据库、data/secret.key 或实例私钥提交到仓库。

服务器准备

  • Ubuntu 24.04;安装 Git、Go、Node.js、npm 和项目所需的协议软件包。运行 OpenVPN 专线还需要 openvpn、easy-rsa、iproute2 与 iptables。OIDC 专线要求 OpenVPN 2.6.2+,另需安装 openvpn-auth-oauth2 到 PATH 或 data/bin/。
  • 在 VPN 网关上开启 IPv4 转发,按实际启用的协议开放 VPN 数据端口。管理端 18080 应仅供可信网络或 SSH 隧道访问。运行账户需要管理 TUN 和防火墙的权限。
  • 服务在仓库目录运行;默认数据目录为 ./data。data/ 保存数据库、加密密钥和各实例配置,升级时不得删除或覆盖。

首次构建与启动

git clone https://gitea.91ai.io/rlwj-lab/opsx-vpn.git
cd opsx-vpn
cd frontend && npm ci && npm run build && cd ..
go build -ldflags="-s -w" -o opsx-vpn ./backend
sudo sh -c 'VPN_LISTEN_ADDR=:18080 setsid nohup ./opsx-vpn > /tmp/opsx-vpn.log 2>&1 < /dev/null &'
curl --fail http://127.0.0.1:18080/api/health

前端资源在构建 Go 二进制时内嵌,修改前端后须重新执行 两个构建步骤。首次登录请立即修改初始密码并启用适当的管理端保护。

在现有服务器上升级

先确认服务器工作树干净且仓库地址、分支符合预期。以下操作以 /home/ubuntu/opsx-vpn 和管理端口 18080 为例;升级前记录已有 VPN 实例进程与健康状态。

cd /home/ubuntu/opsx-vpn
git status --short
curl --fail http://127.0.0.1:18080/api/health
sudo cp -p opsx-vpn "opsx-vpn.bak-$(date +%Y%m%d-%H%M%S)"
git pull --ff-only origin master
cd frontend && npm run build && cd ..
go build -ldflags="-s -w" -o opsx-vpn.new ./backend

编译通过后,按监听端口核对管理程序 PID,精确停止该进程;不要停止仍在运行的 OpenVPN 实例。确认端口释放后替换并启动:

sudo ss -tlnp | grep ':18080'
# 确认 PID 确实属于 opsx-vpn 后:sudo kill <管理程序PID>
sudo mv opsx-vpn.new opsx-vpn
sudo chmod 755 opsx-vpn
sudo sh -c 'cd /home/ubuntu/opsx-vpn && VPN_LISTEN_ADDR=:18080 setsid nohup ./opsx-vpn > /tmp/opsx-vpn.log 2>&1 < /dev/null &'
curl --fail http://127.0.0.1:18080/api/health
sudo ss -tlnp | grep ':18080'

再检查页面静态资源、/tmp/opsx-vpn.log 和原有 VPN 实例状态。若新版本无法启动,停掉新管理进程,复制最近的 opsx-vpn.bak-* 到 opsx-vpn 并按上面的方式启动;如涉及数据模型变更,先依据对应变更的迁移说明处理数据库,不能直接覆盖 data/。

飞书 / OIDC 登录入口

http://121.4.111.208:18080 是当前管理界面示例,既不是 OIDC issuer,也不是 OAuth 回调地址。当前项目在 OpenVPN OIDC 配置中要求 oidc_issuer 和 oidc_base_url 均为 HTTPS。issuer 指向提供标准 OIDC discovery 和 ID Token 的身份提供方(飞书若不支持,需使用 Keycloak / Authentik 等身份代理)。

认证入口另设可供 VPN 客户端在连接前访问的 HTTPS 地址,例如 https://vpn-login.example.com。它可以与 opsx-vpn 管理后台部署在同一台服务器上:反向代理依据域名把管理站点送往 :18080,把认证站点的所有路径送往同机 127.0.0.1:19090(按专线配置调整)。两者是同一台服务器上的不同 Web 服务,并非管理后台不允许提供其他页面;当前实现由平台启动和管理认证组件,回调实际由 openvpn-auth-oauth2 处理。最终在 OIDC 身份提供方登记 https://vpn-login.example.com/oauth2/callback。不要把本地认证端口或 OpenVPN 管理 socket 暴露到公网。详见 接入说明。

该域名须由你控制并解析到公网入口。管理员可在“设置 → 域名与证书”保存 test-link.appx365.com,并选择 Go 或 Nginx 入口模式;VPN_TLS_DOMAIN 和 VPN_TLS_MODE 环境变量优先于页面配置。两种模式只能选一种来占用 TCP 80/443,保存配置并不会安装 Nginx、开放安全组或签发证书。

Go 模式(默认)使用 golang.org/x/crypto/acme/autocert 监听 80/443,处理 HTTP-01、自动签发和续签;首次访问 https://test-link.appx365.com/api/health 才开始签发。证书和 ACME 账号密钥在 data/acme,须备份。此模式下 80 的非挑战请求会跳转 HTTPS,443 的管理站点沿用 Gin 路由,不会对未知路径执行 Nginx return 444。如需严格的公网路径白名单,使用下面的 Nginx 模式。端口空闲、公网 DNS 和云安全组 TCP 80/443 通畅是两种模式的共同前置条件。

Nginx 模式:HTTP-01 与路径白名单

“设置 → 首次引导”先检查 root、默认出口、IPv4 转发;管理员可单独启用 IPv4 转发。OpenVPN、WireGuard、IPSec 等依赖仍在“创建专线”选择相应协议时单独安装,不会因进入引导页而批量安装。“可选 · HTTPS 公网入口 → 准备 Nginx / Certbot”会读取 /etc/os-release,仅在 Ubuntu 使用 apt-get、TencentOS Server 4 使用 dnf 安装 Nginx/Certbot,并创建 /var/lib/opsx-vpn/acme/.well-known/acme-challenge。页面会实时显示安装日志;需以 root 运行平台,其他系统显示不支持。Ubuntu 上如果已有 /usr/sbin/policy-rc.d,初始化会拒绝覆盖该文件;安装期间临时阻止软件包脚本自动启动 Nginx,正常结束后移除临时策略。若进程在安装时被强制杀死,检查并移除该临时策略后再试。TencentOS 上安装后也需核实发行版的软件包脚本没有启动默认站点;如发行版仓库没有 Certbot,页面报告失败,由管理员检查软件源。初始化不改写已有站点,不会主动启用 80/443,也不会签发证书。

“预览 Nginx 配置”仅生成当前域名和后端实际注册 API 路由对应的两段站点配置,不会写入系统目录或启动服务。第一段监听 80,仅从 /var/lib/opsx-vpn/acme 提供 /.well-known/acme-challenge/;其他路径 return 444。第二段在证书已签发后监听 443:只反代已知前端页面、构建资源和已注册 API,其余路径 return 444;未知 TLS 主机名拒绝握手。切换模式必须按以下顺序进行(先备份现有站点,检查是否已有服务占用 80/443):

  1. 可用引导按钮安装 nginx、certbot,检查云安全组放行 TCP 80/443 和域名 A/AAAA 记录;检查现有 /etc/nginx/sites-enabled/,若自带 default 站点占用 default_server,先备份并禁用该站点。若 Go 当前监听 80/443,先规划停机切换,不能同时启动 Nginx。
  2. 创建 /var/lib/opsx-vpn/acme/.well-known/acme-challenge,让 Nginx 工作账户能读取该目录;将页面预览的 HTTP 段保存为站点文件,先运行 nginx -t,再启动或重载 Nginx。先确认挑战路径从公网可读、其他 HTTP 请求断开,再执行 certbot certonly --webroot -w /var/lib/opsx-vpn/acme -d test-link.appx365.com。预览中的域名是页面实际配置的域名,替换示例命令中的域名。
  3. 确认证书和私钥存在于 /etc/letsencrypt/live/<域名>/ 后,追加预览的 HTTPS 段;运行 nginx -t 后重载。设置 Certbot 续期定时器和 deploy hook:续期成功时先 nginx -t,再 systemctl reload nginx。运行 certbot renew --dry-run 并确认 hook 的实际生效方式(测试续期时可能需要 --run-deploy-hooks)。
  4. 页面保存入口模式为 Nginx,启动或重启 opsx-vpn 并设置 VPN_LISTEN_ADDR=127.0.0.1:18080;确认 https://<域名>/api/health、登录及各业务页面可用,未知路径断开,80 的挑战仍可读,然后收紧 18080 公网安全组。若现有业务必须从公网直连 18080,先迁移这些客户端。

不要只开放 /oauth2/callback:独立的 OIDC 认证域名还要转发认证组件的完整登录流程,且应另为该域名申请证书。管理站点的路由预览不覆盖认证域名;真实认证域名和组件端口确认后单独配置。若代理和 VPN 主机分离,预览里的 127.0.0.1 指代理主机自身,应改成受限私网地址并保护传输链路。回退时先恢复原 Nginx 配置及 opsx-vpn 入口模式,运行 nginx -t 后重载,不删除 data/ 或已有证书。

/.well-known/openid-configuration 属于发行者域名,不是认证入口上的 VPN 回调。不要只放行 /oauth2/callback:认证组件还需要发起登录等路由。认证入口使用独立域名,只反代给认证组件;如需按路径白名单返回 Nginx 444,须先核对实际安装版本的完整路由,并保障 HTTP-01 验证路径。认证端口默认 19090,仅监听回环;新增 OIDC 专线自动递增并跳过已配置或已监听的端口,仍以启动时冲突检测为准。

启用飞书认证前,需安装并验证 openvpn-auth-oauth2、准备身份提供方凭据、配置 HTTPS 反代,并用支持 WebAuth 的客户端联调。现有 LDAP 拨号用户不会自动绑定飞书用户。