Skip to content

Cell - Ta Relay ​

从手机等其他设备连到自己电脑上的 ta serve:两边都向 Relay 发起连接,Relay 只转发,内容端到端加密,Relay 读不到。默认关闭:配对了设备,ta serve 才连接 Relay。

text
手机(RelaySocket) ──wss──▶ Relay ◀──wss── ta serve(RelayHost)──ws──▶ 本机的 /api/ws
          └──────── AES-256-GCM,密钥只在两端 ────────┘

配对 ​

bash
ta pair                          # 新增一台设备,打印配对链接;默认 Relay 是 https://relay.cellbang.com
ta pair https://<relay> --name 手机   # 用自己的 Relay,给设备起名
ta pair --list                   # 已配对的设备
ta pair --remove <设备 id>        # 取消配对,立即生效

配对链接形如 https://<relay>/pair#v=1&h=<主机 id>&d=<设备 id>&k=<密钥>。密钥在 # 之后,浏览器不会把它发给 Relay。在 Ta 应用里粘贴这个链接即可连接。Web 客户端和桌面应用里也能配对:齿轮菜单的"在手机上使用…"把链接显示成二维码(只显示一次),并列出已配对的设备、ta serve 是否连着 Relay,可以取消配对(ta serve 的 TaRelayServer)。设备记在 agent 目录的 relay.json(权限 0600),ta serve 运行时会自己读到改动,不用重启。

协议 ​

  • /v1/host/<主机 id>?secret=<主机密钥>:ta serve 连这里。每个主机 id 归第一个带着它连上来的主机,Relay 只存密钥的哈希。
  • /v1/connect/<主机 id>:设备连这里,Relay 给它分一个通道,转给主机({t:'open'|'data'|'close', ch, d})。
  • 握手:设备先发 {t:'hello', v:1, device, nonce};主机找到设备的密钥后回 {t:'ready', nonce, proof}。两边用 HKDF-SHA-256(设备密钥,盐是两个 nonce)给每个方向各派生一个 AES-256-GCM 密钥,所以每次连接的密钥都不同。proof 是主机加密的第一条消息,证明对方有这台设备的密钥;之后每条消息都加密,IV 就是消息序号,Relay 重放、丢弃或调换顺序的消息都会解密失败。
  • 主机给每台设备单独开一条到本机 /api/ws 的连接,带上本机 token。设备拿不到 token,也不需要。

部署 Relay ​

  • Cloudflare Workers:apps/ta-relay(Durable Objects,空闲时休眠)。
  • 自己的机器:ta relay [--host 0.0.0.0] [--port 8080],放在 HTTPS 反向代理后面。主机 id 的归属只存在内存里,重启后由先连上来的主机重新认领。

已知限制 ​

  • 经 Relay 时,只有 WebSocket 上的调用可用;Web 客户端里本地文件的预览(/api/files)用不了。
  • 设备密钥是长期的,没有前向保密:密钥泄露后,录下的旧流量也能解开。取消配对即可让它失效。