diff --git a/install/build_master.sh b/install/build_master.sh new file mode 100755 index 00000000..5445c61a --- /dev/null +++ b/install/build_master.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# ========================================================== +# 模块名称: build_master.sh (v4.3.0 Orchestrator) +# 核心功能: Master 安装业务总指挥 +# ========================================================== + +MODULES=( + "env_setup.sh" + "master_setup.sh" +) + +echo "⏳ 正在装载中枢底层设施依赖..." + +for mod in "${MODULES[@]}"; do + curl -fsSL --connect-timeout 10 --retry 3 "${REPO_RAW_URL}/install/${mod}" -o "${SECURE_TMP}/${mod}" + if [ ! -s "${SECURE_TMP}/${mod}" ]; then + echo -e "\033[31m❌ 致命错误:中枢依赖模块 [${mod}] 装载失败!\033[0m" + exit 1 + fi + source "${SECURE_TMP}/${mod}" +done + +echo -e "\033[32m✅ 中枢模块装载完毕,正在进入部署流程...\033[0m" + +# --- 核心业务编排流 --- + +# [复用模块: env_setup.sh] +do_master_env_precheck # 预检 +do_fetch_master_version # 抓取版本 +do_master_handle_menu # OTA 拦截与菜单选择 +do_install_deps # 安装 sqlite3 等依赖 + +# 如果选择卸载,模块内部会 exit + +# [专属模块: master_setup.sh] +do_master_clean_env # 验证环境与保护 DB +do_master_config # 交互获取 Token 并生成 conf +do_master_init_db # 初始化 SQLite 表结构 +do_master_deploy_core # 覆写内核并注入守护进程 +do_master_summary # 打印状态汇报与回执 diff --git a/install/master_setup.sh b/install/master_setup.sh new file mode 100755 index 00000000..55c969a5 --- /dev/null +++ b/install/master_setup.sh @@ -0,0 +1,328 @@ +#!/bin/bash +# ========================================================== +# 模块名称: master_setup.sh +# 核心功能: Master 环境清洗、令牌交互、SQLite 建库、守护进程注入与结果呈现 +# ========================================================== + +# ---------------------------------------------------------- +# [时序 M.1] 解析版本锚点 (复用/补充) +# ---------------------------------------------------------- +do_fetch_master_version() { + TARGET_VERSION=$( (curl -fsSL --connect-timeout 5 --retry 2 "${REPO_RAW_URL}/version.txt" || curl -4 -fsSL --connect-timeout 5 --retry 2 "${REPO_RAW_URL}/version.txt") 2>/dev/null | grep "^MASTER_VERSION=" | cut -d'=' -f2 | tr -d '[:space:]') + TARGET_VERSION=${TARGET_VERSION:-"4.0.7"} + + MASTER_DIR="/opt/ip_sentinel_master" + DB_FILE="${MASTER_DIR}/sentinel.db" + + echo "========================================================" + echo " 🧠 欢迎使用 IP-Sentinel Master (控制中枢) v${TARGET_VERSION}" + echo "========================================================" +} + +# ---------------------------------------------------------- +# [时序 M.2] 拦截交互菜单 / OTA 静默重载判定 +# ---------------------------------------------------------- +do_master_handle_menu() { + if [ "$SILENT_MASTER_OTA" == "true" ]; then + echo -e "\n⏳ [OTA] 中枢重构指令已确认,正在剥离控制台交互..." + ACTION_CHOICE=1 + UPGRADE_MODE="true" + KEEP_DB="true" + + if [ -f "${MASTER_DIR}/master.conf" ]; then + source "${MASTER_DIR}/master.conf" + + if grep -q "^MASTER_VERSION=" "${MASTER_DIR}/master.conf"; then + sed -i "s/^MASTER_VERSION=.*/MASTER_VERSION=\"$TARGET_VERSION\"/" "${MASTER_DIR}/master.conf" + else + echo "MASTER_VERSION=\"$TARGET_VERSION\"" >> "${MASTER_DIR}/master.conf" + fi + fi + echo -e "\033[32m✅ 已激活 [中枢静默重构模式],即将无损覆写内核...\033[0m" + else + echo -e "\n请选择操作:" + echo " 1) 🚀 部署 Master 控制中枢" + echo " 2) 🗑️ 一键卸载 Master 中枢" + read -p "请输入选择 [1-2] (默认1): " ACTION_CHOICE + + ACTION_CHOICE=${ACTION_CHOICE:-1} + + if [ "$ACTION_CHOICE" == "2" ]; then + echo -e "\n⏳ 正在拉取卸载程序..." + curl -fsSL --connect-timeout 10 --retry 3 "${REPO_RAW_URL}/master/uninstall_master.sh" -o "${SECURE_TMP}/uninstall_master.sh" + chmod +x "${SECURE_TMP}/uninstall_master.sh" + bash "${SECURE_TMP}/uninstall_master.sh" + rm -f "/tmp/uninstall_master.sh" + exit 0 + fi + + # [态势传承] 平滑接管探查并保护库文件 + UPGRADE_MODE="false" + KEEP_DB="true" + + if [ "$ACTION_CHOICE" == "1" ] && [ -f "${MASTER_DIR}/master.conf" ]; then + echo -e "\n\033[33m💡 司令部雷达提示:检测到本机已部署过 Master 中枢。\033[0m" + read -p "👉 是否按原配置直接进行平滑升级?(y/n, 默认y): " UPGRADE_CHOICE + if [[ -z "$UPGRADE_CHOICE" || "$UPGRADE_CHOICE" =~ ^[Yy]$ ]]; then + UPGRADE_MODE="true" + read -p "👉 是否保留历史节点数据库 (SQLite)?(y/n, 默认y): " DB_CHOICE + if [[ "$DB_CHOICE" =~ ^[Nn]$ ]]; then + KEEP_DB="false" + fi + + source "${MASTER_DIR}/master.conf" + + if grep -q "^MASTER_VERSION=" "${MASTER_DIR}/master.conf"; then + sed -i "s/^MASTER_VERSION=.*/MASTER_VERSION=\"$TARGET_VERSION\"/" "${MASTER_DIR}/master.conf" + else + echo "MASTER_VERSION=\"$TARGET_VERSION\"" >> "${MASTER_DIR}/master.conf" + fi + + echo -e "\033[32m✅ 已激活 [平滑升级模式],版本已锚定为 v${TARGET_VERSION}...\033[0m" + else + echo -e "\033[33m🔄 您选择了重新配置,旧的中枢数据将被彻底抹除。\033[0m" + fi + fi + fi +} + +# ---------------------------------------------------------- +# [时序 M.3] 环境清洗 +# ---------------------------------------------------------- +do_master_clean_env() { + echo -e "\n⏳ 正在验证本地环境与数据..." + + if [ "$UPGRADE_MODE" == "true" ]; then + if [ "$KEEP_DB" == "false" ]; then + rm -f "$DB_FILE" 2>/dev/null + echo -e "🗑️ 历史节点数据库已按指令清空。" + else + echo -e "📦 历史节点数据库 (SQLite) 已绝密保留。" + fi + else + rm -rf "$MASTER_DIR" 2>/dev/null + fi + mkdir -p "$MASTER_DIR" +} + +# ---------------------------------------------------------- +# [时序 M.4] 配置总线与交互 +# ---------------------------------------------------------- +do_master_config() { + if [ "$UPGRADE_MODE" == "false" ]; then + echo -e "\n[2/4] 配置控制中枢机器人:" + read -p "请输入 Telegram Bot Token: " TG_TOKEN + + echo -e "\n请选择您的部署环境身份:" + echo " 1) 🛡️ 私有独立中枢 (默认推荐,保留完整 OTA 遥控权限)" + echo " 2) ☁️ 官方公共网关 (面向大众服务,将强制物理隐藏全局 OTA 按钮防滥用)" + read -p "请输入选择 [1-2] (默认1): " GATEWAY_TYPE + GATEWAY_TYPE=${GATEWAY_TYPE:-1} + + IS_OFFICIAL_GATEWAY="false" + ENABLE_MASTER_OTA="false" + if [ "$GATEWAY_TYPE" == "2" ]; then + IS_OFFICIAL_GATEWAY="true" + echo -e "\033[33m⚠️ 已开启官方公共网关模式,全舰队与司令部的 OTA 将被强制屏蔽。\033[0m" + else + echo -e "\n[2.1/4] 司令部自我进化授权" + echo -e "💡 开启后,您可以在 TG 菜单一键将中枢核心系统热更新至最新版本。" + read -p "是否允许司令部接收 OTA 重构指令?(y/n, 默认y): " M_OTA_CHOICE + if [[ "$M_OTA_CHOICE" =~ ^[Nn]$ ]]; then + ENABLE_MASTER_OTA="false" + echo -e "🛡️ \033[33m已关闭司令部 OTA 权限,中枢内核未来仅支持 SSH 升级。\033[0m" + else + ENABLE_MASTER_OTA="true" + echo -e "✅ \033[32m已开启司令部 OTA 权限,金蝉脱壳引信已挂载。\033[0m" + fi + fi + + # [中枢身份生成] 提取宿主特征生成全局唯一标识 + MASTER_IP=$( (curl -4 -s -m 3 api.ip.sb/ip || curl -4 -s -m 3 ifconfig.me) 2>/dev/null | tr -d '[:space:]' ) + MASTER_HASH=$(echo "${MASTER_IP:-127.0.0.1}" | md5sum | cut -c 1-4 | tr 'a-z' 'A-Z') + MASTER_NODE="$(hostname | tr -cd 'a-zA-Z0-9' | cut -c 1-10)-${MASTER_HASH}" + + echo -e "\n[2.2/4] 司令部展示别名设定 (用于面板区分多台 VPS)" + echo -e "💡 系统底层的不可变主键为: \033[33m${MASTER_NODE}\033[0m" + read -p "请输入中枢展示别名 (如'美西主控机', 回车使用默认): " CUSTOM_MASTER_ALIAS + + if [ -n "$CUSTOM_MASTER_ALIAS" ]; then + MASTER_NODE_NAME=$(echo "$CUSTOM_MASTER_ALIAS" | tr -d '"'\''\`\$\|&;<>\n\r' | cut -c 1-20) + [ -z "$MASTER_NODE_NAME" ] && MASTER_NODE_NAME="$MASTER_NODE" + else + MASTER_NODE_NAME="$MASTER_NODE" + fi + echo -e "✅ 已锁定司令部展示别名: \033[32m$MASTER_NODE_NAME\033[0m" + + cat > "${MASTER_DIR}/master.conf" << EOF +# IP-Sentinel Master 本地固化配置 (v${TARGET_VERSION}) +MASTER_VERSION="$TARGET_VERSION" +MASTER_NODE_NAME="$MASTER_NODE_NAME" +TG_TOKEN="$TG_TOKEN" +DB_FILE="$DB_FILE" +MASTER_DIR="$MASTER_DIR" +IS_OFFICIAL_GATEWAY="$IS_OFFICIAL_GATEWAY" +ENABLE_MASTER_OTA="$ENABLE_MASTER_OTA" +EOF + fi + + if [ "$UPGRADE_MODE" == "true" ]; then + if ! grep -q "^IS_OFFICIAL_GATEWAY=" "${MASTER_DIR}/master.conf"; then + echo "IS_OFFICIAL_GATEWAY=\"false\"" >> "${MASTER_DIR}/master.conf" + fi + if ! grep -q "^ENABLE_MASTER_OTA=" "${MASTER_DIR}/master.conf"; then + echo "ENABLE_MASTER_OTA=\"false\"" >> "${MASTER_DIR}/master.conf" + fi + # [热修复] 为老版本司令部平滑补齐中枢标识 + if ! grep -q "^MASTER_NODE_NAME=" "${MASTER_DIR}/master.conf"; then + MASTER_IP=$( (curl -4 -s -m 3 api.ip.sb/ip || curl -4 -s -m 3 ifconfig.me) 2>/dev/null | tr -d '[:space:]' ) + MASTER_HASH=$(echo "${MASTER_IP:-127.0.0.1}" | md5sum | cut -c 1-4 | tr 'a-z' 'A-Z') + MASTER_NODE_NAME="$(hostname | tr -cd 'a-zA-Z0-9' | cut -c 1-10)-${MASTER_HASH}" + echo "MASTER_NODE_NAME=\"$MASTER_NODE_NAME\"" >> "${MASTER_DIR}/master.conf" + fi + fi +} + +# ---------------------------------------------------------- +# [时序 M.5] 初始化 SQLite +# ---------------------------------------------------------- +do_master_init_db() { + echo -e "\n[3/4] 正在初始化 SQLite 数据库表结构..." + sqlite3 "$DB_FILE" </dev/null 2>&1 || true + systemctl stop ip-sentinel-master.service >/dev/null 2>&1 || true + fi + pkill -9 -f "tg_master.sh" >/dev/null 2>&1 || true + + mv "$TMP_MASTER" "${MASTER_DIR}/tg_master.sh" + chmod +x "${MASTER_DIR}/tg_master.sh" + + if is_systemd; then + echo "💡 检测到 Systemd 环境,正在部署原生守护服务..." + + cat > /etc/systemd/system/ip-sentinel-master.service << EOF +[Unit] +Description=IP-Sentinel Master Command Center Service +After=network.target + +[Service] +Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" +SyslogIdentifier=ip-sentinel +Type=simple +ExecStart=/bin/bash ${MASTER_DIR}/tg_master.sh +Restart=always +RestartSec=5 +User=root +WorkingDirectory=${MASTER_DIR} +CPUSchedulingPolicy=idle +IOSchedulingClass=idle + +[Install] +WantedBy=multi-user.target +EOF + + systemctl daemon-reload + systemctl enable --now ip-sentinel-master.service + systemctl restart ip-sentinel-master.service + + crontab -l 2>/dev/null | grep -v "tg_master.sh" | crontab - >/dev/null 2>&1 || true + else + echo "💡 未检测到 Systemd,回退到 Cron 看门狗调度模式..." + crontab -l 2>/dev/null | grep -v "tg_master.sh" > "${SECURE_TMP}/cron_master" || true + echo "* * * * * pgrep -f tg_master.sh >/dev/null || nohup bash ${MASTER_DIR}/tg_master.sh >/dev/null 2>&1 &" >> "${SECURE_TMP}/cron_master" + [ -f "${SECURE_TMP}/cron_master" ] && crontab "${SECURE_TMP}/cron_master" 2>/dev/null + + pgrep -f tg_master.sh >/dev/null || { nohup bash "${MASTER_DIR}/tg_master.sh" >/dev/null 2>&1 & disown 2>/dev/null; } + fi +} + +# ---------------------------------------------------------- +# [时序 M.7] 结束横幅与回执 +# ---------------------------------------------------------- +do_master_summary() { + echo "========================================================" + if [ "$UPGRADE_MODE" == "true" ]; then + echo "🎉 Master 控制中枢平滑热更新完成!" + echo "🤖 新版中枢引擎已接管数据库,继续等待边缘节点汇报。" + + # 幽灵态静默 OTA 完毕后执行回叫汇报 + if [ "$SILENT_MASTER_OTA" == "true" ] && [ -n "$OTA_CHAT_ID" ] && [ -n "$TG_TOKEN" ]; then + echo -e "\n📡 正在向指挥官发送司令部重构捷报..." + curl -s -X POST "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \ + -d "chat_id=${OTA_CHAT_ID}" \ + -d "parse_mode=Markdown" \ + -d "text=✨ *司令部中枢热重载完成!* +🚀 当前内核已跃升至:\`v${TARGET_VERSION}\` +🤖 新版金蝉脱壳引擎已接管阵地,全舰队指控链路恢复正常。" > /dev/null + fi + else + echo "🎉 Master 控制中枢部署完成!" + echo "🤖 机器人现已开始全局接客,等待边缘节点注册。" + fi + echo "========================================================" + + if [ "$UPGRADE_MODE" == "false" ]; then + echo -e "\n📡 正在向开源社区汇报装机量 (完全匿名,不收集IP)..." + MASTER_COUNT=$(curl -s -m 3 "https://ip-sentinel-count.samanthaestime296.workers.dev/ping/master" || echo "") + + if [ -n "$MASTER_COUNT" ] && [[ "$MASTER_COUNT" =~ ^[0-9]+$ ]]; then + echo -e "\033[32m✅ 感谢您成为全球第 ${MASTER_COUNT} 名 IP-Sentinel 中枢管理者!\033[0m" + else + echo -e "\033[32m✅ 感谢您部署 IP-Sentinel 控制中枢!\033[0m" + fi + fi + + echo -e "\n========================================================" + echo -e "⭐ \033[33m开源不易,如果 IP-Sentinel 极大简化了您的多节点管理,请赐予我们一枚星标!\033[0m" + echo -e "💡 \033[32m您的每一颗 Star 都是我们持续迭代架构、开发 Web 视窗化控制台的动力源泉。\033[0m" + echo -e "👉 \033[36m\033[4m\033]8;;https://github.com/hotyue/IP-Sentinel\033\\点击此处直达 GitHub 仓库点亮 Star 🌟\033[0m\033]8;;\033\\" + echo -e "========================================================\n" +} diff --git a/master/install_master.sh b/master/install_master.sh index 1397b2b0..bd49dad7 100755 --- a/master/install_master.sh +++ b/master/install_master.sh @@ -1,13 +1,9 @@ #!/bin/bash - # ========================================================== -# 脚本名称: install_master.sh -# 核心功能: Master 环境探底预装、无感 OTA 置换、持久化 SQLite 建库 +# 脚本名称: install_master.sh (v4.3.0 Bootstrapper) +# 核心功能: Master 中枢极简引导入口。创建沙盒、拉取模块并启动编排器 # ========================================================== -# ---------------------------------------------------------- -# [权限鉴权] 阻断非预期非最高权限的部署操作 -# ---------------------------------------------------------- if [ "$EUID" -ne 0 ]; then echo -e "\033[31m❌ 权限被拒绝: 部署 IP-Sentinel 需要最高系统权限。\033[0m" echo -e "💡 请切换到 root 用户 (执行 su root 或 sudo -i) 后重新运行指令。" @@ -17,422 +13,21 @@ fi SECURE_TMP=$(mktemp -d /tmp/ips_master_install.XXXXXX) trap 'rm -rf "$SECURE_TMP"' EXIT HUP INT QUIT TERM -# ---------------------------------------------------------- -# [环境预检] 中枢架构探测与系统级诊断 -# ---------------------------------------------------------- -is_systemd() { - command -v systemctl >/dev/null 2>&1 || return 1 - [ -d /run/systemd/system ] || return 1 - return 0 -} +REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/feature/v4.3.0-modular" -get_os_info() { - if [ -f /etc/os-release ]; then - . /etc/os-release - echo "$PRETTY_NAME" - else - uname -srm - fi -} +echo -e "\n⏳ 正在拉取 IP-Sentinel Master v4.3.0 安装引擎..." -get_virt_info() { - if grep -qaE 'docker|containerd|podman' /proc/1/cgroup 2>/dev/null || [ -f /.dockerenv ]; then - echo "Docker/OCI Container" - elif grep -qa container=lxc /proc/1/environ 2>/dev/null || [ -d /proc/vz ]; then - echo "LXC/OpenVZ" - elif command -v systemd-detect-virt >/dev/null 2>&1; then - systemd-detect-virt - else - echo "Unknown/Bare Metal" - fi -} +curl -fsSL --connect-timeout 10 --retry 3 "${REPO_RAW_URL}/install/build_master.sh" -o "${SECURE_TMP}/build_master.sh" -echo -e "\n======================================" -echo -e "📊 \033[36mIP-Sentinel 中枢靶机环境侦测\033[0m" -echo -e "--------------------------------------" -echo -e "OS 架构 : $(get_os_info)" -echo -e "虚拟化 : $(get_virt_info)" -if is_systemd; then - echo -e "Init 系统 : systemd ✅" -else - echo -e "Init 系统 : 非 systemd ⚠️ (将自动降维至看门狗模式)" -fi -echo -e "======================================\n" -sleep 1 - -REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main" - -# [链路容灾] 双栈冗余防抖抓取,确立本地态势版本号 -TARGET_VERSION=$( (curl -fsSL --connect-timeout 5 --retry 2 "${REPO_RAW_URL}/version.txt" || curl -4 -fsSL --connect-timeout 5 --retry 2 "${REPO_RAW_URL}/version.txt") 2>/dev/null | grep "^MASTER_VERSION=" | cut -d'=' -f2 | tr -d '[:space:]') -TARGET_VERSION=${TARGET_VERSION:-"4.0.7"} - -MASTER_DIR="/opt/ip_sentinel_master" -DB_FILE="${MASTER_DIR}/sentinel.db" - -echo "========================================================" -echo " 🧠 欢迎使用 IP-Sentinel Master (控制中枢) v${TARGET_VERSION}" -echo "========================================================" - -# ========================================================== -# [指令接管] 云端 OTA 重构流引擎拦截 -# ========================================================== -if [ "$SILENT_MASTER_OTA" == "true" ]; then - echo -e "\n⏳ [OTA] 中枢重构指令已确认,正在剥离控制台交互..." - ACTION_CHOICE=1 - UPGRADE_MODE="true" - KEEP_DB="true" - - if [ -f "${MASTER_DIR}/master.conf" ]; then - source "${MASTER_DIR}/master.conf" - - if grep -q "^MASTER_VERSION=" "${MASTER_DIR}/master.conf"; then - sed -i "s/^MASTER_VERSION=.*/MASTER_VERSION=\"$TARGET_VERSION\"/" "${MASTER_DIR}/master.conf" - else - echo "MASTER_VERSION=\"$TARGET_VERSION\"" >> "${MASTER_DIR}/master.conf" - fi - fi - echo -e "\033[32m✅ 已激活 [中枢静默重构模式],即将无损覆写内核...\033[0m" -else - echo -e "\n请选择操作:" - echo " 1) 🚀 部署 Master 控制中枢" - echo " 2) 🗑️ 一键卸载 Master 中枢" - read -p "请输入选择 [1-2] (默认1): " ACTION_CHOICE - - ACTION_CHOICE=${ACTION_CHOICE:-1} - - if [ "$ACTION_CHOICE" == "2" ]; then - echo -e "\n⏳ 正在拉取卸载程序..." - curl -fsSL --connect-timeout 10 --retry 3 "${REPO_RAW_URL}/master/uninstall_master.sh" -o "${SECURE_TMP}/uninstall_master.sh" - chmod +x "${SECURE_TMP}/uninstall_master.sh" - bash "${SECURE_TMP}/uninstall_master.sh" - rm -f "/tmp/uninstall_master.sh" - exit 0 - fi - - # [态势传承] 平滑接管探查并保护库文件 - UPGRADE_MODE="false" - KEEP_DB="true" - - if [ "$ACTION_CHOICE" == "1" ] && [ -f "${MASTER_DIR}/master.conf" ]; then - echo -e "\n\033[33m💡 司令部雷达提示:检测到本机已部署过 Master 中枢。\033[0m" - read -p "👉 是否按原配置直接进行平滑升级?(y/n, 默认y): " UPGRADE_CHOICE - if [[ -z "$UPGRADE_CHOICE" || "$UPGRADE_CHOICE" =~ ^[Yy]$ ]]; then - UPGRADE_MODE="true" - read -p "👉 是否保留历史节点数据库 (SQLite)?(y/n, 默认y): " DB_CHOICE - if [[ "$DB_CHOICE" =~ ^[Nn]$ ]]; then - KEEP_DB="false" - fi - - source "${MASTER_DIR}/master.conf" - - if grep -q "^MASTER_VERSION=" "${MASTER_DIR}/master.conf"; then - sed -i "s/^MASTER_VERSION=.*/MASTER_VERSION=\"$TARGET_VERSION\"/" "${MASTER_DIR}/master.conf" - else - echo "MASTER_VERSION=\"$TARGET_VERSION\"" >> "${MASTER_DIR}/master.conf" - fi - - echo -e "\033[32m✅ 已激活 [平滑升级模式],版本已锚定为 v${TARGET_VERSION}...\033[0m" - else - echo -e "\033[33m🔄 您选择了重新配置,旧的中枢数据将被彻底抹除。\033[0m" - fi - fi -fi - -# ---------------------------------------------------------- -# [环境清洗] 执行装配前系统清理动作 -# ---------------------------------------------------------- -echo -e "\n⏳ 正在验证本地环境与数据..." - -if [ "$UPGRADE_MODE" == "true" ]; then - if [ "$KEEP_DB" == "false" ]; then - rm -f "$DB_FILE" 2>/dev/null - echo -e "🗑️ 历史节点数据库已按指令清空。" - else - echo -e "📦 历史节点数据库 (SQLite) 已绝密保留。" - fi -else - rm -rf "$MASTER_DIR" 2>/dev/null -fi - -# ========================================================== -# [依赖装甲] 多分支环境极简包管理器适配策略 -# ========================================================== -echo -e "\n[1/4] 正在探测核心依赖 (curl, jq, sqlite3, crontab, pgrep, openssl)..." - -REQUIRED_CMDS=("curl" "jq" "sqlite3" "crontab" "pgrep" "openssl") -MISSING_CMDS=() - -for cmd in "${REQUIRED_CMDS[@]}"; do - if ! command -v "$cmd" >/dev/null 2>&1; then - MISSING_CMDS+=("$cmd") - fi -done - -if [ ${#MISSING_CMDS[@]} -gt 0 ]; then - echo "⏳ 发现缺失依赖: ${MISSING_CMDS[*]},正在尝试自动补齐..." - - if command -v apt-get >/dev/null 2>&1; then - apt-get update -y >/dev/null 2>&1 - apt-get install -y --no-install-recommends curl jq sqlite3 cron procps openssl >/dev/null 2>&1 - systemctl enable cron >/dev/null 2>&1 && systemctl start cron >/dev/null 2>&1 - elif command -v yum >/dev/null 2>&1 || command -v dnf >/dev/null 2>&1 || command -v microdnf >/dev/null 2>&1; then - PKG_MGR="yum" - OPT_ARGS="" - if command -v dnf >/dev/null 2>&1; then - PKG_MGR="dnf" - OPT_ARGS="--setopt=install_weak_deps=False" - elif command -v microdnf >/dev/null 2>&1; then - PKG_MGR="microdnf" - fi - - echo -e "\033[90m (正在安装 epel-release 扩展源,请稍候...)\033[0m" - $PKG_MGR install -y epel-release >/dev/null 2>&1 || true - - echo -e "\033[90m (正在拉取核心组件...)\033[0m" - $PKG_MGR install -y $OPT_ARGS curl jq sqlite cronie procps-ng openssl - systemctl enable crond >/dev/null 2>&1 && systemctl start crond >/dev/null 2>&1 - elif command -v apk >/dev/null 2>&1; then - echo "Alpine 探测到系统类型为 Alpine Linux,正在执行轻量级安装..." - apk add --no-cache curl jq sqlite cronie procps bash openssl || apk add --no-cache curl jq sqlite procps bash openssl - mkdir -p /var/spool/cron/crontabs - rc-update add crond default >/dev/null 2>&1 - service crond start >/dev/null 2>&1 - elif command -v pacman >/dev/null 2>&1; then - pacman -Sy --noconfirm curl jq sqlite cronie procps-ng openssl >/dev/null 2>&1 - mkdir -p /root/.cache/crontab 2>/dev/null - systemctl enable cronie >/dev/null 2>&1 && systemctl start cronie >/dev/null 2>&1 - else - echo -e "\033[31m❌ 自动安装失败:系统未知的包管理器。\033[0m" - echo -e "\033[33m⚠️ 请手动执行以下安装命令后重新运行本脚本:\033[0m" - echo -e " Debian/Ubuntu: \033[36mapt-get update && apt-get install -y --no-install-recommends curl jq sqlite3 cron procps openssl\033[0m" - echo -e " CentOS/RHEL: \033[36myum install -y curl jq sqlite cronie procps-ng openssl\033[0m" - echo -e " Alpine Linux: \033[36mapk add --no-cache curl jq sqlite cronie procps bash openssl\033[0m" - echo -e " Arch Linux: \033[36mpacman -Sy curl jq sqlite cronie procps-ng openssl\033[0m" - exit 1 - fi - - for cmd in "${REQUIRED_CMDS[@]}"; do - if ! command -v "$cmd" >/dev/null 2>&1; then - echo -e "\033[31m❌ 致命错误:核心命令 '$cmd' 仍未找到!\033[0m" - echo -e "请手动修复您的包管理器源,或联系 VPS 供应商。" - exit 1 - fi - done -fi -echo -e "\033[32m✅ 基础环境检测通过。\033[0m" - -mkdir -p "$MASTER_DIR" - -# ========================================================== -# [配置总线] 构建交互与策略文件固化 -# ========================================================== -if [ "$UPGRADE_MODE" == "false" ]; then - echo -e "\n[2/4] 配置控制中枢机器人:" - read -p "请输入 Telegram Bot Token: " TG_TOKEN - - echo -e "\n请选择您的部署环境身份:" - echo " 1) 🛡️ 私有独立中枢 (默认推荐,保留完整 OTA 遥控权限)" - echo " 2) ☁️ 官方公共网关 (面向大众服务,将强制物理隐藏全局 OTA 按钮防滥用)" - read -p "请输入选择 [1-2] (默认1): " GATEWAY_TYPE - GATEWAY_TYPE=${GATEWAY_TYPE:-1} - - IS_OFFICIAL_GATEWAY="false" - ENABLE_MASTER_OTA="false" - if [ "$GATEWAY_TYPE" == "2" ]; then - IS_OFFICIAL_GATEWAY="true" - echo -e "\033[33m⚠️ 已开启官方公共网关模式,全舰队与司令部的 OTA 将被强制屏蔽。\033[0m" - else - echo -e "\n[2.1/4] 司令部自我进化授权" - echo -e "💡 开启后,您可以在 TG 菜单一键将中枢核心系统热更新至最新版本。" - read -p "是否允许司令部接收 OTA 重构指令?(y/n, 默认y): " M_OTA_CHOICE - if [[ "$M_OTA_CHOICE" =~ ^[Nn]$ ]]; then - ENABLE_MASTER_OTA="false" - echo -e "🛡️ \033[33m已关闭司令部 OTA 权限,中枢内核未来仅支持 SSH 升级。\033[0m" - else - ENABLE_MASTER_OTA="true" - echo -e "✅ \033[32m已开启司令部 OTA 权限,金蝉脱壳引信已挂载。\033[0m" - fi - fi - - # [中枢身份生成] 提取宿主特征生成全局唯一标识 - MASTER_IP=$( (curl -4 -s -m 3 api.ip.sb/ip || curl -4 -s -m 3 ifconfig.me) 2>/dev/null | tr -d '[:space:]' ) - MASTER_HASH=$(echo "${MASTER_IP:-127.0.0.1}" | md5sum | cut -c 1-4 | tr 'a-z' 'A-Z') - MASTER_NODE="$(hostname | tr -cd 'a-zA-Z0-9' | cut -c 1-10)-${MASTER_HASH}" - - echo -e "\n[2.2/4] 司令部展示别名设定 (用于面板区分多台 VPS)" - echo -e "💡 系统底层的不可变主键为: \033[33m${MASTER_NODE}\033[0m" - read -p "请输入中枢展示别名 (如'美西主控机', 回车使用默认): " CUSTOM_MASTER_ALIAS - - if [ -n "$CUSTOM_MASTER_ALIAS" ]; then - MASTER_NODE_NAME=$(echo "$CUSTOM_MASTER_ALIAS" | tr -d '"'\''\`\$\|&;<>\n\r' | cut -c 1-20) - [ -z "$MASTER_NODE_NAME" ] && MASTER_NODE_NAME="$MASTER_NODE" - else - MASTER_NODE_NAME="$MASTER_NODE" - fi - echo -e "✅ 已锁定司令部展示别名: \033[32m$MASTER_NODE_NAME\033[0m" - - cat > "${MASTER_DIR}/master.conf" << EOF -# IP-Sentinel Master 本地固化配置 (v${TARGET_VERSION}) -MASTER_VERSION="$TARGET_VERSION" -MASTER_NODE_NAME="$MASTER_NODE_NAME" -TG_TOKEN="$TG_TOKEN" -DB_FILE="$DB_FILE" -MASTER_DIR="$MASTER_DIR" -IS_OFFICIAL_GATEWAY="$IS_OFFICIAL_GATEWAY" -ENABLE_MASTER_OTA="$ENABLE_MASTER_OTA" -EOF -fi - -if [ "$UPGRADE_MODE" == "true" ]; then - if ! grep -q "^IS_OFFICIAL_GATEWAY=" "${MASTER_DIR}/master.conf"; then - echo "IS_OFFICIAL_GATEWAY=\"false\"" >> "${MASTER_DIR}/master.conf" - fi - if ! grep -q "^ENABLE_MASTER_OTA=" "${MASTER_DIR}/master.conf"; then - echo "ENABLE_MASTER_OTA=\"false\"" >> "${MASTER_DIR}/master.conf" - fi - # [热修复] 为老版本司令部平滑补齐中枢标识 - if ! grep -q "^MASTER_NODE_NAME=" "${MASTER_DIR}/master.conf"; then - MASTER_IP=$( (curl -4 -s -m 3 api.ip.sb/ip || curl -4 -s -m 3 ifconfig.me) 2>/dev/null | tr -d '[:space:]' ) - MASTER_HASH=$(echo "${MASTER_IP:-127.0.0.1}" | md5sum | cut -c 1-4 | tr 'a-z' 'A-Z') - MASTER_NODE_NAME="$(hostname | tr -cd 'a-zA-Z0-9' | cut -c 1-10)-${MASTER_HASH}" - echo "MASTER_NODE_NAME=\"$MASTER_NODE_NAME\"" >> "${MASTER_DIR}/master.conf" - fi -fi - -# ---------------------------------------------------------- -# [数据存储] 初始化 SQLite 表结构基线 -# ---------------------------------------------------------- -echo -e "\n[3/4] 正在初始化 SQLite 数据库表结构..." -sqlite3 "$DB_FILE" </dev/null 2>&1 || true - systemctl stop ip-sentinel-master.service >/dev/null 2>&1 || true -fi -pkill -9 -f "tg_master.sh" >/dev/null 2>&1 || true +export SECURE_TMP +export REPO_RAW_URL -mv "$TMP_MASTER" "${MASTER_DIR}/tg_master.sh" -chmod +x "${MASTER_DIR}/tg_master.sh" +chmod +x "${SECURE_TMP}/build_master.sh" +source "${SECURE_TMP}/build_master.sh" -if is_systemd; then - echo "💡 检测到 Systemd 环境,正在部署原生守护服务..." - - cat > /etc/systemd/system/ip-sentinel-master.service << EOF -[Unit] -Description=IP-Sentinel Master Command Center Service -After=network.target - -[Service] -Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" -SyslogIdentifier=ip-sentinel -Type=simple -ExecStart=/bin/bash ${MASTER_DIR}/tg_master.sh -Restart=always -RestartSec=5 -User=root -WorkingDirectory=${MASTER_DIR} -CPUSchedulingPolicy=idle -IOSchedulingClass=idle - -[Install] -WantedBy=multi-user.target -EOF - - systemctl daemon-reload - systemctl enable --now ip-sentinel-master.service - systemctl restart ip-sentinel-master.service - - crontab -l 2>/dev/null | grep -v "tg_master.sh" | crontab - >/dev/null 2>&1 || true -else - echo "💡 未检测到 Systemd,回退到 Cron 看门狗调度模式..." - crontab -l 2>/dev/null | grep -v "tg_master.sh" > "${SECURE_TMP}/cron_master" || true - echo "* * * * * pgrep -f tg_master.sh >/dev/null || nohup bash ${MASTER_DIR}/tg_master.sh >/dev/null 2>&1 &" >> "${SECURE_TMP}/cron_master" - [ -f "${SECURE_TMP}/cron_master" ] && crontab "${SECURE_TMP}/cron_master" 2>/dev/null - - pgrep -f tg_master.sh >/dev/null || { nohup bash "${MASTER_DIR}/tg_master.sh" >/dev/null 2>&1 & disown 2>/dev/null; } -fi - -# ========================================================== -# [状态汇报] 根据操作场景分发回执 -# ========================================================== -echo "========================================================" -if [ "$UPGRADE_MODE" == "true" ]; then - echo "🎉 Master 控制中枢平滑热更新完成!" - echo "🤖 新版中枢引擎已接管数据库,继续等待边缘节点汇报。" - - # 幽灵态静默 OTA 完毕后执行回叫汇报 - if [ "$SILENT_MASTER_OTA" == "true" ] && [ -n "$OTA_CHAT_ID" ] && [ -n "$TG_TOKEN" ]; then - echo -e "\n📡 正在向指挥官发送司令部重构捷报..." - curl -s -X POST "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \ - -d "chat_id=${OTA_CHAT_ID}" \ - -d "parse_mode=Markdown" \ - -d "text=✨ *司令部中枢热重载完成!* -🚀 当前内核已跃升至:\`v${TARGET_VERSION}\` -🤖 新版金蝉脱壳引擎已接管阵地,全舰队指控链路恢复正常。" > /dev/null - fi -else - echo "🎉 Master 控制中枢部署完成!" - echo "🤖 机器人现已开始全局接客,等待边缘节点注册。" -fi -echo "========================================================" - -if [ "$UPGRADE_MODE" == "false" ]; then - echo -e "\n📡 正在向开源社区汇报装机量 (完全匿名,不收集IP)..." - MASTER_COUNT=$(curl -s -m 3 "https://ip-sentinel-count.samanthaestime296.workers.dev/ping/master" || echo "") - - if [ -n "$MASTER_COUNT" ] && [[ "$MASTER_COUNT" =~ ^[0-9]+$ ]]; then - echo -e "\033[32m✅ 感谢您成为全球第 ${MASTER_COUNT} 名 IP-Sentinel 中枢管理者!\033[0m" - else - echo -e "\033[32m✅ 感谢您部署 IP-Sentinel 控制中枢!\033[0m" - fi -fi - -echo -e "\n========================================================" -echo -e "⭐ \033[33m开源不易,如果 IP-Sentinel 极大简化了您的多节点管理,请赐予我们一枚星标!\033[0m" -echo -e "💡 \033[32m您的每一颗 Star 都是我们持续迭代架构、开发 Web 视窗化控制台的动力源泉。\033[0m" -echo -e "👉 \033[36m\033[4m\033]8;;https://github.com/hotyue/IP-Sentinel\033\\点击此处直达 GitHub 仓库点亮 Star 🌟\033[0m\033]8;;\033\\" -echo -e "========================================================\n" \ No newline at end of file +exit 0