路由器(梅林固件)实现局域网电脑远程开机

前言

笔者是从淘宝购得已刷好梅林固件的华硕路由器,型号为 RT-AC86U,具有koolshare软件中心,价格实在是不便宜,不过平心而论,强得很(借用iPhone 13的宣传语),今天就来介绍一个小功能,远程开机。我个人时常需要用笔记本电脑唤醒家里的台式机,来获取一些存货。

  • Asuswrt-Merlin: Asuswrt-Merlin is a third party alternative firmware for Asus routers, with a special emphasis on tweaks and fixes rather than radical changes or collecting as many features as possible.
  • 梅林固件Asuswrt-Merlin 是华硕路由器的第三方替代固件,特别强调轻微调整和修复,而不是激进的更改或收集尽可能多的功能。
  • 华硕官改固件:华硕官改固件是根据华硕对应机型的源代码,在尽量不更改固件其它地方的前提下,增加koolshare软件中心。尽量保持官方固件的原汁原味,又能拥有软件中心。
  • 远程开机(Wake on LAN,WOL):俗称远程唤醒,是现在很多网卡都支持的功能。而远程唤醒的实现,主要是向目标主机发送特殊格式的数据包,是AMD公司制作的MagicPacket这套软件以生成网络唤醒所需要的特殊数据包,俗称魔术包(Magic Packet)。MagicPacket格式虽然只是AMD公司开发推广的技术,并非世界公认的标准,但是仍然受到很多网卡制造商的支持,因此许多具有网络唤醒功能的网卡都能与之兼容。

实现思路

要想远程打开家里的电脑,首先电脑的主板和网卡必须都支持远程唤醒功能,其次得有个常开的路由器,最后要在公网上可以访问到这个路由器。当然,你如果有钱直接买向日葵的开机硬件产品也行,不过那些产品通常也需要连接WiFi。

网卡支持远程唤醒

在有线网卡的电源管理选项卡中,按照这个界面勾选即可,未勾选的“只允许幻数据包唤醒计算机”,代表着网络中的其他通信也可以唤醒计算机。

常开的路由器

给路由器24小时供电即可,如果路由器长时间运行不稳定,通常可以设置定时重启功能,非常有效。

公网访问路由器

你的家庭宽带如果可以直接获得公网IP,静态的最方便,动态的也可以使用DDNS功能,这一步就完成了。

但通常都不会有公网IP,所以引出了内网穿透的概念。

内网穿透

DDNSTO

DDNSTO使用教程

笔者之前一直使用的都是DDNSTO,远程登录路由器,再从路由器的网络工具——通过网络(LAN)唤醒功能去启动家里的计算机。

不过目前DDNSTO的服务器得每隔七天去主动申请一次免费服务才行,你也可以付费购买长期服务,另外,使用时可能需要微信扫码认证,略嫌麻烦,那个限时活动也戳伤了我,而后切换到了下面这种方式。

Zerotier

同样,在软件中心,可以安装Zerotier,然后在笔记本上也装上,台式机也可以装上,都连入同一个网络中,为了给Zerotier加速,可以参考以前的文章:ZeroTier创建Moon节点

而后,你就可以直接输入在Zerotier上分配给路由器的IP地址,从而访问到路由器上了,再通过路由器的界面去唤醒。

用脚本唤醒

但我懒得很,连打开浏览器界面按按钮都觉得费劲,于是乎,便去研究了路由器是如何唤醒计算机的,写了个简单脚本,实现启动脚本便唤醒指定计算机的功能。

开启SSH

不入虎穴焉得虎子,我们先进入路由器的系统管理——系统设置界面,开启SSH功能。

在笔记本上用 ssh-keygen 生成 rsa 的密钥,然后将公钥内容填入授权密钥中,即可实现免密码访问。

分析网页源码

用SSH进入路由器后,即可查看 /www/Main_WOL_Content.asp 的内容。

通过分析页面源码,可以知道实际上是通过 /usr/sbin/ether-wake -i br0 -b 00:00:00:00:00:00 这个命令去唤醒计算机的,最后一段便是网卡的 MAC地址。

脚本编写

一个简易脚本就新鲜出炉了,提供一个下载链接,也可以按照下面的方式手动创建。

下载链接:WakeOnLan.cmd

手动创建:

  1. 在文本编辑器(记事本、Notepad++等)中粘贴以下代码;
  2. 第11行,将 htlsmile 替换为你自己设置的路由器登录用户名;
  3. 第12行,将IP地址 172.23.1.1 替换为在Zerotier中给路由器分配的IP地址;
  4. 第13行,将MAC地址 98:EE:CB:B1:C5:07 替换为待唤醒的计算机网卡MAC地址;
  5. 另存为 WakeOnLan.cmd,建议同时设置该文件为只读。

如果之前在路由器SSH服务中,你已经设置好了授权密钥,那么双击脚本即可实现无密码确认,直接唤醒计算机;如果没有设置SSH公钥,你可以按照提示输入密码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
:: *******Begin Comment**************
::
:: @description This program attempts to wake up the computer through the Asuswrt-Merlin router.
:: @author htlsmile
:: @date 2021/09/25
::
:: *******End Comment**************

@echo off

set router_username=htlsmile
set router_ip=172.23.1.1
set mac_address=98:EE:CB:B1:C5:07

title WakeOnLan
color 1F
chcp 437 >nul
echo.
echo " _ _ _______ _ _____ __ __ _____ _ ______
echo " | | | |__ __| | / ____| \/ |_ _| | | ____|
echo " | |__| | | | | | | (___ | \ / | | | | | | |__
echo " | __ | | | | | \___ \| |\/| | | | | | | __|
echo " | | | | | | | |____ ____) | | | |_| |_| |____| |____
echo " |_| |_| |_| |______|_____/|_| |_|_____|______|______|
echo "
echo "
echo.

:Ping

echo.
echo Try connecting to the router[%router_ip%]...
echo.
ping -n 1 %router_ip% >nul

:: 在批处理程序中使用 ERRORLEVEL 值时,必须按降序列出它们。
:: https://docs.microsoft.com/zh-cn/windows-server/administration/windows-commands/choice#remarks

:: ifERRORLEVEL 的用法
:: https://docs.microsoft.com/zh-cn/windows-server/administration/windows-commands/if

if ERRORLEVEL 1 goto NotConnected
if ERRORLEVEL 0 goto Connected

:NotConnected

color 4F
echo.
echo Router[%router_ip%] Unreachable !
echo.
goto ExitCmd

:Connected

color 2F
echo.
echo Router[%router_ip%] Reachable !
echo.
echo.
echo Wake up MAC[%mac_address%]
echo.
ssh -l %router_username% %router_ip% "/usr/sbin/ether-wake -i br0 -b %mac_address%; exit"
if ERRORLEVEL 1 goto SSHError
echo.
echo Wake up complete!
echo.
goto ExitCmd

:SSHError

color 4F
echo.
echo ssh [%router_ip%] error !
echo.
goto ExitCmd

:ExitCmd
timeout /T 5
exit

使用效果

尝试连接

连接成功

连接失败


后记

果然懒惰才能促使人进步,尽管写下这篇文章都花了两个小时,顺带一提,脚本中的那个字符画,是在 Text to ASCII Art Generator (TAAG) 中生成的,好用得很。