From 1f36a76ce02f35c4de7aea2d423a835857a7577c Mon Sep 17 00:00:00 2001 From: dekun Date: Sat, 11 Jul 2026 13:49:20 +0800 Subject: [PATCH] feat: add bootstrap one-click deploy and update deployment docs Co-authored-by: Cursor --- .gitignore | 3 +- README.md | 61 ++--- client/sing-box-client.json.template | 85 ------- docs/DEPLOY.md | 194 +++++++++++----- docs/README.md | 12 +- docs/STACK.md | 24 +- scripts/bootstrap.sh | 326 +++++++++++++++++++++++++++ scripts/finish-install.sh | 3 - scripts/install.sh | 6 +- scripts/render-client.sh | 33 --- scripts/uninstall.sh | 1 - 11 files changed, 525 insertions(+), 223 deletions(-) delete mode 100644 client/sing-box-client.json.template create mode 100644 scripts/bootstrap.sh delete mode 100644 scripts/finish-install.sh delete mode 100644 scripts/render-client.sh diff --git a/.gitignore b/.gitignore index d0d7186..fd36a80 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ -# 部署生成的客户端配置与运行时数据 -client/generated/ +# 运行时数据 data/ panel/venv/ __pycache__/ diff --git a/README.md b/README.md index c11f7ee..d5b4f54 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ | 文档 | 说明 | |------|------| -| **[docs/DEPLOY.md](docs/DEPLOY.md)** | 部署指南(安全组、安装、升级、验证) | +| **[docs/DEPLOY.md](docs/DEPLOY.md)** | 部署指南(**前期准备、端口、一键安装**) | | **[docs/GUIDE.md](docs/GUIDE.md)** | 使用说明(面板、节点、客户端、维护) | | **[docs/client-import.md](docs/client-import.md)** | 客户端导入 Hy2 链接 | | **[docs/troubleshooting.md](docs/troubleshooting.md)** | 故障排查 | @@ -25,21 +25,36 @@ --- +## 部署前准备 + +| # | 项目 | 要求 | +|---|------|------| +| 1 | VPS | Ubuntu 22.04 / 24.04,root 权限 | +| 2 | 域名 | A 记录指向 VPS 公网 IP | +| 3 | 安全组 | 放行下方端口 | + +### 需要开放的端口 + +| 端口 | 协议 | 用途 | +|------|------|------| +| 22 | TCP | SSH | +| 80 | TCP | ACME 证书验证 | +| 443 | TCP | HTTPS 管理面板 | +| **8443–8499** | **UDP** | Hysteria2 代理(多节点递增) | + +> Hy2 走 **UDP**,安全组必须放行 **8443–8499/UDP 整段**。详细说明见 **[docs/DEPLOY.md](docs/DEPLOY.md)**。 + +--- + ## 快速部署 -```bash -ssh root@YOUR_VPS_IP +SSH 登录新 VPS 后,一条命令完成部署(自动 clone,交互输入域名/邮箱/账号): -apt update && apt install -y git -git clone https://git.bz121.com/dekun/jiedian.git /opt/jiedian -cd /opt/jiedian -cp .env.example .env # 填写 VPS_IP、DOMAIN、ACME_EMAIL -bash scripts/install.sh +```bash +curl -fsSL https://git.bz121.com/dekun/jiedian/raw/main/scripts/bootstrap.sh | bash ``` -安装完成后浏览器打开面板 → 登录 → **添加节点** → 复制 **Hy2 链接** 到 v2rayN / v2rayNG。 - -详细步骤见 **[docs/DEPLOY.md](docs/DEPLOY.md)**。 +安装完成后会输出面板地址、用户名和密码。浏览器打开 → 登录 → **添加节点** → 复制 **Hy2 链接** 到 v2rayN / v2rayNG。 --- @@ -62,19 +77,6 @@ bash scripts/install.sh --- -## 端口与防火墙 - -| 端口 | 协议 | 用途 | -|------|------|------| -| 22 | TCP | SSH | -| 80 | TCP | HTTP(ACME 证书验证 + 跳转 HTTPS) | -| 443 | TCP | **HTTPS 管理面板** | -| 8443–8499 | UDP | Hysteria2(每节点递增) | - -云厂商安全组需放行 **443/TCP** 与 **8443–8499/UDP**。 - ---- - ## 常用命令 ```bash @@ -89,8 +91,8 @@ cd /opt/jiedian && git pull python3 scripts/render-server.py systemctl restart sing-box jiedian-panel -# 从旧版(含 VLESS)迁移 -bash scripts/remove-vless.sh +# 重置面板密码 +bash scripts/generate-keys.sh ``` --- @@ -103,11 +105,10 @@ bash scripts/remove-vless.sh ├── data/nodes.db # 节点数据库 ├── panel/ # Flask 管理面板 ├── scripts/ -│ ├── install.sh # 一键部署 +│ ├── bootstrap.sh # 一键部署入口(自动 clone + 交互配置) +│ ├── install.sh # 核心安装逻辑 │ ├── uninstall.sh # 卸载 -│ ├── remove-vless.sh # 旧版停用 VLESS -│ ├── enable-panel-https.sh # 启用 HTTPS 面板 -│ ├── generate-keys.sh # 生成/重置面板密码 +│ ├── generate-keys.sh # 重置面板密码 │ └── render-server.py # 生成 sing-box 配置 └── docs/ # 文档 ``` diff --git a/client/sing-box-client.json.template b/client/sing-box-client.json.template deleted file mode 100644 index 541c902..0000000 --- a/client/sing-box-client.json.template +++ /dev/null @@ -1,85 +0,0 @@ -{ - "log": { - "level": "info" - }, - "dns": { - "servers": [ - { - "tag": "remote", - "address": "tls://8.8.8.8", - "detour": "proxy" - }, - { - "tag": "local", - "address": "223.5.5.5", - "detour": "direct" - } - ], - "rules": [ - { - "outbound": "any", - "server": "local" - } - ], - "final": "remote" - }, - "inbounds": [ - { - "type": "mixed", - "tag": "mixed-in", - "listen": "127.0.0.1", - "listen_port": 7890 - }, - { - "type": "tun", - "tag": "tun-in", - "interface_name": "sing-tun", - "address": ["172.19.0.1/30"], - "mtu": 9000, - "auto_route": true, - "strict_route": true, - "stack": "mixed" - } - ], - "outbounds": [ - { - "type": "selector", - "tag": "proxy", - "outbounds": ["hysteria2", "direct"] - }, - { - "type": "hysteria2", - "tag": "hysteria2", - "server": "${DOMAIN}", - "server_port": 8443, - "password": "${HY2_PASSWORD}", - "tls": { - "enabled": true, - "server_name": "${DOMAIN}", - "alpn": ["h3"] - } - }, - { - "type": "direct", - "tag": "direct" - }, - { - "type": "dns", - "tag": "dns-out" - } - ], - "route": { - "rules": [ - { - "protocol": "dns", - "outbound": "dns-out" - }, - { - "ip_is_private": true, - "outbound": "direct" - } - ], - "final": "proxy", - "auto_detect_interface": true - } -} diff --git a/docs/DEPLOY.md b/docs/DEPLOY.md index 2c2af69..d092135 100644 --- a/docs/DEPLOY.md +++ b/docs/DEPLOY.md @@ -12,68 +12,143 @@ --- -## 一、部署前准备 +## 一、部署前准备(必读) -### 1. 购买 VPS 并获取 root 登录 +部署前请逐项完成以下准备。**端口未放行或 DNS 未解析会导致安装失败或客户端连不上。** -建议使用境外 VPS,带宽 ≥ 30Mbps。记录: +### 准备清单 -- 公网 IP(写入 `.env` 的 `VPS_IP`) +| # | 项目 | 要求 | +|---|------|------| +| 1 | VPS | Ubuntu 22.04 / 24.04,root 或 sudo,建议带宽 ≥ 30Mbps | +| 2 | 域名 | 已注册,可添加 DNS 记录 | +| 3 | DNS | 域名 **A 记录** 指向 VPS 公网 IP | +| 4 | 安全组 | 云厂商控制台放行下方端口(见下表) | +| 5 | 系统防火墙 | 安装脚本会自动配置 UFW,无需手动操作 | + +### 需要开放的端口 + +**云厂商安全组**与 **VPS 防火墙**均需放行(安装脚本会配置 UFW,但安全组必须在控制台手动开)。 + +| 端口 | 协议 | 方向 | 用途 | 必须 | +|------|------|------|------|------| +| **22** | TCP | 入站 | SSH 远程登录 | 是 | +| **80** | TCP | 入站 | ACME 证书验证(Let's Encrypt) | 是 | +| **443** | TCP | 入站 | **HTTPS 管理面板** | 是 | +| **8443–8499** | **UDP** | 入站 | **Hysteria2 代理**(多节点递增) | 是 | + +> **重要** +> +> - Hy2 使用 **UDP**,不是 TCP。安全组必须放行 **8443–8499/UDP 整段**,不能只开 8443。 +> - 每增加一个节点,Hy2 端口 +1(8443、8444、8445…)。预留 8443–8499 可支持约 57 个节点。 +> - 面板走 **443/TCP**,客户端代理走 **8443+/UDP**,两者都需要。 + +### 各组件端口对照 + +| 组件 | 端口 | 协议 | 说明 | +|------|------|------|------| +| SSH | 22 | TCP | 部署与运维 | +| Nginx | 80 | TCP | 证书申请 + HTTP 跳转 HTTPS | +| Nginx | 443 | TCP | 管理面板 HTTPS | +| sing-box | 8443 | UDP | 第 1 个节点 Hy2 | +| sing-box | 8444 | UDP | 第 2 个节点 Hy2 | +| sing-box | 8445… | UDP | 后续节点依次 +1 | + +### 1. 购买 VPS + +记录: + +- 公网 IP(一键部署会自动检测并写入 `.env`) - SSH 登录方式(密码或密钥) ### 2. 域名与 DNS -将域名 **A 记录** 解析到 VPS 公网 IP(用于 Hy2 TLS 证书与面板访问): +将域名 **A 记录** 解析到 VPS 公网 IP: ``` your.domain.com → YOUR_VPS_IP ``` -验证: +验证(在本地或 VPS 上执行): ```bash dig +short A your.domain.com -# 应返回 VPS IP +# 应返回 VPS 公网 IP ``` -### 3. 云厂商安全组 +DNS 未生效时,证书申请会失败。一键部署脚本会检测并提示。 -在阿里云 / 腾讯云等控制台放行: +### 3. 云厂商安全组配置示例 -| 端口 | 协议 | 用途 | 必须 | -|------|------|------|------| -| 22 | TCP | SSH | 是 | -| 80 | TCP | ACME 证书验证 | 是 | -| 443 | TCP | **HTTPS 管理面板** | 是 | -| 8443–8499 | UDP | Hysteria2(多节点递增) | 是 | +**阿里云 / 腾讯云 / AWS 等**:进入 VPS 实例 → 安全组 → 入站规则,添加上表中的端口。 -> **重要**:每增加一个节点,Hy2 端口 +1(8443、8444、8445…)。安全组必须放行 **8443–8499/UDP** 整段,不能只开 8443。 +常见错误: -### 4. 填写 `.env` +| 错误 | 后果 | +|------|------| +| 只开 8443/UDP,未开 8444–8499 | 第 2 个节点起客户端连不上 | +| Hy2 端口写成 TCP | 客户端延迟 `-1` 或无法连接 | +| 未开 80/TCP | Let's Encrypt 证书申请失败 | +| 未开 443/TCP | 管理面板无法 HTTPS 访问 | -```bash -git clone https://git.bz121.com/dekun/jiedian.git /opt/jiedian -cd /opt/jiedian -cp .env.example .env -nano .env -``` +### 4. 部署时需要的信息 -| 变量 | 必填 | 说明 | +一键部署时会交互询问(或命令行传入): + +| 项目 | 必填 | 说明 | |------|------|------| -| `VPS_IP` | 是 | VPS 公网 IP | -| `DOMAIN` | 是 | 已解析到 VPS 的域名 | -| `ACME_EMAIL` | 是 | Let's Encrypt 申请证书邮箱 | -| `PANEL_USERNAME` | 否 | 面板登录用户名,默认 `admin` | -| `PANEL_PASSWORD` | 否 | 面板密码;留空则安装时自动生成 | -| `PANEL_PATH` | 否 | 面板 URL 路径;留空则自动生成如 `jiedian-a1b2c3d4` | -| `PANEL_ALLOW_IP` | 否 | 仅允许指定 IP 访问面板(可选) | +| 域名 | 是 | 已解析到 VPS 的域名 | +| 证书邮箱 | 是 | Let's Encrypt 申请用 | +| 面板用户名 | 否 | 默认 `admin` | +| 面板密码 | 否 | 留空则自动生成 | -`CLASH_API_SECRET` 由 `install.sh` 自动生成,供面板读取连接统计,无需手动填写。 +以下由脚本自动处理,**无需手动填写**: + +| 项目 | 说明 | +|------|------| +| `VPS_IP` | 自动检测公网 IP | +| `PANEL_PATH` | 自动生成随机路径(如 `jiedian-a1b2c3d4`) | +| `CLASH_API_SECRET` | 自动生成,供面板读取连接统计 | + +### 5. 手动配置(可选) + +若不用一键部署、需自定义 `.env`,见 [手动安装](#手动安装备选)。 --- ## 二、一键安装(新机器) +SSH 登录 VPS 后执行(**无需先 clone**,脚本会自动 clone 到 `/opt/jiedian`): + +```bash +curl -fsSL https://git.bz121.com/dekun/jiedian/raw/main/scripts/bootstrap.sh | bash +``` + +按提示输入域名、证书邮箱、面板用户名和密码即可。 + +脚本会自动: + +1. 检测公网 IP,校验 DNS +2. clone 仓库到 `/opt/jiedian` +3. 写入 `.env`,调用 `install.sh` +4. 安装 sing-box、nginx、Python 面板 +5. 配置 UFW(22/80/443 TCP + 8443–8499 UDP) +6. 申请 TLS 证书,启动服务 +7. 输出面板地址、用户名、密码 + +**非交互模式**(适合脚本化): + +```bash +curl -fsSL https://git.bz121.com/dekun/jiedian/raw/main/scripts/bootstrap.sh | bash -s -- \ + --domain your.domain.com \ + --email you@example.com \ + --username admin \ + --password 'your-password' \ + --yes +``` + +### 手动安装(备选) + ```bash ssh root@YOUR_VPS_IP @@ -85,24 +160,28 @@ cp .env.example .env bash scripts/install.sh ``` -安装脚本会自动完成: - -1. 安装 sing-box、nginx、Python 面板依赖 -2. 配置 UFW 防火墙(22/80/443 TCP,8443–8499 UDP) -3. 通过 acme.sh 为 `DOMAIN` 申请 TLS 证书 -4. 初始化 SQLite 节点库与默认管理员 -5. 生成 sing-box 配置、启用 **HTTPS 面板**并启动服务 +| 变量 | 必填 | 说明 | +|------|------|------| +| `VPS_IP` | 是 | VPS 公网 IP | +| `DOMAIN` | 是 | 已解析到 VPS 的域名 | +| `ACME_EMAIL` | 是 | Let's Encrypt 申请证书邮箱 | +| `PANEL_USERNAME` | 否 | 面板登录用户名,默认 `admin` | +| `PANEL_PASSWORD` | 否 | 面板密码;留空则安装时自动生成 | +| `PANEL_PATH` | 否 | 面板 URL 路径;留空则自动生成 | +| `PANEL_ALLOW_IP` | 否 | 仅允许指定 IP 访问面板(可选) | 安装结束输出示例: ``` -========================================== - 管理面板: https://66.hyf2.cc/jiedian-xxxx/ - (HTTP 会自动跳转到 HTTPS) - 面板路径: jiedian-xxxx - 用户名: dekun - 密码: xxxxx -========================================== +╔══════════════════════════════════════════════════════╗ +║ 部署完成 ║ +╠══════════════════════════════════════════════════════╣ +║ 面板地址: https://66.hyf2.cc/jiedian-xxxx/ +║ 用户名: admin +║ 密码: xxxxxxxxx +╠══════════════════════════════════════════════════════╣ +║ 凭证已保存: /root/jiedian-credentials.txt +╚══════════════════════════════════════════════════════╝ ``` 浏览器打开面板地址 → 登录 → **添加节点** → 复制 **Hysteria2** 链接到客户端。 @@ -123,6 +202,9 @@ sing-box check -c /etc/sing-box/config.json # Hy2 端口监听(默认 8443,多节点还有 8444…) ss -ulnp | grep 8443 +# UFW 规则(确认 UDP 8443-8499 已放行) +ufw status + # 面板 HTTPS 可访问(应返回 200/302) PANEL_PATH=$(grep ^PANEL_PATH= /opt/jiedian/.env | cut -d= -f2) curl -Ik "https://$(grep ^DOMAIN= /opt/jiedian/.env | cut -d= -f2)/${PANEL_PATH}/login" @@ -141,9 +223,13 @@ python3 scripts/render-server.py systemctl restart sing-box jiedian-panel ``` -### 从旧版(含 VLESS/Xray)升级到仅 Hy2 +仅更新面板前端/代码、未改 sing-box 配置时: -若你之前部署过带 VLESS Reality 的版本: +```bash +cd /opt/jiedian && git pull && systemctl restart jiedian-panel +``` + +### 从旧版(含 VLESS/Xray)升级到仅 Hy2 ```bash cd /opt/jiedian @@ -151,15 +237,6 @@ git pull sudo bash scripts/remove-vless.sh ``` -该脚本会: - -- 停止并禁用 Xray -- 重载 sing-box 配置 -- **启用 HTTPS 管理面板(443)** -- 重启面板 - -完成后客户端 **删除所有 VLESS 节点**,从面板复制 `hy2://` 链接,并用 **HTTPS** 登录面板。 - ### 已有 VPS 仅升级 HTTPS 面板 ```bash @@ -187,8 +264,7 @@ systemctl restart sing-box ```bash cd /opt/jiedian bash scripts/uninstall.sh -# 保留 .env 与代码,清理 data/ 与 venv -bash scripts/install.sh +bash scripts/bootstrap.sh # 或 bash scripts/install.sh ``` --- diff --git a/docs/README.md b/docs/README.md index 094b493..1f5a137 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,7 +2,7 @@ | 文档 | 适用对象 | 内容 | |------|----------|------| -| **[DEPLOY.md](DEPLOY.md)** | 运维 / 首次部署 | VPS 安装、安全组、`.env`、升级、验证 | +| **[DEPLOY.md](DEPLOY.md)** | 运维 / 首次部署 | **前期准备、端口放行、一键安装**、升级、验证 | | **[GUIDE.md](GUIDE.md)** | 日常使用 | 面板操作、节点管理、Hy2 说明、安全建议 | | **[client-import.md](client-import.md)** | 客户端用户 | Windows / Android / iOS 导入 Hy2 链接 | | **[troubleshooting.md](troubleshooting.md)** | 排错 | 连不上、面板打不开、迁移 | @@ -12,6 +12,12 @@ - 仓库:https://git.bz121.com/dekun/jiedian.git - 部署目录:`/opt/jiedian` -- 一键安装:`bash scripts/install.sh`(自动 HTTPS 面板) +- **一键部署**:`curl -fsSL https://git.bz121.com/dekun/jiedian/raw/main/scripts/bootstrap.sh | bash` - 旧版去 VLESS:`bash scripts/remove-vless.sh` -- 单独启用 HTTPS:`bash scripts/enable-panel-https.sh` + +## 部署前必做 + +1. 域名 A 记录 → VPS 公网 IP +2. 安全组放行:**22/TCP、80/TCP、443/TCP、8443–8499/UDP** + +详见 **[DEPLOY.md](DEPLOY.md)**。 diff --git a/docs/STACK.md b/docs/STACK.md index 6c6820e..76e5823 100644 --- a/docs/STACK.md +++ b/docs/STACK.md @@ -5,16 +5,21 @@ | 组件 | 用途 | |------|------| | **sing-box** | Hysteria2 服务端、Clash API 统计、多 inbound 按节点分端口 | -| **Nginx** | ACME 验证、管理面板反代(HTTP 80) | +| **Nginx** | ACME 验证、HTTPS 管理面板反代 | | **Flask 面板** | 添加/删除节点、复制 Hy2 链接、在线与流量统计 | ## 端口 -| 端口 | 协议 | 进程 | 说明 | -|------|------|------|------| -| 80 | TCP | Nginx | ACME 验证 + 跳转 HTTPS | -| 443 | TCP | Nginx | **HTTPS 管理面板** | -| 8443–8499 | UDP | sing-box | Hy2,每节点 +1 | +部署前需在云厂商安全组放行以下端口(安装脚本会同步配置 UFW): + +| 端口 | 协议 | 进程 | 方向 | 说明 | +|------|------|------|------|------| +| 22 | TCP | sshd | 入站 | SSH 运维 | +| 80 | TCP | Nginx | 入站 | ACME 证书验证 + 跳转 HTTPS | +| 443 | TCP | Nginx | 入站 | **HTTPS 管理面板** | +| 8443–8499 | **UDP** | sing-box | 入站 | **Hy2 代理**,每节点端口 +1 | + +> Hy2 使用 UDP。安全组必须放行 **8443–8499/UDP 整段**,不能只开 8443。 ## 配置生成 @@ -23,3 +28,10 @@ | `render-server.py` | `/etc/sing-box/config.json` | 增删节点后运行 `render-server.py` 并 `systemctl restart sing-box`。 + +## 部署入口 + +| 脚本 | 用途 | +|------|------| +| `bootstrap.sh` | 一键部署(自动 clone、交互配置、调用 install.sh) | +| `install.sh` | 核心安装(sing-box / nginx / 证书 / 面板) | diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh new file mode 100644 index 0000000..059497f --- /dev/null +++ b/scripts/bootstrap.sh @@ -0,0 +1,326 @@ +#!/usr/bin/env bash +# jiedian 一键部署入口:自动 clone、交互配置、调用 install.sh +# 用法: +# curl -fsSL https://git.bz121.com/dekun/jiedian/raw/main/scripts/bootstrap.sh | bash +# bash scripts/bootstrap.sh +# 非交互: +# bash scripts/bootstrap.sh --domain example.com --email you@example.com --yes +set -euo pipefail + +INSTALL_DIR="/opt/jiedian" +REPO_URL="https://git.bz121.com/dekun/jiedian.git" +REPO_BRANCH="main" +CREDS_FILE="/root/jiedian-credentials.txt" + +RED='\033[0;31m' +GREEN='\033[0;32m' +CYAN='\033[0;36m' +YELLOW='\033[1;33m' +BOLD='\033[1m' +NC='\033[0m' + +log() { echo -e "${GREEN}[+]${NC} $*"; } +warn() { echo -e "${YELLOW}[!]${NC} $*"; } +err() { echo -e "${RED}[!]${NC} $*" >&2; exit 1; } + +usage() { + cat <<'EOF' +用法: + curl -fsSL https://git.bz121.com/dekun/jiedian/raw/main/scripts/bootstrap.sh | bash + + bash scripts/bootstrap.sh [选项] + +选项: + --domain DOMAIN 域名(Hy2 + 面板 HTTPS) + --email EMAIL Let's Encrypt 证书邮箱 + --username USER 面板登录用户名(默认 admin) + --password PASS 面板登录密码(留空则随机生成) + --yes, -y 跳过确认 + -h, --help 显示帮助 +EOF +} + +ensure_repo() { + if [[ -d "$INSTALL_DIR/.git" ]] && [[ -f "$INSTALL_DIR/scripts/install.sh" ]]; then + return 0 + fi + + log "安装 git ..." + export DEBIAN_FRONTEND=noninteractive + apt-get update -qq + apt-get install -y -qq git ca-certificates curl + + if [[ -d "$INSTALL_DIR" ]] && [[ ! -d "$INSTALL_DIR/.git" ]]; then + warn "目录 $INSTALL_DIR 已存在但不是 git 仓库,将备份为 ${INSTALL_DIR}.bak" + mv "$INSTALL_DIR" "${INSTALL_DIR}.bak.$(date +%s)" + fi + + log "克隆仓库到 $INSTALL_DIR ..." + git clone --depth 1 -b "$REPO_BRANCH" "$REPO_URL" "$INSTALL_DIR" +} + +reexec_from_repo() { + [[ "${JIEDIAN_BOOTSTRAP_FROM_REPO:-}" == "1" ]] && return 0 + local repo_bootstrap="$INSTALL_DIR/scripts/bootstrap.sh" + [[ -f "$repo_bootstrap" ]] || return 0 + + local src="${BASH_SOURCE[0]:-}" + case "$src" in + "$repo_bootstrap"|*/jiedian/scripts/bootstrap.sh) return 0 ;; + esac + + export JIEDIAN_BOOTSTRAP_FROM_REPO=1 + log "使用仓库内 bootstrap 继续 ..." + exec bash "$repo_bootstrap" "$@" +} + +check_root() { + [[ $EUID -eq 0 ]] || err "请使用 root 运行(或 sudo bash bootstrap.sh)" +} + +check_os() { + [[ -f /etc/os-release ]] || err "无法识别操作系统" + # shellcheck disable=SC1091 + source /etc/os-release + [[ "${ID:-}" == "ubuntu" ]] || err "仅支持 Ubuntu,当前: ${ID:-unknown}" + case "${VERSION_ID:-}" in + 22.04|24.04) ;; + *) err "仅支持 Ubuntu 22.04 / 24.04,当前: ${VERSION_ID:-unknown}" ;; + esac +} + +detect_public_ip() { + curl -4 -fsSL --connect-timeout 5 ifconfig.me 2>/dev/null \ + || curl -4 -fsSL --connect-timeout 5 ip.sb 2>/dev/null \ + || curl -4 -fsSL --connect-timeout 5 icanhazip.com 2>/dev/null \ + || err "无法检测公网 IP,请检查网络" +} + +resolve_domain() { + local domain="$1" + if command -v dig >/dev/null 2>&1; then + dig +short A "$domain" @8.8.8.8 2>/dev/null | grep -E '^[0-9.]+$' | head -1 + return 0 + fi + getent ahostsv4 "$domain" 2>/dev/null | awk '{print $1; exit}' +} + +valid_domain() { + [[ "$1" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$ ]] +} + +valid_email() { + [[ "$1" == *"@"* ]] && [[ "$1" == *"."* ]] +} + +prompt_if_empty() { + local var_name="$1" + local prompt="$2" + local default="${3:-}" + local secret="${4:-0}" + local value="" + + if [[ -n "${!var_name:-}" ]]; then + return 0 + fi + + if [[ -n "$default" ]]; then + prompt="$prompt [$default]" + fi + + if [[ "$secret" == "1" ]]; then + read -r -s -p "$prompt: " value + echo "" + else + read -r -p "$prompt: " value + fi + + if [[ -z "$value" && -n "$default" ]]; then + value="$default" + fi + + printf -v "$var_name" '%s' "$value" +} + +generate_password() { + openssl rand -base64 32 | tr -d '/+=' | head -c 20 +} + +write_env_file() { + local env_file="$INSTALL_DIR/.env" + cat > "$env_file" < "$CREDS_FILE" </dev/null 2>&1; then + PANEL_PASSWORD="$(sing-box generate rand --base64 32 | tr -d '/+=' | head -c 20)" + else + PANEL_PASSWORD="$(openssl rand -base64 32 | tr -d '/+=' | head -c 20)" + fi if grep -q "^PANEL_PASSWORD=" "$ENV_FILE" 2>/dev/null; then sed -i "s|^PANEL_PASSWORD=.*|PANEL_PASSWORD=${PANEL_PASSWORD}|" "$ENV_FILE" else diff --git a/scripts/render-client.sh b/scripts/render-client.sh deleted file mode 100644 index 3cf6dcb..0000000 --- a/scripts/render-client.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash -# 本地根据 .env 渲染客户端配置(无需在 VPS 上运行) -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ROOT_DIR="$(dirname "$SCRIPT_DIR")" -ENV_FILE="${ROOT_DIR}/.env" -OUT_DIR="${ROOT_DIR}/client/generated" - -[[ -f "$ENV_FILE" ]] || { echo "缺少 .env,请先 cp .env.example .env 并填写"; exit 1; } -# shellcheck disable=SC1090 -source "$ENV_FILE" - -for var in DOMAIN HY2_PASSWORD; do - [[ -n "${!var:-}" ]] || { echo "缺少 .env 变量: $var"; exit 1; } -done - -mkdir -p "$OUT_DIR" - -HY2_PASSWORD_ENC="$(python3 -c "import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=''))" "$HY2_PASSWORD")" - -sed -e "s|\${DOMAIN}|${DOMAIN}|g" \ - -e "s|\${HY2_PASSWORD}|${HY2_PASSWORD}|g" \ - "$ROOT_DIR/client/sing-box-client.json.template" > "$OUT_DIR/sing-box-client.json" - -cat > "$OUT_DIR/share-links.txt" <