怎么唤醒远程局域网的机器
背景
局域网唤醒如果在局域网发起,那没什么复杂的,随便找一个 app、cli 就能实现,如果想唤醒的时候不在局域网用什么方式呢?(当然要有能连到局域网的能力,纯不在局域网,靠 IoT 来电开机那种,不在本文讨论范围内,那也不是唤醒而是远程开机)
方式一:登录远程机器 用命令行唤醒
这个是我之前最常用的方式,需要的时候登录24小时开机的机器,这个时候就在局域网了,直接用终端命令换起来,最多配置一个别名,省得记网卡 mac 地址了。
方式二:写一个小服务
这个是周末临时的想法,因为方式一总要有一个 登录到远程机器 的操作,效率还是低,如果想不登录远程机器,那就写一个 web 小服务,装在这个远程机器上,需要的时候直接访问网址,点一下就行,唤醒由这个程序来做。现在已经实现了,方法也很简单,顺便看了 bun 对 nodejs 的支持到底到什么程度了,简单的项目在这里:
web wol by bun
长期来说 ,我主要还是用这个方式。
方式三:用现成的 app 操作 - 需要额外虚拟一个广播地址
在实现方式二的时候看到 魔术包
和 广播地址
的概念,之前的对成品 app 填 ip 的理解是错的(之前一直填的要唤醒的机器的 ip 😅 ),实际是不填就默认 255.255.255.255
,就广播了。
有了这个知识,又多了一个思路,比如用手机或者不在局域网的机器上的 wol app, 且已经连通了 (wireguard, etc) ,这种能直接唤醒对面局域网的机器么? 答案是肯定的,实际原理还是流量转发或者广播地址模拟相关。
家庭局域网一般没有专门的具有广播能力的 ip,所以选填 ip 那都不填,用 255.255.255.255
来广播,怎么自己造一个有广播能力的 ip 呢?
macOS (亲测有效):
arp -s 192.168.1.254 FF:FF:FF:FF:FF:FF
linux (未实测,因为24小时开机的是一个mac mini):
ip neighbor add 192.168.1.254 lladdr FF:FF:FF:FF:FF:FF dev eth0 nud permanent
再啰嗦一点,上面的两个命令实际就是虚拟了一个具有广播能力的 ip 地址,这样在远程环境,wol app 里填的广播地址就是这个 ip,这样发出来的唤醒请求被 ip 254
收到(虚拟广播地址是在远程那个24小时开机的机器操作的),又在局域网转发广播了,所以就唤醒了。
另外以上的 arp 虚拟操作在 macOS 是一次性的,如果想要持久化,还要创建一个 shell 脚本,并把这个脚本放到开机执行即可,具体可以网上搜或者参考: https://ti.bi/posts/macOS_wireguard_server_dnspod.html