0成本实现远程开机

马上就要放假回家了,几公斤重的主机那当然是带不回去的,手头能用的就只有一台Surface Book初代,然而这已经是6年前的设备了,i5-6300U + GTX940MX的配置实属不够用。想到前不久折腾局域网串流时用过的parsec似乎也能支持广域网串流,能不能用笔记本串流到主机上用呢?那当然是可以的。然而主机毕竟不是服务器,不可能一天24小时开着。那么完成这个计划的第一步,就是实现远程开机了。

远程开机的方法

经过一番搜索,我找到了这么几种可以实现远程开机的方法:

  1. 远程开机棒
  2. 智能插座 + BIOS设置通电即开机
  3. Wake On LAN

其中1和2都是需要购买额外的硬件来实现的,那么穷如我自然不可能选择需要收费的快乐。白嫖一时爽,一直白嫖一直爽。我决定用方案3来实现。

Wake On LAN

Wake-On-LAN简称WOL,是一种电源管理功能;如果存在网络活动,则允许设备将操作系统从待机或休眠模式中唤醒。许多主板厂商支持IBM提出的网络唤醒标准。该标准允许网络管理员远程打开PC机电源,以便进行文件升级、资源跟踪和设备清点等工作。WOL在还未广泛的采用,但在网络时代却具有广阔的发展前景。

Wake-On-LAN的实现,主要是向目标主机发送特殊格式的数据包,是AMD公司制作的MagicPacket这套软件以生成网络唤醒所需要的特殊数据包,俗称魔术包(Magic Packet)。MagicPacket格式虽然只是AMD公司开发推广的技术,并非世界公认的标准,但是仍然受到很多网卡制造商的支持,因此许多具有网络唤醒功能的网卡都能与之兼容。

观察WOL的定义可知,要成功实现WOL,具有以下要点:

  1. 硬件需要支持WOL
  2. 需要远程向目标主机发送幻数据包(Magic Packet)

开启WOL的硬件支持

BIOS设置

一般来讲,较新的主板都是支持WOL的,只不过默认不会开启,因此我们需要进入BIOS开启WOL的支持,各个主板生产商的操作步骤不一样,但是大差不差。对于我正在用的MSI B450 MORTAR来说,需要开启高级->唤醒事件管理->PCIE设备唤醒以及高级->整合周边设备->网卡ROM启动,然后硬件上的设置就完成了。

这里有一个注意点是,在搜索的过程中听说开启快速启动的时候会导致无法唤醒。这个问题我没有遇到,快速启动似乎默认就是关闭的。

快速启动将计算机置于 S4 状态中(正常关机是 S5),而 WOL 仅在 S5 提供支持,所以需要关闭“快速启动”。这一点在不同的计算机上可能有区别,我的硬件仅支持 WOL On S5,据我了解 Mac 仅支持 WOL On S0(S3)。

路由器设置

主要是需要设置DHCP绑定,保证每次分配给主机的内网ip地址都是固定的。

操作系统设置

windows需要在设备管理器中双击网络适配器,然后需要开启高级->关机 网络唤醒高级->魔术封包唤醒电源管理->允许计算机关闭此设备以节约电源电源管理->允许此设备唤醒计算机,但是据我观察,这几个选项一般都是开着的,所以一般不需要特别设置。

向目标主机发送幻数据包

在局域网中向目标主机发送幻数据包是很轻松的,有很多App可以来帮我们完成这件事情,只需要在手机或者什么别的设备上安装好App,然后填入机器的ip地址和Mac地址,在App上就能远程唤醒了。有一部分路由器甚至原生支持WOL的,在管理页面上配置好目标主机的ip及其Mac地址,之后通过管理后台就能直接发送幻数据包来唤醒主机,不过我手上的这个小米AX1800并不支持。

但是换到广域网上,情况就不一样了,众所周知,现在几乎没有运营商会分配公网ip,我们看到的IP大多至少经过了一层NAT,所以直接发送到目标主机几乎是不可行的。除了有一部分品牌的路由器可以在对应的App上进行广域网远程管理,进而通过路由器调用WOL,但是很遗憾,这个我手上的小米AX1800也并不支持。

虽然手上的路由器并不支持这些功能,但是仔细想想,我们现在面临的主要问题就一个:内网穿透。目标主机处于关机状态,自然是不能来承担内网穿透的角色的,所以首先我们需要另一台设备,例如废弃的旧手机,然后进行内网穿透连接到这个设备,最后通过一些办法控制设备来对局域网内的主机进行远程唤醒。

选择唤醒用设备

不难发现,我们之前提到的设备需要有这两个需求:

  1. 24小时开机
  2. 可以进行内网穿透
  3. 可以被远程控制

一般来讲,树莓派之类的小型开发板非常适合用来担当这个角色,但是这里路由器才是最合适的选择。众所周知,路由器其实是一台小型的电脑,它往往具有一个MIPS/ARM架构的处理器,一定的RAM和一定的ROM,本身搭载了一个特殊版本的Linux操作系统,所以2和3是可以满足的。第1点的话,要实现远程开机,自然路由器得24小时开启。路由器很好的满足了这三个要求,所以最终我决定使用路由器来完成这个工作。

1、使用SSH连接到路由器

说到Linux,自然而然的就会想到SSH,路由器既然搭载的是Linux,那么我们就可以通过SSH连接到路由器来进行操作。大部分路由器的SSH功能都是关闭的,我们往往需要使用一些特殊手段来开启。例如利用漏洞注入命令、对路由器进行刷机等,各个路由器的方案不同,可以在网上进行搜索来找到具体的方法。

2、通过SSH发送幻数据包

我们只需要安装一个wakeonlan工具,然后使用以下命令,它就能帮助我们发送幻数据包:

wakeonlan -i 192.168.xx.xx <Mac地址>

各家的安装方法不一定相同,我这个AX1800需要通过以下步骤:

  1. 通过SSH安装了MIXBOX
  2. 在MIXBOX中安装entware
  3. 先后运行opkg install etherwakeopkg install wakeonlan

具体可以参考这个链接

3、开启内网穿透

通过以上步骤,现在应该可以在局域网内通过ssh到路由器来唤醒主机了。但是我们最终需要在外网中进行唤醒,那么首先就要在路由器上进行内网穿透。这里有很多种方法,我最终是使用zerotier构建了一个虚拟局域网,然后只需要连接到虚拟局域网内即可在外网ssh连接到路由器。

安装使用zerotier的过程非常简单,简单叙述一下:

  1. 使用MIXBOX安装zerotier
  2. zerotier官网上注册账号,并创建网络
  3. 在MIXBOX中开启zerotier,并输入2中创建的网络id即可连接至zerotier

碰到的坑

至此,应该可以在外网中唤醒了。但是我之后发现经常会唤醒失败,通过反复控制变量进行试验,最终确定:关机大概1分钟之后就无法唤醒。经过查询发现,此处应该是路由器未进行arp绑定导致的,一般来说这里进行arp绑定之后就可以了。