# -*- coding: utf-8 -*- r'''看一眼 Lightsail 上中转服务器的完整状态。 ⚠ 写这个文件的原因:用 `python -c @"..."@` 传带 `$(...)` 的远端命令, PowerShell 会**先在本机求值** `$(systemctl ...)`(报"无法将 systemctl 项识别为 cmdlet"),还会吃掉引号导致 Python 语法错。 这个毛病我这一轮犯了四五次 —— **凡是超过两行的远端命令,一律写文件。** 用法: python _build/check_lightsail.py python _build/check_lightsail.py --fix # 顺便修文件属主 ''' from __future__ import annotations import sys from pathlib import Path ROOT = Path(__file__).resolve().parent.parent sys.path.insert(0, str(ROOT / "_build")) from lssh import run # noqa: E402 PORT = "13245" DOMAIN = "yk.xxmxxs.top" RELAY_DIR = "/opt/ykxmz-relay" # 三层地址各查一遍: # 域名 —— 用户实际走的路(Cloudflare -> nginx -> 中转) # IP:80 —— 绕过 Cloudflare,直连 nginx(域名没配好时靠它) # :13245 —— **应该不通**(中转已只绑 127.0.0.1,不再对公网) DOMAIN_URL = "http://%s" % DOMAIN NGINX_URL = "http://<源站IP>:80" DIRECT_URL = "http://<源站IP>:%s" % PORT REMOTE = r''' R=__DIR__ P=__PORT__ echo "════ 服务 ════" for s in ykxmz-relay nginx ykxmz-monitor.timer; do printf ' %-22s %s\n' "$s" "$(systemctl is-active $s 2>&1)" done echo echo "════ 三层地址(用户路径 / 绕 CF / 直连中转)════" # ⚠ 一律加 -L 跟跳转:nginx 那边 http 会 301 到 https, # 不跟跳转拿到的是 301 而不是 200,会看着像"挂了"。 printf ' %-26s %s\n' "域名 __DOMAIN__" "$(curl -sL -o /dev/null -w '%{http_code}' --max-time 12 __DOMAIN_URL__/v1/health)" printf ' %-26s %s\n' "IP:80(nginx)" "$(curl -sL -o /dev/null -w '%{http_code}' --max-time 12 __NGINX_URL__/v1/health)" printf ' %-26s %s\n' ":__PORT__(应 000)" "$(curl -s -o /dev/null -w '%{http_code}' --max-time 8 __DIRECT_URL__/v1/health)" printf ' %-26s %s\n' "本机 :__PORT__" "$(curl -s -o /dev/null -w '%{http_code}' --max-time 8 http://127.0.0.1:$P/v1/health)" printf ' %-26s %s\n' "域名延迟" "$(curl -sL -o /dev/null -w '%{time_total}s' --max-time 12 __DOMAIN_URL__/v1/health)" echo echo "════ 首页角标 ════" echo " 域名 -> $(curl -sL --max-time 12 __DOMAIN_URL__/ | grep -o '最新版 [0-9.]*' | head -1)" echo " IP:80 -> $(curl -sL --max-time 12 __NGINX_URL__/ | grep -o '最新版 [0-9.]*' | head -1)" echo echo "════ 缓存头(决定 Cloudflare 缓不缓存)════" printf ' %-20s %s 条\n' "下载" "$(curl -sL -I --max-time 12 __DOMAIN_URL__/download/ykxmz-setup-2.1.3.exe | grep -ci cache-control)" curl -sL -I --max-time 12 __DOMAIN_URL__/download/ykxmz-setup-2.1.3.exe \ | grep -i '^cache-control' | sed 's/^/ /' printf ' %-20s %s\n' "长轮询" "$(curl -sL -I --max-time 12 __DOMAIN_URL__/v1/health | grep -i '^cache-control' | tr -d '\r')" echo echo "════ 监听 / 进程 ════" ss -tlnp 2>/dev/null | grep -E ":(80|$P) " | sed 's/^/ /' ps -eo pid,rss,etime,cmd --sort=-rss 2>/dev/null | grep 'relay\.py' | grep -v grep | head -1 | sed 's/^/ /' echo echo "════ 监测单元 ════" cat $R/monitor_state.txt 2>/dev/null | sed 's/^/ /' echo " --- 探测的是什么地址 ---" grep -E '^(PUBLIC_URL|FALLBACK_URL)=' $R/monitor.sh | sed 's/^/ /' echo " --- monitor.log 尾部(只挑非 Permission 的)---" grep -v 'Permission denied' $R/monitor.log 2>/dev/null | tail -4 | sed 's/^/ /' echo echo "════ 抢救报告 / 知识库 ════" echo " 报告 $(ls $R/rescue_reports 2>/dev/null | wc -l) 份" echo " 知识库 $(wc -l < $R/rescue_knowledge.md 2>/dev/null || echo 0) 行" echo echo "════ 资源 ════" free -m 2>/dev/null | sed -n 2p | awk '{printf " 内存 %s/%s MB\n", $3, $2}' df -h / | tail -1 | awk '{printf " 磁盘 %s 用 %s\n", $2, $5}' uptime | sed 's/^/ /' echo echo "════ 文件属主(admin 必须能写日志)════" ls -la $R/*.log $R/monitor_state.txt 2>/dev/null | awk '{print " " $3":"$4" "$9}' ''' def main() -> int: if "--fix" in sys.argv: print(" ── 修属主 ──") out = run("sudo chown -R admin:admin %s && sudo chmod 755 %s && echo OK" % (RELAY_DIR, RELAY_DIR), timeout=120, quiet=True) print(" " + out[1].strip()) cmd = (REMOTE .replace("__DIR__", RELAY_DIR) .replace("__PORT__", PORT) .replace("__DOMAIN__", DOMAIN) .replace("__DOMAIN_URL__", DOMAIN_URL) .replace("__NGINX_URL__", NGINX_URL) .replace("__DIRECT_URL__", DIRECT_URL)) out = run(cmd, timeout=300, quiet=True) print(out[1] if isinstance(out, tuple) else out) return 0 if __name__ == "__main__": sys.exit(main())