From 5107f134dd5c96c7389122d8ed70aaf09331f328 Mon Sep 17 00:00:00 2001 From: opsx Date: Tue, 20 Oct 2026 21:48:05 +0800 Subject: [PATCH] =?UTF-8?q?fix(openvpn):=20=E4=BE=9D=E8=B5=96=E6=A3=80?= =?UTF-8?q?=E6=B5=8B=E7=BA=B3=E5=85=A5=20easy-rsa=EF=BC=8C=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E3=80=8C=E5=B7=B2=E5=B0=B1=E7=BB=AA=E3=80=8D=E5=8D=B4?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E4=B8=8B=E5=8F=91=E5=AE=A2=E6=88=B7=E7=AB=AF?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现象:装了 openvpn 但缺 easy-rsa 时,协议状态显示已就绪;创建 OpenVPN 隧道后 生成客户端配置报 open .../pki/ca.crt: no such file or directory。 原因:PKI 自动初始化要求 easyRSAPath() != "",缺 easy-rsa 时静默跳过; 而 binmgr.CheckBinary(openvpn) 只检测 openvpn 二进制,未校验 easy-rsa。 修复: - binmgr 新增 easyRSAAvailable(),兼容 PATH 与 /usr/share/easy-rsa/* - CheckBinary(openvpn) 在 easy-rsa 缺失时置 installed=false(前端即显示未就绪) - README 依赖清单补 easy-rsa、xl2tpd 验证:隐藏 /usr/share/easy-rsa 后 /api/binaries/status 中 openvpn installed=false, 恢复后 true。 --- README.md | 4 ++-- backend/internal/binmgr/binmgr.go | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4d0d895..c0629b9 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ scp opsx-vpn user@server:/opt/opsx-vpn/ cd /opt/opsx-vpn && chmod +x opsx-vpn # 3. 安装系统依赖(按需) -apt install -y wireguard-tools openvpn strongswan strongswan-swanctl iproute2 iptables +apt install -y wireguard-tools openvpn easy-rsa strongswan strongswan-swanctl iproute2 iptables xl2tpd # FRP 无需系统包 —— 平台 UI 内点「下载部署」自动从 GitHub 下载到 data/bin/ # 4. 启动(生产建议用 systemd 管理) @@ -139,7 +139,7 @@ TCP 22 你的IP/32 # SSH | 协议 | 安装方式 | 平台下载 | |---|---|---| | WireGuard | `apt install -y wireguard-tools` | ❌ 系统包 | -| OpenVPN | `apt install -y openvpn` | ✅ GitHub Release / 系统包 | +| 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 下载 | diff --git a/backend/internal/binmgr/binmgr.go b/backend/internal/binmgr/binmgr.go index 943c2a6..c1188b7 100644 --- a/backend/internal/binmgr/binmgr.go +++ b/backend/internal/binmgr/binmgr.go @@ -479,6 +479,25 @@ func InstallViaPackageManager(protocol string) (output string, err error) { return output, nil } +// easyRSAAvailable 判断 easy-rsa 是否可用。 +// 兼容两种安装形态:包管理器装了 /usr/share/easy-rsa/easyrsa(常不在 PATH), +// 或用户自行软链到 PATH。 +func easyRSAAvailable() bool { + if _, err := exec.LookPath("easyrsa"); err == nil { + return true + } + for _, pattern := range []string{ + "/usr/share/easy-rsa/easyrsa", + "/usr/share/easy-rsa/*/easyrsa", + "/usr/local/share/easy-rsa/easyrsa", + } { + if paths, _ := filepath.Glob(pattern); len(paths) > 0 { + return true + } + } + return false +} + // ProtocolAlias 返回协议的实际二进制检测名(导出供 API 使用) func ProtocolAlias(protocol string) string { aliasMap := map[string]string{ @@ -541,6 +560,14 @@ func CheckBinary(name string) BinaryStatus { st.Installed = true st.Path = p st.Source = "system" + // OpenVPN 依赖 easy-rsa 生成 PKI;缺失时标记未就绪, + // 否则页面显示「已就绪」但建隧道时读 ca.crt 会失败。 + if name == "openvpn" && !easyRSAAvailable() { + st.Installed = false + st.Path = p + st.Version = "" + return st + } return st } }