feat: add web admin panel for node management

Add Flask panel with login, add/delete nodes, and share link copy.
Generate sing-box config from SQLite; add uninstall script and clean install flow.
Panel served at https://DOMAIN:8444 via nginx.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-16 09:10:19 +08:00
parent e8631a0e10
commit bccf6cfdce
21 changed files with 1069 additions and 305 deletions
+8 -9
View File
@@ -1,12 +1,11 @@
#!/usr/bin/env bash
# 生成 Reality 与 Hysteria2 所需密钥,输出到 stdout 并写入 .env
# 生成 Reality 密钥与面板登录密码,写入 .env
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
ENV_FILE="${ROOT_DIR}/.env"
# 依赖 sing-box 生成 reality 密钥对
if ! command -v sing-box &>/dev/null; then
echo "sing-box 未安装,使用临时下载..." >&2
TMP="$(mktemp -d)"
@@ -16,31 +15,28 @@ if ! command -v sing-box &>/dev/null; then
aarch64) SB_ARCH="arm64" ;;
*) echo "不支持的架构: $ARCH" >&2; exit 1 ;;
esac
curl -fsSL "https://github.com/SagerNet/sing-box/releases/latest/download/sing-box-1.11.0-linux-${SB_ARCH}.tar.gz" \
curl -fsSL "https://github.com/SagerNet/sing-box/releases/download/v1.11.0/sing-box-1.11.0-linux-${SB_ARCH}.tar.gz" \
| tar -xz -C "$TMP" --strip-components=1
SB="$TMP/sing-box"
else
SB="sing-box"
fi
UUID="$("$SB" generate uuid)"
KEYPAIR="$("$SB" generate reality-keypair)"
PRIVATE_KEY="$(echo "$KEYPAIR" | grep 'PrivateKey:' | awk '{print $2}')"
PUBLIC_KEY="$(echo "$KEYPAIR" | grep 'PublicKey:' | awk '{print $2}')"
SHORT_ID="$("$SB" generate rand --hex 8)"
HY2_PASSWORD="$("$SB" generate rand --base64 32 | tr -d '/+=' | head -c 24)"
PANEL_PASSWORD="$("$SB" generate rand --base64 32 | tr -d '/+=' | head -c 20)"
echo "========== 生成的密钥 =========="
echo "UUID: $UUID"
echo "REALITY_PRIVATE_KEY: $PRIVATE_KEY"
echo "REALITY_PUBLIC_KEY: $PUBLIC_KEY"
echo "REALITY_SHORT_ID: $SHORT_ID"
echo "HY2_PASSWORD: $HY2_PASSWORD"
echo "PANEL_PASSWORD: $PANEL_PASSWORD"
echo "================================"
if [[ -f "$ENV_FILE" ]]; then
# 更新或追加 .env 中的密钥字段
for var in UUID REALITY_PRIVATE_KEY REALITY_PUBLIC_KEY REALITY_SHORT_ID HY2_PASSWORD; do
for var in REALITY_PRIVATE_KEY REALITY_PUBLIC_KEY REALITY_SHORT_ID PANEL_PASSWORD; do
val="${!var}"
if grep -q "^${var}=" "$ENV_FILE" 2>/dev/null; then
sed -i "s|^${var}=.*|${var}=${val}|" "$ENV_FILE"
@@ -48,6 +44,9 @@ if [[ -f "$ENV_FILE" ]]; then
echo "${var}=${val}" >> "$ENV_FILE"
fi
done
if ! grep -q "^PANEL_USERNAME=" "$ENV_FILE" 2>/dev/null; then
echo "PANEL_USERNAME=admin" >> "$ENV_FILE"
fi
echo "已写入 $ENV_FILE"
else
echo "提示: 先复制 .env.example 为 .env 并填写 VPS_IP、DOMAIN 等,再重新运行本脚本" >&2