最近家里又多了一块“电子垃圾”———树莓派 Zero 2 W,如下图所示,用来作为便携、极简、低成本的旁路由网关。 由于 #树莓派 是“无头”设备:即无显示设备、无键盘、无鼠标;甚至无网线接口、无串口,只需要连接一根电源🔌线,所以很难维护(在不外接设备的情况下),除了网络以外几乎别无它法。
但是,网络配置很容易出错,而如果一旦配置出错,几乎就🟰设备已完全失联,只能重装系统。 好在重装系统时所用的官方 Imager 非常友好,可以一键设置需要连接的 WiFi、SSH 用户及证书等, 好处在于可以立马复活,坏处在于数据可能完全丢失。
起因
在经历过一次失联(IP 配置错误)、重装系统的痛苦后,我就想到,既然基于 WiFi 的网络不太“稳定”,能不能基于蓝牙?因为 #蓝牙 可以说是点对点的连接、不需要借助外部设备。 然后我就调研了一下,发现网上有很多人有类似需求,也有一部分“复杂”的实现。复杂在于,他们是尝试用 RFComm 设备连接到 getty 设备(获取默认的屏幕串口设备),实现复杂,且不稳定。
我的想法是:sshd 是绑定在 0.0.0.0 上面的,即便没有 WiFi 连接,通过 localhost:22 也可以访问成功。 为什么不直接通过蓝牙模拟出一条网络连接(可读、可写即可)访问它即可呢?
实现
我用低功耗蓝牙设备(BLE)实现了两个特性(Characteristics):
- 一个可读,用于从设备发送数据到主机
- 一个可写,用于从主机发送数据到设备
主机连接设备后:
- 主机将这两个特性的读、写数据作为 #ssh 的 ProxyCommand
- 设备将这两个特性的读、写数据转发给 sshd
这样一来,ssh 和 sshd 之间的数据就通过蓝牙从空中传递了。
严厉抨击不少评论者认为 ssh 必须依赖低层的基于 TCP 的网络连接。
代码
参考代码:https://github.com/movsb/tcp-over-bt。
代码量很少,主机和设备的代码行数均不到 150 行。无需任何配置。
在设备上运行后,它会开始广播自己。 尝试 ssh 到设备时,代码会尝试主动扫描第一个可用的设备并尝试连接。
具体的操作方式见代码的 README。
后续
虽然本文标题配文“树莓派”以及“SSH”,而实际上,本文所用的技术并不限制于此; 理论上,所有基于“可读可写的连接”均可用此实现:不限制为 SSH 连接、不限制为树莓派。