# -*- coding: utf-8 -*- """把隧道看门狗写进 install.sh。 为什么需要: 匿名隧道在这条线路上时好时坏。tunnel-run.sh 只管**建立**阶段, 建立之后中途失效没人管 —— 用户只能自己发现、自己 SSH 上来重启。 看门狗每 5 分钟检查一次公网可达性,连续 3 次不通就重启隧道。 写进 install.sh 之后,别人部署也会有这个能力。 """ from __future__ import annotations import sys from pathlib import Path INSTALL = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\relay" r"\install.sh") ANCHOR = '''systemctl daemon-reload systemctl enable lanremote-relay lanremote-tunnel >/dev/null 2>&1 systemctl start lanremote-relay sleep 3 systemctl start lanremote-tunnel echo " 两个服务已注册并启动"''' NEW = '''systemctl daemon-reload systemctl enable lanremote-relay lanremote-tunnel >/dev/null 2>&1 systemctl start lanremote-relay sleep 3 systemctl start lanremote-tunnel echo " 两个服务已注册并启动" # ---------- 3b. 装隧道看门狗 ---------- # 匿名隧道建立之后中途失效没人管,用户只能自己发现、自己上来重启。 # 看门狗每 5 分钟检查一次公网可达性,连续 3 次不通就重启隧道。 echo echo "[3b] 装隧道看门狗" if [ -f "$RELAY_DIR/watchdog.sh" ] || [ -f "$SCRIPT_DIR/watchdog.sh" ]; then if [ -f "$SCRIPT_DIR/watchdog.sh" ] && \\ [ "$(readlink -f "$SCRIPT_DIR/watchdog.sh")" != \\ "$(readlink -f "$RELAY_DIR/watchdog.sh" 2>/dev/null || echo x)" ]; then cp -f "$SCRIPT_DIR/watchdog.sh" "$RELAY_DIR/watchdog.sh" fi chmod +x "$RELAY_DIR/watchdog.sh" cat > /etc/systemd/system/lanremote-watchdog.service <<'WDUNIT' [Unit] Description=LanRemote 隧道看门狗(检查公网可达性) After=lanremote-relay.service lanremote-tunnel.service [Service] Type=oneshot ExecStart=/bin/bash /root/lanremote-relay/watchdog.sh MemoryMax=64M StandardOutput=append:/root/lanremote-relay/watchdog.log StandardError=append:/root/lanremote-relay/watchdog.log WDUNIT cat > /etc/systemd/system/lanremote-watchdog.timer <<'WDTIMER' [Unit] Description=每 5 分钟检查一次隧道 [Timer] OnBootSec=3min OnUnitActiveSec=5min AccuracySec=30s Unit=lanremote-watchdog.service [Install] WantedBy=timers.target WDTIMER systemctl daemon-reload systemctl enable lanremote-watchdog.timer >/dev/null 2>&1 systemctl start lanremote-watchdog.timer echo " 看门狗已启用(每 5 分钟检查一次)" else echo " [跳过] 没找到 watchdog.sh" fi''' # 便捷命令里加一个"看隧道状态" CMD_ANCHOR = '''cat > /usr/local/bin/lanremote-key <<'EOF' #!/bin/bash # 打印管理页钥匙 cat /root/lanremote-relay/data/admin_key.txt 2>/dev/null || echo "(还没有钥匙)" EOF chmod +x /usr/local/bin/lanremote-key''' CMD_NEW = CMD_ANCHOR + ''' cat > /usr/local/bin/lanremote-status <<'EOF' #!/bin/bash # 一眼看清中转 + 隧道的状态 echo "=== 服务 ===" for s in lanremote-relay lanremote-tunnel lanremote-watchdog.timer; do printf " %-28s %s\\n" "$s" "$(systemctl is-active "$s" 2>/dev/null)" done echo echo "=== 公网地址 ===" cat /root/lanremote-relay/public_url.txt 2>/dev/null || echo " (还没有)" echo echo "=== 可达性 ===" URL=$(cat /root/lanremote-relay/public_url.txt 2>/dev/null) if [ -n "$URL" ]; then C=$(timeout 20 curl -4 -s -o /dev/null -w '%{http_code}' "$URL/v1/health" 2>/dev/null) echo " HTTP ${C:-超时}" fi echo echo "=== 看门狗最近记录 ===" tail -3 /root/lanremote-relay/watchdog.log 2>/dev/null | sed 's/^/ /' || echo " (还没有)" echo echo "=== 内存 ===" free -m | awk 'NR==2{printf " 已用 %s MB / 可用 %s MB\\n", $3, $7}' EOF chmod +x /usr/local/bin/lanremote-status''' # 说明里提一句 DOC_ANCHOR = ''' 下面还有两个命令(SSH 上去用): lanremote-url 打印当前公网地址 systemctl restart lanremote-tunnel 换个地址(超时的时候用)''' DOC_NEW = ''' 下面还有三个命令(SSH 上去用): lanremote-status 一眼看清中转 + 隧道状态(推荐先看这个) lanremote-url 打印当前公网地址 systemctl restart lanremote-tunnel 手动换地址 隧道有看门狗看着:每 5 分钟检查一次公网可达性, 连续 3 次不通会自动重启隧道。你不用管它。''' def main() -> int: text = INSTALL.read_text(encoding="utf-8") ok = True for old, new, tag in ((ANCHOR, NEW, "看门狗安装"), (CMD_ANCHOR, CMD_NEW, "lanremote-status 命令")): if old in text: text = text.replace(old, new, 1) print(f" {tag}: 已加") else: print(f" [跳过] {tag} —— 锚点没找到") ok = False if DOC_ANCHOR in text: text = text.replace(DOC_ANCHOR, DOC_NEW, 1) print(" 说明文档: 已更新") else: print(" [跳过] 说明文档锚点没找到") INSTALL.write_text(text, encoding="utf-8", newline="\n") raw = INSTALL.read_bytes() if b"\r\n" in raw: INSTALL.write_bytes(raw.replace(b"\r\n", b"\n")) print(" 顺手修了 CRLF") print(" install.sh 已更新,纯 LF") return 0 if ok else 1 if __name__ == "__main__": sys.exit(main())