mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 10:10:43 +00:00
== 用户要求 ==
"安卓那个逻辑也要改一下,就是你输入配对码后,进入一个页面,
页面有两个按钮,第一个按钮是远控,第二个按钮是静默更新被控端"
== 做成什么样 ==
新增 choicePanel,连接成功后先进这一页:
已连接「电脑名」
电脑端 2.1.5 → 可更新到 2.2.0
[ 远控 ] <- 第一个按钮
[ 静默更新被控端 ] <- 第二个按钮
按钮顺序按用户说的来(远控在前)。
页面顶上显示电脑名和**电脑端当前版本** —— 用户之前要求
"手表端连接那个电脑端也可以查看电脑端目前所处的版本",
这里是最自然的展示位置(不弹框,只显示一行)。
为什么不让它直接进控制页:老版本的被控端可能缺功能或有 bug,
"先更新再远控"是更合理的顺序 —— 但不强制,给用户自己选。
== 一个刻意不改的地方 ==
自动切到中转服务器**恢复**时的 `showControlPanel()` **没动** ——
用户本来就在远控页,中途弹一层选择页会打断他。
测试里专门断言了这一点,免得以后有人"顺手统一一下"改坏。
== 顺手修的几个问题 ==
1. **忘了定义 lastDeviceName** —— 写选择页时凭直觉用了这个变量,
编译报"找不到符号"。补上字段并在连接回调里赋值。
(教训:写代码时要用的变量,先确认它存在。)
2. **泄漏闸门拦下我自己** —— 这两天写的一批服务器诊断/配置脚本里
硬编码了服务器 IP(26 处,5 个文件)。规则是 IP 不能进任何
被跟踪的文件。已全部改成占位符,真实值仍从
_build/.lightsail_host(已 gitignore)读。
3. **verify_all.ps1 删掉「锁屏时记 SKIP」的逻辑** ——
用户明确要求删。那个好意带来一个更糟的后果:锁屏时几关根本不跑,
回归"全绿"了但关键测试其实一跳而过。
**"因为环境不满足所以不测"比"测了发现失败"更危险。**
删掉之后果然暴露出 3 个 FAIL —— 屏幕解锁后重跑全部通过,
确认是环境问题而不是代码问题。
== 服务器这边(不在这份提交里,但同一天做的)==
* nginx 按用户要求重排:
IP(80) 任何路径 -> 404(没东西)
域名 / -> 官网;/zhongzhuanzhan -> 中转站设置
9100 -> 同样的内容(等 AWS 开防火墙)
* 删掉早年 Cloudflare Tunnel 的 systemd 残留
* **补上 ACME 挑战例外** —— 这是最要紧的一条:
80 端口原来把所有请求都 301 到 https,包括
/.well-known/acme-challenge/,**续期时会失败**。
而且它是延迟爆发的(最长 90 天后证书到期才暴露)。
* 清理 1Panel 安装包残留(223MB)
== 验证 ==
全量回归 21 关全部 PASS(零 FAIL,桌面可用状态)
Java 编译通过(android-34, --release 8)
623+ Python 文件语法通过
泄漏闸门通过
全部产物重建,Win7 兼容校验通过
213 lines
9.1 KiB
Python
213 lines
9.1 KiB
Python
# -*- coding: utf-8 -*-
|
||
r'''服务器整理:删隧道残留 + 加 9100 监听 + 修"用 IP 访问 404"。
|
||
|
||
== 用户的要求 ==
|
||
|
||
* "为什么中转站里还有隧道,所有没的东西就删了"
|
||
* "网站官网不是 <服务器IP> 吗,改成 <服务器IP>:9100,中转站也一样"
|
||
* "我感觉网站还是不稳定"
|
||
|
||
== 查到的现状 ==
|
||
|
||
* `lanremote-tunnel` / `cloudflared` 两个单元 **inactive dead**,
|
||
但**单元文件还在**(`systemctl list-units --all` 能列出来)。
|
||
那是早年走 Cloudflare Tunnel 时留下的,现在早就换成
|
||
nginx + Let's Encrypt 直连了 —— 属于"没的东西",该删。
|
||
* **用 IP 直接访问 `http://<服务器IP>/` 返回 404** ——
|
||
因为唯一的 80 站点是 `server_name yk.xxmxxs.top`,
|
||
Host 不匹配时 nginx 拿它当 default server,转给 relay,
|
||
relay 不认这个 Host 就 404。
|
||
**这很可能就是"感觉不稳定"的来源**:用域名是对的,用 IP 就不对。
|
||
* 9100 端口**服务端没监听、AWS 防火墙也没开** —— 两头都要做。
|
||
|
||
== 这一版做什么 ==
|
||
|
||
1. **删掉两个隧道单元**(先 stop + disable + 删文件 + daemon-reload)
|
||
2. **nginx 加 9100 监听**:
|
||
* `http://<服务器IP>:9100/` 直接出官网
|
||
* 中转接口也在 9100 上(`/v1/...`、`/download/...`)
|
||
⚠ 这需要 **AWS Lightsail 控制台里开放 9100**,
|
||
只有用户能做(我没有他的 AWS 凭据)。
|
||
3. **修 IP 访问 404**:给 80 端口加一个 default server,
|
||
把不认识的 Host 也送到同一套后端 —— 这样 `http://IP/` 能用。
|
||
|
||
== 为什么 9100 用 HTTP 而不是 HTTPS ==
|
||
|
||
IP 地址**没法签证书**(Let's Encrypt 不给纯 IP 签)。
|
||
所以 `https://<服务器IP>:9100` 会报证书错。
|
||
9100 定位是"Cloudflare 出问题时的直连备用通道",
|
||
用 HTTP 就行 —— 中转的数据本身有自己的校验。
|
||
'''
|
||
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, upload # noqa: E402
|
||
|
||
# ---------------------------------------------------------------- nginx 片段
|
||
# 在 ykxmz 站点的 443 server 里补 9100 监听,并加一个 80 的 default server。
|
||
#
|
||
# 为什么加在**同一个文件**里:这样只有一份 server 块要维护,
|
||
# 后端地址(127.0.0.1:13245)只写一次,改后端不用改两处。
|
||
EXTRA_LISTEN = """
|
||
# ---- 9100:Cloudflare 之外的直连通道 ----
|
||
#
|
||
# 用户要求:"网站官网不是 <服务器IP> 吗,改成 <服务器IP>:9100"。
|
||
#
|
||
# ⚠ 用 IP 没法签证书(Let's Encrypt 不给纯 IP 签),所以这里是 HTTP。
|
||
# 定位是备用通道:Cloudflare 出问题时还能直接连上。
|
||
#
|
||
# ⚠ 还需要在 **AWS Lightsail 控制台**开放 9100 端口 ——
|
||
# 光配 nginx 没用,外面照样连不上(实测 9100 现在不通)。
|
||
listen 9100;
|
||
listen [::]:9100;
|
||
"""
|
||
|
||
DEFAULT_SERVER = """
|
||
# ======================================================================
|
||
# 80 端口的默认站点
|
||
# ======================================================================
|
||
#
|
||
# 为什么需要它:原来唯一的 80 站点是 `server_name yk.xxmxxs.top`。
|
||
# 用 IP 直接访问(`http://<服务器IP>/`)时 Host 不匹配,
|
||
# nginx 就拿这个站点当 default server,把请求转给 relay ——
|
||
# relay 不认这个 Host,返回 404。
|
||
#
|
||
# **这很可能就是"感觉网站不稳定"的来源**:用域名是对的,用 IP 就 404,
|
||
# 用户不知道区别,只会觉得"时好时坏"。
|
||
#
|
||
# 现在显式指定一个默认站点:不管什么 Host,都送到同一套后端。
|
||
server {
|
||
listen 80 default_server;
|
||
listen [::]:80 default_server;
|
||
server_name _;
|
||
|
||
access_log /var/log/nginx/ykxmz_default_access.log;
|
||
error_log /var/log/nginx/ykxmz_default_error.log;
|
||
|
||
# 用 IP 访问时不要跳 https —— IP 没证书,跳过去浏览器会报警告,
|
||
# 用户会以为网站坏了。直接给内容。
|
||
client_max_body_size 64m;
|
||
server_tokens off;
|
||
|
||
location / {
|
||
proxy_pass http://127.0.0.1:13245;
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_set_header Upgrade $http_upgrade;
|
||
proxy_set_header Connection "upgrade";
|
||
proxy_read_timeout 300s;
|
||
proxy_connect_timeout 30s;
|
||
}
|
||
}
|
||
"""
|
||
|
||
|
||
def main() -> int:
|
||
print("=" * 62)
|
||
print(" 服务器整理:删隧道 + 加 9100 + 修 IP 访问")
|
||
print("=" * 62)
|
||
print()
|
||
|
||
# ---------------------------------------------------------------- 1. 删隧道
|
||
print("── 1. 删掉隧道残留 ──")
|
||
r = run(r'''
|
||
for u in lanremote-tunnel cloudflared lanremote-relay; do
|
||
if systemctl list-unit-files 2>/dev/null | grep -q "^$u"; then
|
||
echo " 处理 $u"
|
||
sudo systemctl stop $u 2>/dev/null
|
||
sudo systemctl disable $u 2>/dev/null
|
||
sudo rm -f /etc/systemd/system/$u.service \
|
||
/lib/systemd/system/$u.service \
|
||
/etc/systemd/system/multi-user.target.wants/$u.service 2>/dev/null
|
||
fi
|
||
done
|
||
# 还有没有别的相关残留
|
||
sudo find /etc/systemd/system /lib/systemd/system -maxdepth 2 \
|
||
-iname "*lanremote*" -o -iname "*cloudflared*" -o -iname "*tunnel*" 2>/dev/null \
|
||
| while read f; do echo " 删 $f"; sudo rm -f "$f"; done
|
||
sudo systemctl daemon-reload
|
||
echo " --- 之后还剩什么 ---"
|
||
systemctl list-units --all --no-pager --plain 2>/dev/null \
|
||
| grep -iE 'lanremote|cloudflared|tunnel' | sed 's/^/ /' || echo " (干净了)"
|
||
''', timeout=180, quiet=True)
|
||
print(r[1] if isinstance(r, tuple) else r)
|
||
|
||
# ---------------------------------------------------------------- 2. 改 nginx
|
||
print()
|
||
print("── 2. nginx:加 9100 监听 + 80 默认站点 ──")
|
||
r = run("sudo cat /etc/nginx/sites-available/ykxmz", timeout=90, quiet=True)
|
||
conf = r[1] if isinstance(r, tuple) else str(r)
|
||
if "listen 9100" in conf:
|
||
print(" 9100 已经配过了")
|
||
else:
|
||
# 在 443 那个 server 块的 listen 后面插 9100
|
||
anchor = " listen 443 ssl; # managed by Certbot"
|
||
if anchor not in conf:
|
||
# 换一个可能的形式
|
||
import re
|
||
m = re.search(r"\n(\s*)listen 443[^\n]*\n", conf)
|
||
if not m:
|
||
print(" ✗ 找不到 443 的 listen 行")
|
||
return 1
|
||
anchor = m.group(0).strip()
|
||
conf = conf.replace(anchor, anchor + "\n" + EXTRA_LISTEN.rstrip(),
|
||
1)
|
||
conf = conf.rstrip() + "\n" + DEFAULT_SERVER
|
||
|
||
tmp = ROOT / "_build" / "_nginx_ykxmz.conf"
|
||
tmp.write_text(conf, encoding="utf-8", newline="\n")
|
||
upload(str(tmp), "/tmp/ykxmz.conf.new")
|
||
tmp.unlink(missing_ok=True)
|
||
r2 = run(
|
||
"sudo cp /etc/nginx/sites-available/ykxmz "
|
||
"/etc/nginx/sites-available/ykxmz.bak.$(date +%s) && "
|
||
"sudo mv /tmp/ykxmz.conf.new /etc/nginx/sites-available/ykxmz && "
|
||
"sudo nginx -t 2>&1 | tail -3", timeout=180, quiet=True)
|
||
out = r2[1] if isinstance(r2, tuple) else str(r2)
|
||
print(" " + out.replace("\n", "\n "))
|
||
if "successful" not in out:
|
||
print(" ✗ 配置有错,撤回")
|
||
run("sudo cp $(sudo ls -t /etc/nginx/sites-available/ykxmz.bak.* "
|
||
"| head -1) /etc/nginx/sites-available/ykxmz", timeout=90,
|
||
quiet=True)
|
||
return 1
|
||
print(" ✓ 已写入并备份")
|
||
|
||
print()
|
||
print("── 3. 重载 nginx ──")
|
||
r = run("sudo systemctl reload nginx && sleep 1 && systemctl is-active nginx",
|
||
timeout=120, quiet=True)
|
||
print(" nginx: " + (r[1] if isinstance(r, tuple) else str(r)).strip())
|
||
|
||
# ---------------------------------------------------------------- 4. 复核
|
||
print()
|
||
print("── 4. 复核 ──")
|
||
r = run(r'''
|
||
echo " --- 监听端口 ---"
|
||
sudo ss -tlnp 2>/dev/null | grep -E ':(80|443|9100) ' | sed 's/^/ /'
|
||
echo " --- 用 IP 访问(不带 Host)---"
|
||
curl -s -o /dev/null -w " http://127.0.0.1/ -> %{http_code} %{size_download} 字节\n" --max-time 10 http://127.0.0.1/
|
||
curl -s -o /dev/null -w " http://127.0.0.1:9100/ -> %{http_code} %{size_download} 字节\n" --max-time 10 http://127.0.0.1:9100/
|
||
echo " --- 用域名访问 ---"
|
||
curl -s -o /dev/null -w " https://yk.xxmxxs.top/ -> %{http_code} %{size_download} 字节\n" --max-time 15 https://yk.xxmxxs.top/
|
||
curl -s -o /dev/null -w " /v1/health -> %{http_code}\n" --max-time 15 https://yk.xxmxxs.top/v1/health
|
||
''', timeout=180, quiet=True)
|
||
print(r[1] if isinstance(r, tuple) else r)
|
||
|
||
print()
|
||
print(" ⚠ 还需要你在 **AWS Lightsail 控制台**里开放 9100 端口:")
|
||
print(" 实例 -> 联网 -> IPv4 防火墙 -> 添加规则 -> 自定义 -> TCP 9100")
|
||
print(" 光配 nginx 没用,外面照样连不上。")
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|