# -*- coding: utf-8 -*- r'''把 package_remote.py 里的 RELAY_README 整块换成新版本。 为什么按块换而不是用 edit 工具: 那段是个 f-string 三引号大块,里面有几百行、 还有各种全角空格和竖线字符,逐字符对齐很容易失败。 定位「RELAY_README = f"""」到下一个单独的 `"""` 行更稳。 ''' from __future__ import annotations import sys from pathlib import Path SRC = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote" r"\_build\package_remote.py") BOM = b"\xef\xbb\xbf" NEW_BODY = '''RELAY_README = f"""======================================================== 服务器端(随身 WiFi / Linux) 版本 {VERSION} ======================================================== 作用:让**不在同一个网络**的电脑和手表连上。 手表 ──HTTPS──┐ ├──> Cloudflare ──> 本机 :8080 电脑 ──HTTPS──┘ 本程序是**纯标准库**的 Python,不装任何第三方包。 内存占用约 20MB,加 cloudflared 共约 60MB —— 512MB 的小机器跑得动。 【装:一条命令,全自动】 把本文件夹拷到设备上,然后: bash deploy.sh 它会一口气做完这些,不用你一步步敲: 1. 检查并安装 cloudflared(已经装了就用现成的) 2. 把中转程序装到 /root/lanremote-relay/ 3. 网络调优(keepalive / MSS / MTU / 开机加速) 4. 注册并启动 4 个 systemd 服务(开机自启) 5. 配好 Cloudflare 隧道 6. 自检,然后把**公网地址**打印出来 ── 三种常见情形 ── ① 机器上已经有隧道凭据(/root/.cloudflared/*.json) 直接: bash deploy.sh ② 有 Cloudflare 给的隧道 Token TUNNEL_TOKEN=eyJhIjoi... bash deploy.sh (用环境变量而不是 --token,Token 就不会留在 shell 历史里) ③ 换域名 / 只装中转不要隧道 bash deploy.sh --hostname relay.你的域名 bash deploy.sh --skip-tunnel 看全部参数: bash deploy.sh --help **重跑 deploy.sh = 升级**,不会把已有配置冲掉: 设备数据、配对码、管理密码、隧道凭据、手工改过的 config.yml 都会原样保留。 【常用命令】 lanremote-status 看整体状态(服务 / 端口 / 公网 / 内存) lanremote-url 打印当前公网地址 lanremote-key 打印管理钥匙 systemctl status lanremote-relay systemctl status lanremote-tunnel journalctl -u lanremote-relay -f 【关于 install.sh(旧版脚本,仍在包里)】 装匿名快速隧道,公网地址每次重启都变。 新机器建议用 deploy.sh(具名隧道,地址固定)。 install.sh 保留是为了兼容已经用它装过的机器。 【地址老变怎么办?记住一个局域网地址就行】 匿名隧道的公网地址每次重启都会变。查当前地址: 浏览器打开 http://<随身WiFi的IP>:8080/url 它会直接返回当前的公网地址,纯文本,不用登录。 具名隧道(deploy.sh 装的)地址是固定的,不用管这个。 【管理】 官网: <公网地址>/ 管理页: <公网地址>/?key= 管理密码: 120830(存在 data/admin_password.txt,可改) 能看到:设备列表、在线状态、配对码、流量、会话数 能操作:踢会话、抹掉配对码绑定 【网络调优:这些参数都是实测调出来的】 deploy-tune.sh 会做这五件事,改动之前先看它开头的说明: ① TCP keepalive 30/10/3 这条 4G 线路会**静默丢连接**(不发明文 FIN/RST)。 Linux 默认要 7200 秒才发现死链,表现就是"过几分钟突然 502"。 改成 30 秒首发探测之后,最快 60 秒就能发现并重建。 ② tcp_mtu_probing = 1 接口写着 MTU 1500,但实际路径扛不住(1472 通、1500 全丢)。 不打开探测的话,新建 TLS 连接约 30% 失败。 ③ MSS 钳制到 1360 只限制 TCP 段,不动链路层。 实测:不夹 87%,夹到 1360/1400 都是 100%。 ④ 接口 MTU 1400 **这一条是专门给 QUIC 隧道的**:MSS 钳制走 iptables 的 TCPMSS 目标,只对 TCP 生效;QUIC 跑 UDP,完全不受它保护。 QUIC 的包超过路径 MTU 就会被丢,而 UDP 丢包不回 ICMP, 只能干等握手超时(日志里那句 "failed to dial to edge with quic: timeout: no recent network activity")。 实测把 MTU 从 1500 降到 1400:建齐 6 条连接 28 秒 -> 13 秒。 ⑤ mask 掉 systemd-networkd-wait-online 这台机器 wlan0 归 NetworkManager 管, systemd-networkd-wait-online 傻等一个不归它的网络, 干等 2 分钟超时,把 relay / tunnel 全拖住。 实测:掉电重启后公网恢复 2 分 10 秒 -> 24 秒。 【隧道的两套配置】 deploy.sh 会装两份隧道服务,但**只启用一份** —— 两条隧道同时跑会互相争抢,实测反而更不稳。 lanremote-tunnel 主用(默认 quic) lanremote-tunnel-h2 备用(http2) 想切换: systemctl disable --now lanremote-tunnel systemctl enable --now lanremote-tunnel-h2 为什么默认 quic:尾部延迟好得多(实测 P99 2.99 秒 vs 13.9 秒)。 什么时候换 http2:这条线路对 UDP 特别不友好的时候 (日志里大量 "Failed to dial a quic connection")。 【省内存】 默认给服务设了 MemoryMax(relay 128M / tunnel 160M)。 要再省就把用不上的服务停掉: systemctl stop mariadb php8.2-fpm apache2 systemctl disable mariadb php8.2-fpm apache2 """''' def main() -> int: raw = SRC.read_bytes() had_bom = raw.startswith(BOM) text = raw.decode("utf-8-sig") start = text.find('RELAY_README = f"""') if start < 0: print(" ✗ 找不到 RELAY_README 的开头") return 1 # 结束:从开头往后找第一个「单独一行 """」的结束引号 body_start = start + len('RELAY_README = f"""') end = text.find('\n"""', body_start) if end < 0: print(" ✗ 找不到 RELAY_README 的结束引号") return 1 end += len('\n"""') # 把结束引号一起吃掉 old = text[start:end] print(" 原块 %d 行 -> 新块 %d 行" % (old.count("\n") + 1, NEW_BODY.count("\n") + 1)) if old.strip() == NEW_BODY.strip(): print(" 内容已经一样了,不动") return 0 text = text[:start] + NEW_BODY + text[end:] data = text.encode("utf-8") if had_bom: data = BOM + data SRC.write_bytes(data) # 语法自检 import ast ast.parse(SRC.read_text(encoding="utf-8-sig")) print(" ✓ 已替换,语法检查通过") return 0 if __name__ == "__main__": sys.exit(main())