From 34320b2385ae48c8b655107e8823b46f1944c84c Mon Sep 17 00:00:00 2001 From: hotyue <52734432+hotyue@users.noreply.github.com> Date: Tue, 21 Apr 2026 02:00:10 +0000 Subject: [PATCH] =?UTF-8?q?refactor(core):=20=E6=89=8B=E5=B7=A5=E8=9E=8D?= =?UTF-8?q?=E5=90=88=20Systemd=20=E5=BC=95=E6=93=8E=E4=B8=8E=20Root=20?= =?UTF-8?q?=E6=9D=83=E9=99=90=E6=A0=A1=E9=AA=8C=20(=E6=8F=90=E5=8F=96?= =?UTF-8?q?=E8=87=AA=20PR=20#25)=EF=BC=8C=E4=BF=AE=E5=A4=8D=20Cgroup=20?= =?UTF-8?q?=E8=AF=AF=E6=9D=80=E4=B8=8E=E4=BA=A4=E4=BA=92=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E9=99=B7=E9=98=B1=EF=BC=8C=E6=9E=84=E5=BB=BA=E7=81=B0=E5=BA=A6?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=80=99=E9=80=89=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/agent_daemon.sh | 28 +++--- core/install.sh | 169 +++++++++++++++++++++++++++++++------ core/mod_trust.sh | 4 +- core/uninstall.sh | 44 ++++++++-- core/updater.sh | 4 +- master/install_master.sh | 60 +++++++++++-- master/tg_master.sh | 14 ++- master/uninstall_master.sh | 34 ++++++-- 8 files changed, 282 insertions(+), 75 deletions(-) diff --git a/core/agent_daemon.sh b/core/agent_daemon.sh index d3f5779..7b63dcd 100755 --- a/core/agent_daemon.sh +++ b/core/agent_daemon.sh @@ -24,10 +24,6 @@ if [ -z "$NODE_NAME" ]; then fi NODE_ALIAS="${NODE_ALIAS:-$NODE_NAME}" -# --- [重点升级 1: 守护进程防冲突自检] --- -if pgrep -f "webhook.py $AGENT_PORT" > /dev/null; then - exit 0 -fi # 1. 尝试获取实时公网 IP RAW_IP=$(curl -${IP_PREF:-4} -s -m 5 api.ip.sb/ip | tr -d '[:space:]') @@ -374,11 +370,17 @@ class AgentHandler(http.server.BaseHTTPRequestHandler): self.end_headers() self.wfile.write(b"Action Accepted: trigger_ota\n") - # 挂起异步升级进程 (注入 SILENT_OTA 旁路变量跳过所有 read -p 交互) - # 注意:这里我们写死拉取 dev-v3.6.0 分支的安装脚本进行覆盖测试,未来正式版上线时会改回 main - repo_url = "https://raw.githubusercontent.com/hotyue/IP-Sentinel/dev-v3.6.0" - ota_cmd = f"export SILENT_OTA='true'; curl -sL {repo_url}/core/install.sh | bash > /opt/ip_sentinel/logs/ota_upgrade.log 2>&1 &" - subprocess.Popen(['bash', '-c', ota_cmd]) + # [修复] 逃逸 Systemd Cgroup,防止 Agent 在升级时被同归于尽机制误杀 + import shutil + repo_url = "https://raw.githubusercontent.com/hotyue/IP-Sentinel/v3.6.2-rc" + ota_cmd = f"export SILENT_OTA='true'; curl -fsSL {repo_url}/core/install.sh -o /tmp/ota_agent.sh && bash /tmp/ota_agent.sh > /opt/ip_sentinel/logs/ota_upgrade.log 2>&1" + + if shutil.which("systemd-run"): + full_cmd = f"systemd-run --quiet --no-block bash -c \"{ota_cmd}\"" + else: + full_cmd = f"nohup bash -c \"{ota_cmd}\" &" + + subprocess.Popen(full_cmd, shell=True) except Exception as e: self.send_response(500) @@ -413,8 +415,6 @@ except Exception as e: # ==================================================================================== EOF -# --- [重点升级 3: 真正的静默后台启动] --- -echo "🚀 [Agent] 正在后台启动 Webhook 监听服务 (端口: $AGENT_PORT)..." -nohup python3 "${INSTALL_DIR}/core/webhook.py" "$AGENT_PORT" > /dev/null 2>&1 & -disown 2>/dev/null || true -echo "✅ [Agent] 守护进程启动完毕,可安全关闭终端。" \ No newline at end of file +# --- [重点升级 3: 移交系统级守护进程接管 (阻塞模式)] --- +echo "🚀 [Agent] 正在启动 Webhook 监听服务 (端口: $AGENT_PORT)..." +exec python3 "${INSTALL_DIR}/core/webhook.py" "$AGENT_PORT" \ No newline at end of file diff --git a/core/install.sh b/core/install.sh index de51118..bb20179 100755 --- a/core/install.sh +++ b/core/install.sh @@ -5,10 +5,19 @@ # 核心功能: 战区分组菜单、模块按需开启、官方机器人一键配置、版本状态机路由 # ========================================================== +# ========================================================== +# 🛑 核心权限防线: 检查是否以 root 权限运行 +# ========================================================== +if [ "$EUID" -ne 0 ]; then + echo -e "\033[31m❌ 权限被拒绝: 部署 IP-Sentinel 需要最高系统权限。\033[0m" + echo -e "💡 请切换到 root 用户 (执行 su root 或 sudo -i) 后重新运行指令。" + exit 1 +fi + # 你的 GitHub 仓库 Raw 数据直链前缀 -REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main" +# REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main" # 临时改为开发地址用于测试 -# REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/dev-v3.6.0" +REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/v3.6.2-rc" INSTALL_DIR="/opt/ip_sentinel" CONFIG_FILE="${INSTALL_DIR}/config.conf" @@ -249,15 +258,17 @@ if [ "$UPGRADE_MODE" == "false" ]; then IFS="|" read -r CITY_ID CITY_NAME < /tmp/cities.txt echo -e "\033[32m💡 该区域下仅有单一城市 [$CITY_NAME],已自动锁定。\033[0m" else - i=1; CITY_MAP=() + i=1; CITY_MAP=(); CITY_NAME_MAP=() while IFS="|" read -r c_id c_name; do echo " $i) $c_name" CITY_MAP[$i]="$c_id" + CITY_NAME_MAP[$i]="$c_name" ((i++)) done < /tmp/cities.txt read -p "请输入选择 [1-$((i-1))] (默认1): " CI_SEL CI_SEL=${CI_SEL:-1} CITY_ID="${CITY_MAP[$CI_SEL]}" + CITY_NAME="${CITY_NAME_MAP[$CI_SEL]}" fi # 清理临时文件 (增加清理 continents.txt) @@ -622,37 +633,139 @@ fi chmod +x ${INSTALL_DIR}/core/*.sh # 7. 配置系统定时任务 (高频调度与看门狗) -echo -e "\n[7/7] 正在注入系统定时任务与看门狗进程..." -crontab -l 2>/dev/null | grep -v "ip_sentinel" > /tmp/cron_backup || true - -# 核心养护模块: 每 30 分钟触发一次 -echo "*/30 * * * * ${INSTALL_DIR}/core/runner.sh >/dev/null 2>&1" >> /tmp/cron_backup -# 养料更新模块: (v3.3.0升级) 每天凌晨 3 点触发,由中枢自动进行分频调度 -echo "0 3 * * * ${INSTALL_DIR}/core/updater.sh >/dev/null 2>&1" >> /tmp/cron_backup +echo -e "\n[7/7] 正在注入系统守护进程与调度器..." # [v3.3.0 新增] 初始化 UA 指纹库更新时间戳,确立 30 天滚动周期的计算锚点 echo $(date +%s) > "${INSTALL_DIR}/core/.ua_last_update" -# 如果配置了联控,启动 Webhook 与战报任务 -if [[ -n "$TG_TOKEN" ]] && [[ -n "$CHAT_ID" ]]; then - # 每天早上 8 点发送昨天的统计战报 - echo "0 8 * * * ${INSTALL_DIR}/core/tg_report.sh >/dev/null 2>&1" >> /tmp/cron_backup +if command -v systemctl >/dev/null 2>&1; then + echo "💡 检测到 Systemd 环境,正在部署原生守护服务..." - # [v3.0.1新增修改 3: 删除原来的 curl 取 IP,直接使用我们上方锁定的 BIND_IP] - # 并提前写入 IP 缓存,彻底阻断 agent_daemon 首次启动时的重复推送 - # [修复竞态]: 提前写入公网 IP 缓存,彻底阻断 agent_daemon 首次启动时的抢跑推送 - echo "$SAFE_PUBLIC_IP" > "${INSTALL_DIR}/core/.last_ip" - - # 双保险守护进程看门狗 - echo "@reboot nohup bash ${INSTALL_DIR}/core/agent_daemon.sh >/dev/null 2>&1 &" >> /tmp/cron_backup - echo "* * * * * nohup bash ${INSTALL_DIR}/core/agent_daemon.sh >/dev/null 2>&1 &" >> /tmp/cron_backup - - # 安装时立刻启动一次边缘守护进程 - nohup bash "${INSTALL_DIR}/core/agent_daemon.sh" >/dev/null 2>&1 & -fi + # 1. Runner 核心养护模块服务与定时器 + cat > /etc/systemd/system/ip-sentinel-runner.service << EOF +[Unit] +Description=IP-Sentinel Runner Service +After=network.target +[Service] +Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" +SyslogIdentifier=ip-sentinel +Type=oneshot +ExecStart=/bin/bash ${INSTALL_DIR}/core/runner.sh +User=root +CPUSchedulingPolicy=idle +IOSchedulingClass=idle +EOF -[ -f /tmp/cron_backup ] && crontab /tmp/cron_backup 2>/dev/null -rm -f /tmp/cron_backup + cat > /etc/systemd/system/ip-sentinel-runner.timer << EOF +[Unit] +Description=Timer for IP-Sentinel Runner Service +[Timer] +OnBootSec=10 +OnUnitActiveSec=30min +RandomizedDelaySec=180 +Persistent=true +Unit=ip-sentinel-runner.service +[Install] +WantedBy=timers.target +EOF + + # 2. Updater 养料更新模块服务与定时器 + cat > /etc/systemd/system/ip-sentinel-updater.service << EOF +[Unit] +Description=IP-Sentinel Updater Service +After=network.target +[Service] +Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" +SyslogIdentifier=ip-sentinel +Type=oneshot +ExecStart=/bin/bash ${INSTALL_DIR}/core/updater.sh +User=root +CPUSchedulingPolicy=idle +IOSchedulingClass=idle +EOF + + cat > /etc/systemd/system/ip-sentinel-updater.timer << EOF +[Unit] +Description=Timer for IP-Sentinel Updater Service +[Timer] +OnCalendar=*-*-* 03:00:00 +Persistent=true +Unit=ip-sentinel-updater.service +[Install] +WantedBy=timers.target +EOF + + systemctl daemon-reload + systemctl enable --now ip-sentinel-runner.timer ip-sentinel-updater.timer + + if [[ -n "$TG_TOKEN" ]] && [[ -n "$CHAT_ID" ]]; then + # 3. TG 战报服务与定时器 + cat > /etc/systemd/system/ip-sentinel-report.service << EOF +[Unit] +Description=IP-Sentinel Telegram Report Service +After=network.target +[Service] +Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" +SyslogIdentifier=ip-sentinel +Type=oneshot +ExecStart=/bin/bash ${INSTALL_DIR}/core/tg_report.sh +User=root +CPUSchedulingPolicy=idle +IOSchedulingClass=idle +EOF + + cat > /etc/systemd/system/ip-sentinel-report.timer << EOF +[Unit] +Description=Timer for IP-Sentinel Telegram Report Service +[Timer] +OnCalendar=*-*-* 08:00:00 +Unit=ip-sentinel-report.service +[Install] +WantedBy=timers.target +EOF + + # 4. [排雷修复] Agent Daemon Webhook 监听守护服务 (Type=simple, 常驻执行) + cat > /etc/systemd/system/ip-sentinel-agent-daemon.service << EOF +[Unit] +Description=IP-Sentinel Agent Daemon 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 ${INSTALL_DIR}/core/agent_daemon.sh +Restart=always +RestartSec=5 +User=root +CPUSchedulingPolicy=idle +IOSchedulingClass=idle +[Install] +WantedBy=multi-user.target +EOF + + # [修复竞态]: 提前写入公网 IP 缓存,阻断重复推送 + echo "$SAFE_PUBLIC_IP" > "${INSTALL_DIR}/core/.last_ip" + + systemctl daemon-reload + systemctl enable --now ip-sentinel-report.timer + systemctl enable --now ip-sentinel-agent-daemon.service + fi +else + echo "💡 未检测到 Systemd (可能是 Alpine Linux),回退到 Cron 调度模式..." + crontab -l 2>/dev/null | grep -v "ip_sentinel" > /tmp/cron_backup || true + echo "*/30 * * * * ${INSTALL_DIR}/core/runner.sh >/dev/null 2>&1" >> /tmp/cron_backup + echo "0 3 * * * ${INSTALL_DIR}/core/updater.sh >/dev/null 2>&1" >> /tmp/cron_backup + + if [[ -n "$TG_TOKEN" ]] && [[ -n "$CHAT_ID" ]]; then + echo "0 8 * * * ${INSTALL_DIR}/core/tg_report.sh >/dev/null 2>&1" >> /tmp/cron_backup + echo "$SAFE_PUBLIC_IP" > "${INSTALL_DIR}/core/.last_ip" + echo "@reboot nohup bash ${INSTALL_DIR}/core/agent_daemon.sh >/dev/null 2>&1 &" >> /tmp/cron_backup + echo "* * * * * nohup bash ${INSTALL_DIR}/core/agent_daemon.sh >/dev/null 2>&1 &" >> /tmp/cron_backup + nohup bash "${INSTALL_DIR}/core/agent_daemon.sh" >/dev/null 2>&1 & + fi + [ -f /tmp/cron_backup ] && crontab /tmp/cron_backup 2>/dev/null + rm -f /tmp/cron_backup +fi # ================== [v3.4.0 核心: 状态机驱动的热更新路由] ================== if [[ -n "$TG_TOKEN" ]] && [[ -n "$CHAT_ID" ]]; then diff --git a/core/mod_trust.sh b/core/mod_trust.sh index a105128..2549179 100755 --- a/core/mod_trust.sh +++ b/core/mod_trust.sh @@ -9,9 +9,9 @@ INSTALL_DIR="/opt/ip_sentinel" CONFIG_FILE="${INSTALL_DIR}/config.conf" UA_FILE="${INSTALL_DIR}/data/user_agents.txt" # 你的 GitHub 仓库 Raw 数据直链前缀 -REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main" +# REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main" # 临时改为私库地址用于测试 -# REPO_RAW_URL="https://git.94211762.xyz/hotyue/IP-Sentinel/raw/branch/main" +REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/v3.6.2-rc" # 1. 基础环境校验 [ ! -f "$CONFIG_FILE" ] && exit 1 diff --git a/core/uninstall.sh b/core/uninstall.sh index 4010b7f..f0d6002 100755 --- a/core/uninstall.sh +++ b/core/uninstall.sh @@ -1,10 +1,18 @@ #!/bin/bash -# ========================================================== # 脚本名称: uninstall.sh (IP-Sentinel 一键卸载脚本 - 动态锚点版) # 核心功能: 无痕清理守护进程、定时任务、运行目录及临时缓存 # ========================================================== +# ========================================================== +# 🛑 核心权限防线: 检查是否以 root 权限运行 +# ========================================================== +if [ "$EUID" -ne 0 ]; then + echo -e "\033[31m❌ 权限被拒绝: 卸载 IP-Sentinel 需要最高系统权限。\033[0m" + echo -e "💡 请切换到 root 用户 (执行 su root 或 sudo -i) 后重新运行指令。" + exit 1 +fi + INSTALL_DIR="/opt/ip_sentinel" echo "========================================================" @@ -18,13 +26,31 @@ if [ -f "$CONFIG_FILE" ]; then fi echo "========================================================" -# 1. 停止运行中的守护进程与主控模块 (涵盖所有历史版本进程) -echo "[1/3] 正在终止后台守护进程与所有养护任务..." +# 1. 停止并删除 Systemd 服务 (适配新架构) +echo "[1/4] 正在停止并删除 Systemd 服务..." +if command -v systemctl >/dev/null 2>&1; then + echo "💡 检测到 Systemd 环境,正在抹除 Systemd 服务单元..." + systemctl disable --now ip-sentinel-runner.service ip-sentinel-runner.timer \ + ip-sentinel-updater.service ip-sentinel-updater.timer \ + ip-sentinel-report.service ip-sentinel-report.timer \ + ip-sentinel-agent-daemon.service >/dev/null 2>&1 + rm -f /etc/systemd/system/ip-sentinel-runner.service + rm -f /etc/systemd/system/ip-sentinel-runner.timer + rm -f /etc/systemd/system/ip-sentinel-updater.service + rm -f /etc/systemd/system/ip-sentinel-updater.timer + rm -f /etc/systemd/system/ip-sentinel-report.service + rm -f /etc/systemd/system/ip-sentinel-report.timer + rm -f /etc/systemd/system/ip-sentinel-agent-daemon.service + systemctl daemon-reload + systemctl reset-failed +else + echo "💡 未检测到 Systemd,跳过此步骤..." +fi -# 使用 pkill 替代传统的 pgrep | xargs,指令更短、容错率更高 +# 2. 停止运行中的守护进程与主控模块 (兜底清理老版进程) +echo "[2/4] 正在终止后台守护进程与所有养护任务..." pkill -9 -f "tg_daemon.sh" >/dev/null 2>&1 pkill -9 -f "agent_daemon.sh" >/dev/null 2>&1 -# [v3.4.0 优化] 确保清理所有 python3 调起的 Webhook 实例 pkill -9 -f "python3.*webhook.py" >/dev/null 2>&1 pkill -9 -f "webhook.py" >/dev/null 2>&1 pkill -9 -f "runner.sh" >/dev/null 2>&1 @@ -33,16 +59,16 @@ pkill -9 -f "tg_report.sh" >/dev/null 2>&1 pkill -9 -f "mod_google.sh" >/dev/null 2>&1 pkill -9 -f "mod_trust.sh" >/dev/null 2>&1 -# 2. 清除系统定时任务 (Cron) -echo "[2/3] 正在清理系统定时任务 (Cron)..." +# 3. 清除系统定时任务 (Cron) +echo "[3/4] 正在清理系统定时任务 (Cron)..." if crontab -l >/dev/null 2>&1; then crontab -l | grep -v "ip_sentinel" > /tmp/cron_backup crontab /tmp/cron_backup rm -f /tmp/cron_backup fi -# 3. 删除所有文件、日志与临时缓存 -echo "[3/3] 正在抹除核心程序、配置文件与系统痕迹..." +# 4. 删除所有文件、日志与临时缓存 +echo "[4/4] 正在抹除核心程序、配置文件与系统痕迹..." if [ -d "$INSTALL_DIR" ]; then rm -rf "$INSTALL_DIR" fi diff --git a/core/updater.sh b/core/updater.sh index eca26cd..49c0a3c 100755 --- a/core/updater.sh +++ b/core/updater.sh @@ -10,9 +10,9 @@ CONFIG_FILE="${INSTALL_DIR}/config.conf" UA_TIME_FILE="${INSTALL_DIR}/core/.ua_last_update" # GitHub 仓库 Raw 数据直链前缀 -REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main" +# REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main" # 临时改为开发地址用于测试 -# REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/dev-v3.6.0" +REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/v3.6.2-rc" # 1. 加载本地冷数据配置 if [ ! -f "$CONFIG_FILE" ]; then diff --git a/master/install_master.sh b/master/install_master.sh index 0a4831f..3f726ae 100755 --- a/master/install_master.sh +++ b/master/install_master.sh @@ -5,10 +5,19 @@ # 核心功能: 部署/卸载调度中枢、SQLite 资产管理、平滑热更新引擎 # ========================================================== +# ========================================================== +# 🛑 核心权限防线: 检查是否以 root 权限运行 +# ========================================================== +if [ "$EUID" -ne 0 ]; then + echo -e "\033[31m❌ 权限被拒绝: 部署 IP-Sentinel 需要最高系统权限。\033[0m" + echo -e "💡 请切换到 root 用户 (执行 su root 或 sudo -i) 后重新运行指令。" + exit 1 +fi + # 你的 GitHub 仓库 Raw 数据直链前缀 -REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main" +# REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main" # 临时改为开发地址用于测试 -# REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/dev-v3.6.1" +REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/v3.6.2-rc" # [核心: 动态提取 Master 专属版本锚点 (KV 解析法)] # 通过 grep 定位 MASTER_VERSION 行,再通过 cut 提取等号右侧的值 @@ -260,14 +269,47 @@ echo -e "\n[4/4] 部署 TG 调度守护进程..." curl -sL "${REPO_RAW_URL}/master/tg_master.sh" -o "${MASTER_DIR}/tg_master.sh" chmod +x "${MASTER_DIR}/tg_master.sh" -# 写入看门狗 Cron (容错版) -crontab -l 2>/dev/null | grep -v "tg_master.sh" > /tmp/cron_master || true -echo "* * * * * pgrep -f tg_master.sh >/dev/null || nohup bash ${MASTER_DIR}/tg_master.sh >/dev/null 2>&1 &" >> /tmp/cron_master -[ -f /tmp/cron_master ] && crontab /tmp/cron_master 2>/dev/null -rm -f /tmp/cron_master +if command -v systemctl >/dev/null 2>&1; then + echo "💡 检测到 Systemd 环境,正在部署原生守护服务..." + + cat > /etc/systemd/system/ip-sentinel-master.service << EOF +[Unit] +Description=IP-Sentinel Master Command Center Service +After=network.target -# 立刻启动 (追加 disown 彻底脱离终端管控,实现绝对静默) -pgrep -f tg_master.sh >/dev/null || { nohup bash "${MASTER_DIR}/tg_master.sh" >/dev/null 2>&1 & disown 2>/dev/null; } +[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 + + # 清理可能残留的历史 Cron + crontab -l 2>/dev/null | grep -v "tg_master.sh" > /tmp/cron_master || true + [ -f /tmp/cron_master ] && crontab /tmp/cron_master 2>/dev/null + rm -f /tmp/cron_master +else + echo "💡 未检测到 Systemd,回退到 Cron 看门狗调度模式..." + crontab -l 2>/dev/null | grep -v "tg_master.sh" > /tmp/cron_master || true + echo "* * * * * pgrep -f tg_master.sh >/dev/null || nohup bash ${MASTER_DIR}/tg_master.sh >/dev/null 2>&1 &" >> /tmp/cron_master + [ -f /tmp/cron_master ] && crontab /tmp/cron_master 2>/dev/null + rm -f /tmp/cron_master + + pgrep -f tg_master.sh >/dev/null || { nohup bash "${MASTER_DIR}/tg_master.sh" >/dev/null 2>&1 & disown 2>/dev/null; } +fi # ================== [v3.2.2 优化 & v3.6.1 OTA捷报: 战报文案分流] ================== echo "========================================================" diff --git a/master/tg_master.sh b/master/tg_master.sh index 06d9390..4b73db5 100755 --- a/master/tg_master.sh +++ b/master/tg_master.sh @@ -10,9 +10,9 @@ CONF="/opt/ip_sentinel_master/master.conf" source "$CONF" # [核心: 运行态版本继承与云通信地址] -REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main" +# REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main" # 临时改为开发地址用于测试 -# REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/dev-v3.6.1" +REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/v3.6.2-rc" # MASTER_VERSION 已经在上方的 source "$CONF" 中被载入 # 如果本地极度陈旧没有该变量,才给定一个基础兜底值,避免变量为空导致崩溃 MASTER_VERSION=${MASTER_VERSION:-"3.5.0"} @@ -261,13 +261,19 @@ while true; do fi # 下载最新的 master install 脚本作为幽灵进程 - curl -sL "${REPO_RAW_URL}/master/install_master.sh" -o "/tmp/install_master.sh" + curl -fsSL "${REPO_RAW_URL}/master/install_master.sh" -o "/tmp/install_master.sh" chmod +x "/tmp/install_master.sh" # 抛出幽灵进程进行脱壳升级,传递静默变量与回执 ID export SILENT_MASTER_OTA="true" export OTA_CHAT_ID="$CHAT_ID" - nohup bash /tmp/install_master.sh >/dev/null 2>&1 & disown + + # [修复] 逃逸 Systemd Cgroup,防止被同归于尽机制误杀 + if command -v systemd-run >/dev/null 2>&1; then + systemd-run --quiet --no-block /bin/bash /tmp/install_master.sh + else + nohup bash /tmp/install_master.sh >/dev/null 2>&1 & disown + fi # 当前旧进程休眠并等待被幽灵进程处决 sleep 10 diff --git a/master/uninstall_master.sh b/master/uninstall_master.sh index f391a36..aed61fc 100644 --- a/master/uninstall_master.sh +++ b/master/uninstall_master.sh @@ -5,6 +5,15 @@ # 核心功能: 终止调度进程、清理看门狗定时任务、抹除数据库与配置 # ========================================================== +# ========================================================== +# 🛑 核心权限防线: 检查是否以 root 权限运行 +# ========================================================== +if [ "$EUID" -ne 0 ]; then + echo -e "\033[31m❌ 权限被拒绝: 卸载 IP-Sentinel 需要最高系统权限。\033[0m" + echo -e "💡 请切换到 root 用户 (执行 su root 或 sudo -i) 后重新运行指令。" + exit 1 +fi + MASTER_DIR="/opt/ip_sentinel_master" CONF_FILE="${MASTER_DIR}/master.conf" @@ -25,19 +34,30 @@ if [[ ! "$CONFIRM_DEL" =~ ^[Yy]$ ]]; then exit 0 fi -# 1. 停止运行中的 Master 守护进程 -echo "[1/3] 正在终止后台中枢调度进程..." -# [优化] 使用 pkill 替代 pgrep | xargs,指令更短、容错率更高 +# 1. 停止并删除 Systemd 服务 (适配新架构) +echo "[1/4] 正在停止并删除 Systemd 服务..." +if command -v systemctl >/dev/null 2>&1; then + echo "💡 检测到 Systemd 环境,正在抹除 Systemd 服务单元..." + systemctl disable --now ip-sentinel-master.service >/dev/null 2>&1 + rm -f /etc/systemd/system/ip-sentinel-master.service + systemctl daemon-reload + systemctl reset-failed +else + echo "💡 未检测到 Systemd,跳过此步骤..." +fi + +# 2. 停止运行中的 Master 守护进程 (兜底清理老版进程) +echo "[2/4] 正在终止后台中枢调度进程..." pkill -9 -f "tg_master.sh" >/dev/null 2>&1 || true -# 2. 清除看门狗定时任务 (Cron) -echo "[2/3] 正在清理系统定时任务 (Cron)..." +# 3. 清除看门狗定时任务 (Cron) +echo "[3/4] 正在清理系统定时任务 (Cron)..." crontab -l 2>/dev/null | grep -v "tg_master.sh" > /tmp/cron_backup crontab /tmp/cron_backup rm -f /tmp/cron_backup -# 3. 删除所有文件、配置与数据库 -echo "[3/3] 正在抹除核心程序、配置文件与 SQLite 数据库..." +# 4. 删除所有文件、配置与数据库 +echo "[4/4] 正在抹除核心程序、配置文件与 SQLite 数据库..." if [ -d "$MASTER_DIR" ]; then rm -rf "$MASTER_DIR" fi