ARTICLE · 1216379
我把遥控器 App 的局域网限制解了——还浑然不知
我把遥控器 App 的局域网限制解了——还浑然不知
自己写的 App、自己配的 Tailscale、自己忘记的子网路由。三件事碰在一起,结果就是:人在外面,遥控了家里的电视。
起因:一个"不对劲"的瞬间
那天在外面吃饭,掏出手机想调一下家里的米家设备。
打开 App,操作灯、开关,一切正常——毕竟 HomeAssistant 跑在 NAS 上,Tailscale 连着,没啥好奇怪的。
然后我无意中点开了自己写的遥控器 App。
居然连上了。 甚至还能操控。
我愣了一下。
这个 App 叫 AIRC(AI 遥控),是我用 Kotlin Multiplatform 写的 Android 遥控器。它的工作原理是:手机通过 ADB 往目标设备(一台插在康佳电视上的 Android 盒子)上部署一个 airc-runtime,之后全部通信走局域网 WebSocket + mDNS 发现。
关键词:局域网。
而我现在人在外面,走的是 4G。
"这 App 绝对没写云中转功能啊……"
排查:娜斯的"诊断报告"
我把情况丢给了 NAS 上常驻的 Hermes Agent(我叫它"娜斯"),让它帮我查网络拓扑。
几分钟后回来了:
Tailscale 设备列表: 100.110.175.89 ds220plus suqishuo@ linux - 100.85.74.46 ace-3 suqishuo@ android active; direct 100.123.9.55 aliyun-derp suqishuo@ linux -NAS 的 Tailscale 配置: AdvertiseRoutes: ["192.168.1.0/24"] IP Forwarding: 已开启真相大白。
原理:Tailscale 子网路由当了一回"隐身网桥"
这事的本质很简单,但效果很离谱。
我的 App 原本的通信路径
AIRC 的设计是纯局域网的:
一加 Ace 3(控制端) │ │ WebSocket(局域网直连) │ ▼Android 盒子(192.168.1.x) │ HDMI ▼康佳电视手机通过 mDNS 发现盒子,然后建 WebSocket 长连接。没有云中转、没有公网穿透、没有任何外网访问逻辑。 就是一段干净的局域网代码。
Tailscale 偷偷干了什么
NAS(ds220plus)上很早之前配过一条命令:
tailscale up --advertise-routes=192.168.1.0/24这意味着 NAS 向整个 Tailscale 网络宣告:"发往 192.168.1.x 的所有流量,由我来转发。"
于是实际的通信路径变成了:
一加 Ace 3(外面,4G) │ │ Tailscale WireGuard 加密隧道 │ (direct UDP / IPv6 直连,不打洞不过中继) │ ▼NAS ds220plus(子网路由器,100.110.175.89) │ │ 本地转发到 192.168.1.0/24 │ ▼Android 盒子(192.168.1.x) │ HDMI ▼康佳电视手机 App 以为自己还在局域网里。
mDNS 发现?Tailscale 虽然不是原生支持 mDNS,但子网路由把整个 IP 层的 192.168.1.x 都打通了——App 直接用 IP 建 WebSocket 连接,NAS 透明转发,App 毫无感知。
这就好比你给家里的每一面墙都装了一扇隐形门,而你忘记了这件事。
为什么是"直连"而不是"中继"?
娜斯的诊断里还有一个关键字段:
ace-3 active; direct [IPv6]:41647, tx 30MB rx 16MBdirect —— 手机和 NAS 之间是 UDP 打洞成功的直连,没有经过 Tailscale 的 DERP 中继。
这意味着:
• 延迟低(不绕路、不排队) • 带宽上限取决于两端网络,不被中继限制 • 流量不过 Tailscale 的第三方服务器
Tailscale 的 NAT 穿透技术在 IPv6 环境下尤其高效。30MB 上传 / 16MB 下载的流量,大概是传了几张截图和操作指令——和我实际使用场景对得上。
这就是"基础设施对了"的感觉
这件事最有意思的不是技术本身,而是一个开发者对自己系统的"失控感"。
我写了 AIRC,我知道它的通信边界是局域网。
我配了 Tailscale 子网路由,但那是很早之前的事了,配完就忘了。
这两件事在我脑子里是两条平行线,从来没觉得它们会相交。
但基础设施不这么想。它不管你记得不记得。它就在那里,默默工作,把两条平行线焊在了一起。
结果就是:我自己写的 App 跨过了我自己认为不可能跨越的边界,而我自己还不知道。
对 AIRC 的启发
这次"意外 QA"也让我重新审视 AIRC 的架构:
1. 不需要加云中转。Tailscale 子网路由已经证明了——只要目标设备的 IP 层可达,AIRC 现有的 WebSocket 方案就能工作。加云中转反而引入延迟、成本和安全隐患。 2. mDNS 发现可以加 fallback。在子网路由场景下 mDNS 不可达(mDNS 是链路层多播,不会被路由),但用户手动输入 IP 或从历史记录重连就能直接用 WebSocket。加一个"上次连接的 IP"快捷入口就够了。 3. Tailscale + AIRC 是一个很好的组合。对于 NAS 用户和 Homelab 玩家来说,这种"局域网 App 自动变成全球可达"的体验,比任何云方案都干净。
配置只需 3 步
如果你也有类似场景——自己写的局域网 App、家里的打印机、没公网 IP 的摄像头——Tailscale 子网路由可以一键打通:
1. 安装 Tailscale
Synology 套件中心搜 Tailscale(SPK 包)。其他 NAS 品牌也有对应版本。
2. 宣告子网路由
SSH 进 NAS:
sudo tailscale up --advertise-routes=192.168.1.0/24(换成你家里的实际网段)
3. 批准路由
登录 Tailscale Admin Console,找到你的 NAS,点击路由旁边的 Approve。
手机端不需要任何配置。Tailscale Android/iOS 客户端默认接受子网路由。
总结
这次经历最好的部分不是技术,而是一种类似"发现隐藏关卡"的感觉:
你自己写的软件,在你不知道的时候,运行得比你预期的更好。
这大概也算一种 Vibe Coding 的 bonus track。
AIRC 项目:github.com/Ernest-su/ai-remote-controller
排查由 NAS 上的 Hermes Agent 完成。
公众号:编码生活禅意录 | 博客:suqishuo.cn















































































