NOTE
手机遥控家里的 agent(实录)
不装手机 App、不向公网开任何端口:手机 Chrome 打开一个 tailnet 内的地址,就是家里那台 PC 的桌面版界面 —— 同一批会话、同一个工作区、实时流式输出。下面是完整做法,外加三个把我坑了半天的判据。
① 最终形态
- 链路:手机 Chrome → Tailscale(WireGuard;直连打不通时自动走 DERP 中继)→ 家里的 tailscaled → serve 把 tailnet 的
:443反代到本机回环 →127.0.0.1:19400小代理(约 100 行 Node)→127.0.0.1:19387桌面版 GUI。 - 手机侧零配置:不输密码、不装 App、不装 Termux。那张签名会话 cookie 是本机代理替它带的,手机从头到尾没拿到过。
- 路由器一根手指都不用动:不需要公网 IP、端口映射、DDNS、反向隧道服务;
serve默认只在 tailnet 内可见(不是 funnel)。
② 为什么"直接连"一定失败(三道闸)
- 闸 1 · 宿主只绑回环:GUI 只听
127.0.0.1:19387,手机哪怕在同一局域网也连不上 → 必须有个"从回环往外转"的东西,tailscale serve就是。 - 闸 2 · /api 要一张绑定"授权域"的签名 cookie:实测不带 cookie 时,连回环 Host 也照样 401;cookie 名 =
base64url(sha256("<host:port>")),payload 里写死 authority。用域名直连时服务端算出的授权域与地址栏对不上,现场签一张也照样被拒(实测 8 组组合全 401)。→ 中间必须有代理,让上游始终看到回环授权域。 - 闸 3 · 上游有意不给远程页面完整能力:客户端按"地址栏主机名是不是回环"决定设置持久化模式,非回环 →
memory,设置镜像一个请求都不发。这是设计不是 bug → 本文不绕它:手机上看会话、跑 agent,要改设置回 PC 上改。
③ 工具与步骤
- 只用两样:Tailscale(两端各一个客户端)+ Node(那个小代理,零依赖)。
- Step 1 · 打通 tailnet:
tailscale status/tailscale ip -4/tailscale netcheck(UDP: true说明能直连)。 - Step 2 · 开 443 反代:
tailscale serve --bg --https=443 http://127.0.0.1:19400。关键在--bg:规则写进 tailscaled 自己的配置,重启电脑后自动恢复(实测重启后两条规则都还在)。想保留裸端口再加--bg --tcp=19400 tcp://127.0.0.1:19400。 - Step 3 · 小代理干三件事:① 把 Host / Origin 改写成回环 ② 从本机凭据库取密钥、现签一张 cookie 带上(30 天,值不落日志)③ 转发 WebSocket 升级(实时输出是 wss 不是轮询;Node 的 http 服务不会自动转发 upgrade,得手工写请求行)。只绑回环 —— 绑
0.0.0.0等于把凭据送给整个局域网。 - Step 4 · 自启:启动夹里放
.lnk(目标wscript.exe,参数是你的.vbs)。启动脚本要幂等、要在宿主没起来时也照常启动代理、要写日志 —— 三条缺一条,出问题就没法查。
④ 三个坑(每个都附判据)
- 坑 1 · 启动夹里放"裸脚本"不会被执行:把
.vbs直接丢进启动夹,重启后代理没起,无报错、日志一行都没有(启动夹里的东西是按文件关联被"打开"的)。判据:自启没生效时先看日志有没有那一行 —— 一行都没有 = 根本没被执行;有行但失败 = 脚本内部问题。正确做法是放.lnk→wscript.exe。 - 坑 2 · 第三方 VPN 的系统代理把 tailnet 也代理了:Clash 系客户端会把系统代理设成
127.0.0.1:<port>,bypass 列表通常写死localhost;127.*;192.168.*;10.*;172.16-31.*—— 不含100.64.0.0/10,也不含*.ts.net,于是这台电脑上所有浏览器都访问不了 tailnet。判据:node(不走系统代理)返回 200 / 浏览器(走系统代理)返回ERR_CONNECTION_CLOSED。修法是把100.*;*.ts.net加进 bypass(VPN 重连可能把它写回去)。 - 坑 3 · 会出事的是"路由"不是"端口":流行说法是"VPN 抢了 Tailscale 的 UDP 41641",实测不成立(VPN 全程开着,
41641一直属于tailscaled,手机 peer 走蜂窝 IPv6 直连)。真正会断线的是某些 VPN 抢192.168.0.0/24与整个100.0.0.0/8。判据:tailscale status看 peer 是direct还是relay;route print看谁接手了这些段。另外 Windows 版 Tailscale 没有官方改 WireGuard 端口的入口,所以"重分配端口"这条路本来就走不通。
⑤ 怎么证明"真的可用"(不是"页面能打开")
- 鉴权链路:
POST /api/session/list到那个 HTTPS 地址必须回 200 才算过(401 unauthorized= 没过鉴权)。手搓 body 会得到invalid client-request,那也是 200,恰好证明鉴权已经过了。 - 实时通道:握手
wss://<host>/api/remote.mux必须回 101 Switching Protocols。 - 手机到没到:
tailscale status里手机 peer 是online+active,并看清是direct还是relay。 - 扛不扛重启:重启后
tailscale serve status里两条规则都还在、代理日志里有started一行。
⑥ 边界与安全(照实说)
- 只在 tailnet 内:别用
tailscale funnel—— 那会把桌面版 GUI 暴露到公网。代理只绑回环;那张 cookie 是 30 天的长期凭据,别把脚本与凭据库放到共享机器上。 - 手机端设置页不可用是上游有意设计,本文不去绕它。
- 四个前提同时成立才"丝滑":① 有人登录 Windows ② 宿主 GUI 在跑 ③ 宿主回环端口不漂移 ④ 别启动会抢
100.0.0.0/8的那个 VPN 客户端。宿主彻底关机、或重启后没人登录,用户级启动项不会跑 —— 这一层做不到"无人值守"。 - 实测数字:手机(蜂窝 IPv6)→ 宿主 direct;
wss://…/api/remote.mux→ 101;POST /api/session/list→ 200;第三台机器走 tailnet 打开同地址 HTTP 200;两条serve --bg规则重启后仍在。
留言所有留言都公开可见(审核通过后)。默认先审后发:挡的是广告和机器人,不是你的不同意见。
还没有人留言。
写两句(公开,提交后需审核)
你的昵称:过热的探针 39
不接受广告、引流与人身攻击;可要求删除自己的评论。