Initial commit: OpenVPN Manager v1.0
OpenVPN Web management console with multi-instance support, client cert issuance, traffic/connection auditing, certificate expiry reminders, auto backup/restore. Stack: - Backend: Go 1.21+ (Gin + JWT) - Frontend: Vue 3 + Element Plus + ECharts + Vite - Storage: JSON file (db.json) + filesystem (pki/, instances/, clients/, backups/) Features: - Multi-instance OpenVPN management (independent port/proto/subnet/PKI) - One-click client certificate issuance with .ovpn (embedded certs) - Certificate expiry reminders (30-day threshold) - Connection log parsing (status-version 3) - Auto backup/restore (tar.gz) - Audit log for all write operations - JWT auth (12h TTL) - One-line install.sh for Ubuntu/Debian/RHEL/Fedora
This commit is contained in:
Executable
+198
@@ -0,0 +1,198 @@
|
||||
#!/usr/bin/env bash
|
||||
# openvpn-manager 一键部署脚本
|
||||
# 适用: Ubuntu 20.04+/Debian 11+/CentOS Stream 9+
|
||||
# 行为: 装依赖 → 编译前端 → 编译 Go 二进制 → 装到 /opt/openvpn-manager → 写 systemd
|
||||
# 用法: sudo ./install.sh [卸载参数 -u] [--port 8089] [--user admin] [--pass xxxx]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
APP_NAME="openvpn-manager"
|
||||
INSTALL_DIR="/opt/openvpn-manager"
|
||||
SERVICE_NAME="openvpn-manager"
|
||||
|
||||
# 默认配置(可被命令行覆盖)
|
||||
PORT=8089
|
||||
ADMIN_USER="admin"
|
||||
ADMIN_PASS="admin123"
|
||||
JWT_SECRET="$(openssl rand -hex 32 2>/dev/null || head -c 64 /dev/urandom | xxd -p -c 64)"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
用法: $0 [选项]
|
||||
-u, --uninstall 卸载(停止服务, 删除 /opt/openvpn-manager 与 systemd 单元)
|
||||
--port PORT Web 监听端口 (默认 8089)
|
||||
--user USER 管理员用户名 (默认 admin)
|
||||
--pass PASS 管理员密码 (默认 admin123)
|
||||
--dir DIR 安装目录 (默认 /opt/openvpn-manager)
|
||||
-h, --help 显示本帮助
|
||||
|
||||
示例:
|
||||
sudo $0
|
||||
sudo $0 --port 9090 --user root --pass 'StrongPass!2026'
|
||||
sudo $0 -u
|
||||
EOF
|
||||
}
|
||||
|
||||
uninstall() {
|
||||
echo "==> 停止并禁用服务"
|
||||
systemctl stop "$SERVICE_NAME" 2>/dev/null || true
|
||||
systemctl disable "$SERVICE_NAME" 2>/dev/null || true
|
||||
rm -f "/etc/systemd/system/${SERVICE_NAME}.service"
|
||||
systemctl daemon-reload
|
||||
echo "==> 删除安装目录 $INSTALL_DIR"
|
||||
rm -rf "$INSTALL_DIR"
|
||||
echo "==> 完成(已保留源码目录, 如需彻底清理请手动 rm -rf 源码目录)"
|
||||
}
|
||||
|
||||
# ---------- 参数解析 ----------
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-u|--uninstall) uninstall; exit 0 ;;
|
||||
--port) PORT="$2"; shift 2 ;;
|
||||
--user) ADMIN_USER="$2"; shift 2 ;;
|
||||
--pass) ADMIN_PASS="$2"; shift 2 ;;
|
||||
--dir) INSTALL_DIR="$2"; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "未知参数: $1"; usage; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ---------- 权限检查 ----------
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "请使用 root 运行: sudo $0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ---------- 发行版识别 ----------
|
||||
. /etc/os-release 2>/dev/null || true
|
||||
echo "==> 操作系统: ${PRETTY_NAME:-unknown}"
|
||||
|
||||
SCRIPTPATH="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
SRC_DIR="$( cd -- "$SCRIPTPATH/.." &> /dev/null && pwd )"
|
||||
echo "==> 源码目录: $SRC_DIR"
|
||||
echo "==> 安装目录: $INSTALL_DIR"
|
||||
|
||||
# ---------- 包管理器 ----------
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
PKG="apt-get"
|
||||
PKG_INSTALL="apt-get install -y --no-install-recommends"
|
||||
PKG_UPDATE="apt-get update -qq"
|
||||
DEPS=(curl ca-certificates openssl openvpn easy-rsa nodejs npm golang-go git)
|
||||
elif command -v dnf >/dev/null 2>&1; then
|
||||
PKG="dnf"
|
||||
PKG_INSTALL="dnf install -y"
|
||||
PKG_UPDATE="dnf makecache -q"
|
||||
DEPS=(curl ca-certificates openssl openvpn easy-rsa nodejs npm golang git)
|
||||
elif command -v yum >/dev/null 2>&1; then
|
||||
PKG="yum"
|
||||
PKG_INSTALL="yum install -y"
|
||||
PKG_UPDATE="yum makecache fast -q"
|
||||
DEPS=(curl ca-certificates openssl openvpn easy-rsa nodejs npm golang git)
|
||||
else
|
||||
echo "不支持的发行版(需 apt/dnf/yum 之一)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "==> 使用包管理器: $PKG"
|
||||
|
||||
echo "==> 更新包索引"
|
||||
$PKG_UPDATE || true
|
||||
|
||||
echo "==> 安装系统依赖"
|
||||
$PKG_INSTALL "${DEPS[@]}" || {
|
||||
echo "依赖安装失败, 请检查网络/源"; exit 1;
|
||||
}
|
||||
|
||||
# ---------- 校验版本 ----------
|
||||
echo "==> 检查工具版本"
|
||||
node -v
|
||||
npm -v
|
||||
go version
|
||||
openssl version
|
||||
openvpn --version | head -1
|
||||
|
||||
# 若 Go < 1.21, 警告但不中断(本项目最低 1.21)
|
||||
GO_VER=$(go version | awk '{print $3}' | sed 's/go//')
|
||||
echo "==> Go 版本: $GO_VER"
|
||||
|
||||
# ---------- 构建前端 ----------
|
||||
echo "==> 构建前端 (npm install + build)"
|
||||
cd "$SRC_DIR/frontend"
|
||||
npm install --include=dev --no-audit --no-fund
|
||||
npm run build
|
||||
|
||||
# ---------- 构建后端 ----------
|
||||
echo "==> 编译 Go 后端二进制"
|
||||
cd "$SRC_DIR/backend"
|
||||
go build -ldflags "-s -w" -o "$SRC_DIR/bin/openvpn-manager" ./cmd/server
|
||||
|
||||
# ---------- 安装 ----------
|
||||
echo "==> 安装到 $INSTALL_DIR"
|
||||
mkdir -p "$INSTALL_DIR"/{bin,data,dist}
|
||||
cp -r "$SRC_DIR/bin/openvpn-manager" "$INSTALL_DIR/bin/"
|
||||
cp -r "$SRC_DIR/dist/"* "$INSTALL_DIR/dist/"
|
||||
|
||||
# 写入环境变量文件(便于 systemd 引用)
|
||||
cat > "$INSTALL_DIR/.env" <<EOF
|
||||
OVPNMGR_HOST=0.0.0.0
|
||||
OVPNMGR_PORT=$PORT
|
||||
OVPNMGR_ADMIN_USER=$ADMIN_USER
|
||||
OVPNMGR_ADMIN_PASS=$ADMIN_PASS
|
||||
OVPNMGR_JWT_SECRET=$JWT_SECRET
|
||||
OVPNMGR_OPENVPN_BIN=$(command -v openvpn)
|
||||
OVPNMGR_EASYRSA_BIN=$(command -v easyrsa || echo easyrsa)
|
||||
EOF
|
||||
chmod 600 "$INSTALL_DIR/.env"
|
||||
|
||||
# 渲染 systemd 单元(替换环境变量)
|
||||
sed -e "s|Environment=OVPNMGR_PORT=.*|Environment=OVPNMGR_PORT=$PORT|" \
|
||||
-e "s|Environment=OVPNMGR_ADMIN_USER=.*|Environment=OVPNMGR_ADMIN_USER=$ADMIN_USER|" \
|
||||
-e "s|Environment=OVPNMGR_ADMIN_PASS=.*|Environment=OVPNMGR_ADMIN_PASS=$ADMIN_PASS|" \
|
||||
-e "s|Environment=OVPNMGR_JWT_SECRET=.*|Environment=OVPNMGR_JWT_SECRET=$JWT_SECRET|" \
|
||||
-e "s|/opt/openvpn-manager|$INSTALL_DIR|g" \
|
||||
"$SRC_DIR/systemd/${SERVICE_NAME}.service" > "/etc/systemd/system/${SERVICE_NAME}.service"
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable "$SERVICE_NAME"
|
||||
systemctl restart "$SERVICE_NAME"
|
||||
|
||||
# ---------- 健康检查 ----------
|
||||
sleep 2
|
||||
HEALTH_URL="http://127.0.0.1:${PORT}/api/health"
|
||||
echo "==> 健康检查 $HEALTH_URL"
|
||||
for i in 1 2 3 4 5; do
|
||||
if curl -fsS "$HEALTH_URL" >/dev/null 2>&1; then
|
||||
echo "✓ 服务已就绪"
|
||||
break
|
||||
fi
|
||||
if [[ $i -eq 5 ]]; then
|
||||
echo "✗ 健康检查失败, 查看: journalctl -u $SERVICE_NAME -n 50"
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# ---------- 完成提示 ----------
|
||||
cat <<EOF
|
||||
|
||||
================================================================
|
||||
OpenVPN Manager 安装完成
|
||||
================================================================
|
||||
访问地址 : http://<服务器IP>:${PORT}
|
||||
用户名 : ${ADMIN_USER}
|
||||
密码 : ${ADMIN_PASS}
|
||||
安装目录 : ${INSTALL_DIR}
|
||||
数据目录 : ${INSTALL_DIR}/data
|
||||
配置单元 : /etc/systemd/system/${SERVICE_NAME}.service
|
||||
|
||||
常用命令:
|
||||
systemctl status ${SERVICE_NAME} # 查看状态
|
||||
systemctl restart ${SERVICE_NAME} # 重启
|
||||
systemctl stop ${SERVICE_NAME} # 停止
|
||||
journalctl -u ${SERVICE_NAME} -f # 跟踪日志
|
||||
${INSTALL_DIR}/bin/openvpn-manager --help
|
||||
|
||||
卸载:
|
||||
sudo $0 -u
|
||||
================================================================
|
||||
EOF
|
||||
Reference in New Issue
Block a user