让手机连上家里电脑的 AI Agent:OpenTandem 的内网穿透与安全架构实践

2 阅读6分钟

越来越多开发者把 Codex、Claude Code 这样的 AI Agent 放在自己电脑上长时间运行,人离开工位之后,自然希望用手机继续查看进度、下达指令。难点在于家里的电脑躲在 NAT 后面,外部无法直接访问。常见的内网穿透方案把答案归结为「打洞」,但打洞需要时间,而且在对称型 NAT 和企业防火墙下注定失败;如果把打洞当成连接的前提,用户要先等打洞完成,打洞失败时就连不上。

我们在做 OpenTandem 时把顺序反过来:连接首先要在任何网络下都可用,其次才追求更快,并且始终要确认是谁在连。由此得出三条设计原则。

原则解决的问题做法
可用性优先于最优路径任何网络下都能连上被控端主动连接云端,先走中转
直连是升级路径,而非前提条件允许时更快、更省后台打洞,成功后无缝切换
只认令牌,不认网络位置连得上不等于有权操作身份识别、短时效令牌、全程加密

图 1 是这套架构的全貌:手机和电脑都连向云端,其中电脑那条连接是主动连出的,中间的绿色虚线是条件允许时建立的直连。

整体架构

一、可用性优先于最优路径

可以把 NAT 想象成一栋办公楼的总机:整栋楼对外只有一个总机号码,也就是公网 IP,楼里每台设备只有内部分机号,也就是内网 IP。分机往外拨没有问题,外部来电却无法直接拨通某个分机,而家里的电脑正处在分机的位置。

下图画出了这栋楼:外部来电被挡在门口,分机 102 只能自己向外拨。

NAT 总机比喻

既然外面打不进来,就让电脑主动拨出去并保持通话,这就是出站长连接:由内网设备主动发起、与云端维持的通道,用户无需配置端口映射。我们的做法是连接建立时先走 WSS 中转。WSS 运行在 443 端口上,形态和普通 HTTPS 流量一样,几乎所有网络都会放行,也不需要等待任何打洞过程,用户打开手机就能马上开始操作。代价是所有数据都要经过云端转发,时延与带宽成本更高,这正是第二条原则要解决的问题。

二、直连是升级路径,而非前提

直连在这套架构里是后台的升级尝试,建立连接不以它为前提。打洞的原理可以用「来电显示」来理解:路由器会记下自己拨出过的号码,只放行看起来是回应的电话。

  1. 双方分别询问 STUN 服务器,得知自己在外部的号码与端口;
  2. 云端把双方地址互相告知,双方同时向对方发起连接;
  3. 路由器把对方的来电当作自己刚拨出电话的回应而放行,直连建立,这就是打洞。

下图是打洞的全过程:两台设备各自从 STUN 得知公网地址,再同时向对方发起连接。

STUN 打洞

打洞失败时还有 TURN 中继兜底,相当于请总机转接:双方都连到同一台公网中继,由它代为转发。三条通道放在一起看:

通道转发方式时延可达性
P2P 直连无转发最低受 NAT 类型限制
TURN 中继公网中继转发较低高
WSS 中转云端转发较高几乎不受限

我们把打洞放在后台进行,用户不需要等它成功:中转先保证可用,后台持续尝试打洞,一旦直连或 TURN 打通,新的传输切到更快的通道,旧通道等在途请求结束后再关闭;网络环境变化时重新尝试,全程对用户透明。

下图按速度从低到高排列三种通道,箭头表示系统在后台逐级尝试升级。

连接自动升级

有些网络无论如何都打不通,这时连接会一直走中转,速度慢一些,但功能不受影响。

三、只认令牌,不认网络位置

网络打通之后,任何能连上的人都可能发来指令,所以不能因为请求来自某条连接就信任它,而要逐次确认它带着合法的身份凭证。

下图概括了这条校验链路:先识别身份,再签发令牌,最后由电脑校验后才执行。

身份识别与令牌校验

  1. 身份识别:账号登录后还要与具体设备绑定,云端据此确认是谁在操作哪台电脑。
  2. 短时效令牌:云端为每次连接签发短时效令牌,被控端逐次校验,过期即失效。代价是收回权限后,已签发的令牌在有效期内仍可使用,所以有效期必须短。
  3. 全程加密:直连通道使用 DTLS,中转通道使用 TLS,数据传输途中始终是密文;中转节点会解开 TLS,更敏感的数据还需要在两端之间再做一层端到端加密。

结语

这套架构在建立连接时先通过中转保证连通,打洞则在后台尝试、成功后再提升速度,并且每次操作都会校验短时效令牌。另外,大文件走对象存储传输,不占用控制通道。如果只是想用手机驱动本机的 AI Agent,可以直接使用 OpenTandem,无需自行搭建这套基础设施。