Files
ykxmz/_build/patch_relay_readme.py
T
xmz7891 facb156aca 服务端 zip 加一键部署脚本(cloudflared 安装 + 部署 + 公网,全自动)
用户要求:服务器端文件里放一个 .sh,双击就能检查 cloudflared 装没装、
自动部署、配好公网,以后全自动。

== 新增 ==

relay/deploy.sh        一键部署主脚本,7 步全自动:
                       环境检查 -> 装 cloudflared -> 部署程序 -> 网络调优
                       -> 写 4 个 systemd 服务 -> 配隧道 -> 启动自检打公网地址
relay/deploy-tune.sh   网络调优,可单独重跑:
                       keepalive 30/10/3 + 路径 MTU 探测 + MSS 1360
                       + 接口 MTU 1400 + mask networkd-wait-online
                       每一项都写明了实测依据

用法:
    bash deploy.sh                           复用已有凭据,全自动
    TUNNEL_TOKEN=eyJh... bash deploy.sh      Token 模式
    bash deploy.sh --hostname relay.你的域名  换域名
    bash deploy.sh --skip-tunnel             只装中转
    bash deploy.sh --help                    全部参数

重跑 = 升级;已有数据/配对码/管理密码/凭据/手改过的 config.yml 都不动。

== 自动化到什么程度 ==

* cloudflared 不在就自动下载装上(并校验能执行)
* 隧道支持两种模式:已有凭据文件、或 TUNNEL_TOKEN
* **不传 --hostname 且没有 Token 时明确提示要填**,不会静默用一个写死的值
  (用户明确说过:这个中转站是他自己用的,不对外开放,
   绝不能把私人域名烧成默认值)
* deploy-tune.sh 的 MTU 取 1400:路径 MTU 实测 1472,
  而 MSS 钳制只管 TCP、QUIC 走 UDP 完全不受保护;
  接口 MTU 降到 1400 后 QUIC 建齐 10 条连接从 28 秒缩到 12 秒

== 顺带修掉两个真 bug ==

1. write_tunnel_unit 写的文件名漏了 .service 后缀 ——
   文件写下去了但 systemd 完全看不见,enable 还会安静地失败。
2. 发布包一直缺 site_shots/(老 bug):
   package_remote.py 用 iterdir() + is_file() 收文件,目录进不去。
   新机器装完官网截图全是 404。只有从 zip 解压真跑一遍才暴露。
   同时把 deploy.sh 里 site_shots 的检查降级成警告(缺截图不该让部署失败)。

另外给 deploy-tune.sh 清旧 MSS 规则的循环加了 10 次上限 ——
原写法在 -D 报成功但规则仍在时会死循环把整个部署卡死。

== 验证 ==

* _build/test_deploy_sh.sh        沙箱 65 项,全通过
* _build/test_zip_deploy.sh       从发布 zip 解压再跑,30 项,全通过
* _build/test_deploy_real.sh      **真机 Debian 上实测**(新增):
    zip 解出 17 个文件 -> 语法/LF/无 BOM 通过
    --help 退出码 0 且无副作用、未知参数退出码 2
    沙箱安装成功、幂等重跑哨兵不被冲
    现有三个中转服务全程 active,自检 200
2026-10-07 17:28:09 +08:00

205 lines
6.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- 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=<lanremote-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())