Pilo:树莓PI供电的LightOut远程服务器管理

2020-08-23 01:02:03

像许多极客一样,我有一个由现成的消费级PC部件制成的“家庭服务器”,我在上面运行我的周末编程项目,朋友的游戏服务器,这个网站等等。最近,我在家里发生了一次电源故障,导致服务器重新启动。当电源恢复时,服务器启动了,但它停留在启动屏幕上,等待我输入磁盘解密密码!

幸运的是,当时我在家睡觉。一旦我醒来,意识到有什么不对劲,我就可以插上键盘,输入密码了。但是这件事让我思考--如果我当时不在家怎么办?如果我在另一个国家呢?如果有一天,我将这台服务器移出家门,需要定期访问物理屏幕和键盘,该怎么办?

在“真实服务器”世界中,这个问题的解决方案被称为“无人值守管理”(LOM)。每个主要的服务器制造商都有他们自己的风格,比如惠普的iLO(集成无人值守)。甚至还有像IPMI这样的行业标准为LOM实现定义公共接口。LOM系统通常支持的功能包括:

我决定制作我自己的基于树莓PI的LOM,它可以做其中的一些事情,以帮助我下次离开家很长一段时间时减轻压力。我想介绍一下Pilo--“PI Lightout”。

注:这篇文章描述了我是如何得出这个系统的最终设计的。如果你只是想要自己设置的说明,从“教程”开始阅读。

当我开始寻找使用我的PI向计算机发送键盘命令的方法时,我发现的问题是所有现有的方法都依赖于使用Raspberry Pi Zero作为USB主机,这使得无法将板载USB端口用于其他目的。此外,此方法在其他主板上不起作用,如Raspberry PI 3B+。这是有问题的,因为我想使用3B+,因为车载以太网-那是,而且事实是,我有一个踢来踢去从之前的PI-孔部署。

更合适的解决方案是通过PI的GPIO引脚模拟键盘。从理论上讲,这不会影响现有的USB设备,并且可以在任何型号的PI上使用,而不仅仅是PI Zero。因此,我开始研究如何通过PI的GPIO引脚“比特绑定”USB人机接口设备协议。

我很快就走进了死胡同。网上有很多关于在PI上比特敲击USB协议的讨论。人们的共识似乎是,Raspberry Pi的GPIO速度太慢,无法模拟USB,即使它可以输出足够快的比特来充当USB设备,但由于Linux操作系统的非实时特性,其实现将非常有缺陷(请阅读更多内容)。

但USB并不是向电脑发送按键的唯一方式--在USB标准在康柏眼中闪闪发光之前近十年,IBM就已经使用PS/2标准(不要与PS2混淆)将鼠标和键盘连接到PC上。使用PI对PS/2协议进行位绑定仍然不可行,但我们可以使用Arduino作为子板,ps2dev库可以处理PS/2串行协议的细节。

所以我就是这么做的。左边的Arduino Nano直接插入主板背面的PS/2组合端口(忽略未使用的5V线,红色)。最初,我计划剪掉PS/2电缆的一端,把它弄得漂亮些,但我附近的Goodwill没有任何PS/2垃圾,结果发现面包板线正好适合哦-所以-舒适地插入噪音孔中。所以事情就是这样了。

Arduino Nano闪现了一个短程序,使其充当一个哑巴管道,盲目地将字节从Arduino的USB串行端口传输到主板上的PS/2连接。这意味着应该为其发送键盘命令的所有逻辑都必须在PI端编写,这很好,因为这意味着我们永远不需要重新刷新Arduino来更新一些键盘逻辑。

请注意,目前,Pilo仅用于控制键盘输入,因为它面向服务器使用。无需额外硬件即可添加PS/2鼠标输出,只需2或3条线用于PS/2鼠标CLK、DATA和GND(除非使用组合端口)。Ps2dev库还包含用于鼠标控制的函数。

最初,我以为我必须把继电器连到主板的复位引脚上,这样皮洛才能控制计算机的电源。这是另一个类似项目DIY-IPMI使用的方法。然而,在研究键盘控制器时,我重新发现了PS/2标准中一个遗失已久的秘密:“ACPI键”。ACPI,即高级配置和电源接口,是一套适用于PC的电源管理标准。PS/2标准定义了可用于控制PC电源状态的电源、唤醒和休眠键扫描码-就像包装盒前面的电源按钮一样,短按电源键可请求操作系统关闭。但是,在我的主板上,长时间按电源似乎不能强制关闭电源。

几乎所有BIOS都支持使用ACPI键在关闭状态下打开系统电源。上面是选项在我的BIOS中的样子(在ACPI中,断电状态称为“S5”)。启用此选项后,发送电源扫描码将从关闭状态启动计算机。

因此,现在Arduino在Pilo有两项职责:定期向计算机发送按键,以及向计算机发送电源命令。这使我们不必为主板的复位引脚安装继电器。

我的服务器有一个带有HDMI输出的GPU,所以我决定使用USB HDMI采集卡来获取Pilo的视频提要。我在亚马逊上找到了一台,大约15美元。当连接到PI时,它就像一个普通的USB网络摄像头,可以在/dev/VideoX下买到。

在这个项目之前,我没有在网络上播放流媒体视频的经验。我决定使用uv4l(“Userspace Video4Linux”)的uv4l-server组件来设置HTTP视频服务器。Uv4l可以轻松设置简单的MJPEG流,这是最好的视频流-流的每一帧都是完整的JPEG图像,实时发送给您。正如您可以想象的那样,它不是带宽最小的,但很容易嵌入-所有Web浏览器都支持将其嵌入<;img>;tag:<;img src=";/Stream.mjpeg";/>;

我将uv4l-server配置为只侦听localhost,想法是我可以反向代理连接到视频流以提供安全性。

对于Pilo界面,我决定使用Web应用程序,而不是VNC或实际的IPMI协议。这在很大程度上是因为我有网络开发的背景,而且这款应用程序可以通过网络浏览器访问,这是每台电脑都安装的东西。以下是一段简短的视频,展示了完整的Pilo应用程序的运行情况:

你可以在这里找到Pilo的GitHub回购。它由两个主要组件组成:

前端-使用普通的HTML/CSS/JS来显示界面、翻译按键以及通过WebSockets与服务器通信。

服务器-HTTP服务器,用Node.js编写。使用HTTP基本身份验证验证请求,通过串行端口库与键盘控制器通信,并管理uv4l-server视频流的反向代理。

E2e文件夹中还有端到端测试,它们使用Cypress在真实的Web浏览器中测试应用程序。这在每次通过GitHub操作工作流提交CI时针对Firefox和Chrome运行。

如果您对贡献感兴趣,该自述文件包含有关构建和测试项目的信息。构建的包也会发布到NPM以供生产使用。

在构建Pilo时,我的目标之一是使其足够小,可以放入我的服务器机箱中。看看这些照片,看看它是如何融入其中的:

完整的封装仅比PI本身稍大,约为88 mm x 60 mm x 20 mm,这意味着Pilo可以方便地放入标准的3.5“硬盘托架中。

Raspberry PI 3B+(MicroCenter售价25美元,其他地方售价35美元)或其他微型Linux计算机-即使PI Zero也可以使用,但您需要使用WiFi,并且您需要一个USB集线器来存储Arduino系列,或者通过GPIO设置Arduino系列。

Arduino Nano(亚马逊的售价为16.99美元,每个售价5-3.40美元)任何其他5V逻辑级的Arduino都可以使用。需要为5V或将CLK+数据输出从3V3转换为5V,因为PS/2串行连接需要5V。

供应品:电线、烙铁(如果需要焊接)、微型SD卡和PI…的微型usb电源。

如果你以最便宜的价格买所有东西,大约60美元,如果你足够幸运地住在微中心附近,50美元。

在开始之前,请确保您的设备已经准备好:在PI的microSD卡上安装基于Debian的操作系统,如Raspbian或DietPI。

根据这张漂亮的接线图连接所有设备:┌──┐│以太网├──┤扩展。以太网│RasPI 3B+├──┤扩展中的USBPower。5V电源│(或其他)usb端口├─┐│usb端口├─┐│└──┘││││┌──┐┌─。─┐│└─┤USB插头HDMI采集卡││服务器HDMI输出├─┼─┤HDMI输入││PS/2键盘端口├───┐│└──┘└──。─┘│┌──┐│└─┤USB端口││┌──┤D2(数据)Arduino Nano│└─┤──┤D3(时钟)(或其他)│└──┤地面(地面)│└─。─┘

将D2(数据)、D3(CLK)和GND从Arduino Nano直接连接到主板上PS/2键盘端口的相应针脚。有关参考引脚的信息,请参考互联网。您可以通过清理备用的PS/2辫尾并剥离末端来装扮它,但是面包板电线也可以舒适地插入DIN端口。

在将任何东西连接到PS/2端口或从PS/2端口断开任何东西之前,请关闭服务器。PS/2端口在设计时没有考虑到热插拔。您有损坏组件的风险,而且您的操作系统很可能检测不到热插拔的PS/2设备,所以不必费心了。

请勿将+5V针脚从PS/2端口连接到Arduino上的VIN-这不是一个好主意,原因有很多。

为USB HDMI采集卡设置MJPEG流服务器。按照uv4l网站上的说明安装uv4l的APT源代码。Debian Buster用户请注意:目前还没有适用于Buster的uv4l apt repo,但扩展repo似乎在buster上运行良好。

通过运行lsusb检索您的USB HDMI捕捉卡的ID。它应该是类似于1a2b:3c4d的十六进制字符串。

启动在127.0.0.1:9000上侦听的uv4l服务器,将您的设备ID替换为下面的1a2b:3c4d:您应该能够在http://127.0.0.1:9000/stream/video.mjpeg.的PI上本地访问USB HDMI捕捉卡的MJPEG流。您将无法通过网络访问它,因为它通过--bind-host-address绑定到localhost。

将(4)中的命令设置为在每次引导时运行,例如,将其添加到/etc/rc.local。

现在可以通过运行环境变量中设置了AUTH_SHHA的命令在端口3000上启动PILO:现在应该可以使用之前创建的用户名和密码在http://<;your-pi-IP>;:3000/,访问PILO。