折腾笔记:在小米路由器原生系统上部署自定义应用,实现远程开关机

起因:远程开关机的需求

笔者6月初组了台式,并将主机置于角落,按下物理的开关键变得很麻烦,因此有了远程开关机的需求。 经过了解后,发现远程开关机有三种方式:

  • 主板通电开机 + 智能插座物理断电关机
  • 安装 PCIe 开机卡
  • Wake On Lan + SSH关机

智能插座

  • 开机 现代主板都有来电自启动这个功能,开启之后,搭配智能插座的远程通断电功能,如米家插座,就可以远程开机了。

    • 智能插座一般都依赖于路由器提供Wi-Fi,以接入物联网 Internet of Things(IoT) 软件
  • 关机 通过智能插座的物理断电以强制关机。

  • 优缺点

    • 实现简单:只需要购买智能插座和开启主板的来电自启
    • 花费:¥40 智能插座
    • 开机慢: 主板在通电后首次开机,自检项目很多,导致开机时间被延长
    • 断电关机有风险:如果在传输数据过程中关机,操作系统可能会来不及保存数据而造成文件损坏
      • 向日葵智能插座提供了软关机的方式,但需要后台运行向日葵监控软件

PCIe 开机卡

按下机箱上的开机键,会让电脑开关机,其本质就是短接下主板的 power on/off 针脚,而接入 PCIe 开机卡则是能够通过 IoT 软件中发出开关机的指令。

  • 接入 PCIe 开机卡,同样需要路由器提供Wi-Fi,才能接入 IoT 软件。

  • 优缺点

    • 规避了物理通断电的缺点
    • 会占用主板上的 PCIe 槽,虽然不会抢带宽
    • 花费:¥40 PCIe 开机卡
    • 部分厂商无法接入米家

Wake On Lan + SSH关机

开机:网络唤醒 Wake on LAN (WoL),设备通过局域网向目标主机的网卡发送指令,网卡就会通知所在主板开机。 关机:设备通过SSH远程登录指定主机,然后执行关机指令。

优缺点:

  • 需要额外的且24h 运行的设备
    • 如果能够解锁路由器的SSH,就可以用路由器充当这个设备。否则需要考虑 NAS,软路由等。
  • 实现麻烦:
    • 开启 WoL,需要调整主板,系统内的设置,SSH 远程指令,更是大坑
  • 花费:¥0,现有设备,才应该考虑这个方案。

出于折腾和省钱的目的,笔者选择了第三种方案。

警告

  1. 刷机,乃至于开启 SSH都有可能失去官方保修,请谨慎操作
  2. 小米路由器开启SSH 对系统版本有要求,新版本固件很可能不支持开启SSH

前期准备

注册巴法云账号

注册一个巴法云账户,并添加一个006后缀的主题。

可参考:平台操作教程 | 巴法文档中心

步骤如下:

  1. 打开 巴法物联网云平台,使用邮箱或手机注册。
  2. 点击「控制台」,拷贝自己的私钥,后续会用到。
  3. 新建主题-命名为 pc006,名称可以为任意英文,但必须以006结尾,表示开关设备。

效果如图: bemfa init

  • 点击「昵称」,网页会弹出「修改昵称」的窗口,以供自定义。

为受控电脑安装 SSH 服务

Windows

具体的安装方法请参考:Windows 上的 OpenSSH:安装、配置和使用指南 - 系统极客

在开始安装 OpenSSH 之前,请确保你的电脑满足以下条件:

  • 操作系统:Windows 11 或 Windows 10(1809 版本或更高)。
  • PowerShell 版本:PowerShell 5.1 或以上。
  • 管理员权限:安装 OpenSSH 需要拥有管理员权限。

Linux

Linux 电脑一般都安装 OpenSSH,如果没有可以通过各发行版的包管理工具安装:

  • DebianUbuntu

    sudo apt install ssh
    
  • CentOs

    sudo yum install openssh-server
    

开启受控电脑的 Wake On Lan

开启主板的 WoL

想要使用网络唤醒(Wake-on-LAN,WoL),也需要开启主板BIOS的 WoL 功能,各厂商的主板开启方式不一致,具体方法视厂商而定,进入 BIOS 后注意选项附加的说明即可,可以参考的关键词包括:

  • Automatic Power On
  • Wake on LAN/WLAN
  • Power Management
  • Power On by Onboard LAN
  • Power On by PCI-E Devices

关闭主板的电源节能设置

很多厂商的主板都有低功耗模式,为了节能,该模式下,电脑关机后,会彻底关闭网卡,会无法使用 WoL ,因此需要关闭此类模式。可以参考的关键词包括:

  • ErP
  • EUP

windows 系统设置

配置网卡
  1. 在 Windows 10 中,运行 > ncpa.cpl 打开「网络连接」设置,然后找到当前在使用的有线网卡,右键点击「属性」:

    image-20240723000140265
  2. 点击「配置」:

    image-20240723000220472
  3. 切换到「电源管理」,勾选「允许此设备唤醒计算机」以及「只允许幻数据包唤醒计算机」:

    image-20240722235715931
关闭快速启动
image-20240901234515640
  1. 先点击「更改当前不可用的设置」,以便能修改关机设置
  2. 关闭「启用快速启动」(快速启动(Fast Startup),属于 S4 电源状态,不支持网络唤醒)

部署 pc

笔者编写了一个小应用(下文称为 pc),依赖于 WakeOnLan、巴法云和SSH协议,实现了远程开关机:

sequenceDiagram
	actor user AS 用户
	participant iot AS iot(小爱同学)
	participant bemfa AS 巴法云
    participant power AS pc
	participant pc AS 电脑

	rect rgb(191, 223, 255)
	Note over user,pc: 远程关机
	user ->>+ iot: 语音:关电脑
	iot ->> bemfa: 推送消息:"off"
	bemfa ->> power: TCP("off")
	power ->> pc: SSH("关机")
	pc ->> pc: 关机
	iot --)- user: ok(异步)
    end
    
	rect rgb(248,240,233)
	Note over user,pc: 远程开机
    user ->>+ iot: 语音:开电脑
	iot ->> bemfa: 推送消息:"on"
	bemfa ->> power: TCP("on")
	power ->> pc: WoL & SSH("取消关机")
	pc ->> pc: 开机
	iot --)- user: ok(异步)
    end

开启设备的 SSH/Telnet

pc 需要运行在局域网内不停机的机器上,如路由器、NAS。

因此需要能登录到目标机器上,然后下载并运行pc。最常用的远程登录协议为 SSH,搭配 SCP 操作文件系统也会更方便。

  • 某些设备只能启用 Telnet 协议,无法启用 SSH ,操作会繁琐一些。

以笔者的小米路由器 AX3000T(1.0.47版本下)为例,开启SSH的步骤:

  1. 登录路由器后台,复制 stok变量

    image-20240727194218564

  2. 将脚本内容保存到 stok.bat 文件中,执行后并输入复制的stok变量,

    @REM 使用 UTF8 编码,以正确显示中文
    chcp 65001
    
    @echo off
    
    @REM  <STOK>修改为复制的变量
    echo Input the ^<STOK^> in admin page of your Xiaomi router
    echo 输入你小米路由器中后台页面中的 ^<STOK^>
    set /p STOK=
    @REM echo %STOK%
    
    curl -X POST http://192.168.31.1/cgi-bin/luci/;stok=%STOK%/api/misystem/arn_switch -d "open=1&model=1&level=%0Anvram%20set%20ssh_en%3D1%0A"
    
    curl -X POST http://192.168.31.1/cgi-bin/luci/;stok=%STOK%/api/misystem/arn_switch -d "open=1&model=1&level=%0Anvram%20commit%0A"
    
    curl -X POST http://192.168.31.1/cgi-bin/luci/;stok=%STOK%/api/misystem/arn_switch -d "open=1&model=1&level=%0Ased%20-i%20's%2Fchannel%3D.*%2Fchannel%3D%22debug%22%2Fg'%20%2Fetc%2Finit.d%2Fdropbear%0A"
    
    curl -X POST http://192.168.31.1/cgi-bin/luci/;stok=%STOK%/api/misystem/arn_switch -d "open=1&model=1&level=%0A%2Fetc%2Finit.d%2Fdropbear%20start%0A"
    
    pause
    

    效果大概是这样的:

    image-20240805002207392

下载 pc

根据设备的芯片架构及安装的操作系统,找到对应的压缩包:Release

如果是 Linux/OpenWrt 系统,可以在命令行输入 cat /etc/os-release | grep ARCH 以查看设备的架构,以笔者的为例:

cat /etc/os-release | grep ARCH
LEDE_ARCH="aarch64_cortex-a53" # cortex-a53 是 实现ARMv8-A 64位指令集的微架构,故 CPU 是 arm64架构的

在目标设备中,将解压后的二进制文件及配置文件移动到可读写的文件夹,实现方式有两种:

  • 直接通过 curlwget 命令下载压缩包后解压
  • 在其他设备上下载后,通过 scp 等协议上传到设备

修改配置文件

pc 使用 yaml文件作为配置文件,使用前,使用者应当熟悉一下 yaml 的基本语法,以修改或补全空白配置项的值:

# 当前程序所在主机的局域网IP,即通过 SSH/Telnet 登录的设备,一般为路由器/NAS
# 小米路由器的局域网IP一般为:192.168.31.1
myIP: ""

# 目标主机的主板网卡MAC地址,
# windows 机器可以在命令行中输入 `ipconfig /all` 查看,如:00-1B-44-11-3A-B7
targetMac: ""

# ssh 配置
ssh:
   # 目标主机的 IP + SSH 端口号
   # host:port 如 192.168.31.111:11022
   addr: ""

   # 用户名,目前支持私钥和密码登录
   user: ""

   # 私钥路径,建议使用绝对地
   # 通过公私钥登录,推荐使用
   #
   # 私钥可通过其他设备上的 `ssh-keygen -t ed25519 -f ed25519` 命令生成
   # 然后将 ed25519 私钥上传至运行设备上
   identity: ""

   # 使用密码登录,可选项
   # 密码明文,应当在局域网环境使用
   password: ""

# 日志设置
log:
   # 日志文件位置,默认为 pc.log
   file: /tmp/log/pc.log

   # 是否打印代码位置
   addSource: false

   # 日志级别
   # 定义见 log/slog/level.go:43
   # LevelDebug Level = -4
   # LevelInfo  Level = 0
   # LevelWarn  Level = 4
   # LevelError Level = 8
   level: 0


bemfa:
   # 巴法云的 UID,即控制台的私钥
   uid: ""

   # topic-switch
   switch:

      # 主题的名称
      topic: XXX006

      # Switch 只接收 on/off 两种指令,对应的操作
      # 覆盖这里的指令之前,你应该在默认的 shell,Linux(sh)/Windows(cmd) 中测试一下,以确保关机指令和取消指令是正确的。
      on: cmd /c shutdown /a
      off: cmd /c shutdown /s /t 600

调试 pc

  1. 运行 pc

    # Linux 机器上,赋予 `pc` 执行权限
    chmod +x pc
    # 指定配置文件并运行
    ./pc -config config.yml
    
  2. 通过巴法云推送消息

    在巴法云控制台,如果连接正常,pc 订阅的主题上,会显示订阅者的在线数量:

    • 设备(Windows)处于开机状态

      • 推送 off,弹窗显示,即将关机:
      • 推送 on,弹窗显示,关机被取消:
    • 设备处于关机机状态

      • 推送 off,设备无反应
      • 推送 on,设备 开机
  3. 后台运行 pc 若调试后无问题,即可在设备上后台运行 pc, 以捕获巴法云的消息推送

    ./pc -config config.yml &
    
  4. 巴法云接入 iot 软件

    • 米家:
Licensed under CC BY-NC-SA 4.0
发表了9篇文章 · 总计7.98k字