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)用不了。 - 设备密钥是长期的,没有前向保密:密钥泄露后,录下的旧流量也能解开。取消配对即可让它失效。