本文完整阅读约需 20 分钟,如时间较长请考虑收藏后慢慢阅读~

记得小时候上微机课,老师总是告诉我们不要直接拔掉电脑电源,理由是磁头会与磁盘碰撞导致硬件损坏。随着技术的改进,现代硬盘已经不太可能因为断电导致硬件损坏,但由于现代文件系统的性能优化(异步写入、延迟写入、多级缓存等),断电依旧会导致较大的数据损失风险。本文将以笔者在家庭中搭建多设备共享UPS环境的经历,介绍NUT在Debian下的安装、配置,以及Windows和QNAP设备连接网络UPS的配置。

0x01 前言

由于笔者租的房子每个月都会出现一两次停电,为了避免停电造成的数据损失和硬件损坏(电涌和欠压),笔者最近购入了山特的 TG-BOX 850 UPS,评测参见互联网上其他分享,本文不再赘述:

笔者需要使用UPS保护的设备总功率为150W,实测该UPS断电情况下可以续航25分钟,足够在此时间内关机保护数据(甚至还可以跑完一次Windows更新)。

顺便吐槽下市面上的UPS,大部分UPS都只标示最大功率(多少VA),但却不标示电瓶容量和转化率,以及可输出的瓦时数,根据实测,该UPS的电瓶参数为12V/9Ah,实际可以输出的瓦数大约为60Wh(电量低于10%即强制关机,因此转化率应该高于60/12*9=45%)。

这款UPS在各方面都令人满意,但和所有的家用UPS一样,它只支持USB连接(市面上部分其他低端型号甚至只支持串口),这就意味着在默认情况下,只能让一台电脑自动关机。

笔者有一台台式机和一台NAS(以及后续会加入UPS的其他设备),而UPS距离NAS距离太远,不方便直接连接NAS,因此需要利用一台小巧的设备连接UPS,再通过手动配置的方式实现UPS状态的共享。

0x02 设备列表

  • UPS:山特 TG-BOX 850
  • Master:
    • 192.168.31.2 – NanoPi NEO3 running Debian 10 (通过USB直连UPS)
  • Slave:
    • 192.168.31.3 – Windows Workstation
    • 192.168.31.5 – QNAP TS-551 5-Bay NAS

0x03 所需规则

  • 电源中断后
    • Master发送邮件,但不自动关机(Master没有文件读写,不担心掉电丢数据)
    • Slave定时监测状态,监测到中断后,自动关机
      • Windows电脑延迟两分钟关机(避免有自动更新,导致更新过程中掉电)
      • NAS延迟两分钟进入自动保护模式(关闭所有服务,卸载磁盘,掉电不丢数据,上电后更快恢复服务)
  • 电源恢复
    • Master上电自动开机
    • Master检测到电源恢复,发送WOL请求给Windows电脑和NAS

0x04 Master配置

安装软件

$ sudo apt install nut lsusb
...
$ lsusb
Bus 005 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 004 Device 002: ID 0463:ffff MGE UPS Systems UPS
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

nut组件一览

  • nut-driver: 负责和UPS通信
  • nut-server: 负责对外提供服务
  • nut-client: 负责监视UPS状态,并进行指定的操作

配置nut-driver

$ sudo vim /etc/nut/ups.conf
maxretry = 3

# 注意:QNAP的NAS只识别这个名称
[qnapups]
  driver = usbhid-ups
  port = auto
  desc = "My UPS (Compatible with QNAP NAS)"
$ sudo systemctl enable nut-driver
$ sudo systemctl start nut-driver

配置nut-server

$ sudo vim /etc/nut/upsd.users
# 注意:QNAP的NAS只识别这个用户和密码
[admin]
  password = 123456
  upsmon master
$ sudo vim /etc/nut/nut.conf
MODE=netserver
$ sudo systemctl enable nut-server
$ sudo systemctl start nut-server

监测driver和server是否工作正常

$ /bin/upsc [email protected]

配置nut-client

$ sudo vim /etc/nut/upsmon.conf
MONITOR [email protected] 1 admin 123456 master
$ sudo systemctl enable nut-client
$ sudo systemctl start nut-client

此时可以关闭UPS,会发现nut向所有登录用户发送电池供电的通知。

默认配置下,等UPS出现低电量警报后,设备会自动关机,如果在低电量之前电源恢复,则nut会再发送一条电源恢复的通知。

配置高级电源策略(upssched)

$ sudo vim /etc/nut/upsmon.conf
NOTIFYCMD /sbin/upssched
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC

# 由于笔者不需要Master自动关机,因此修改关机命令为/bin/false
# 读者根据自己的需求选择是否修改
SHUTDOWNCMD "/bin/false"
$ sudo vim /etc/nut/upssched.conf
CMDSCRIPT /usr/local/bin/upssched
PIPEFN /var/run/nut/upssched.pipe
LOCKFN /var/run/nut/upssched.lock

# 由于笔者不需要Master自动关机,因此注释该部分
# 读者根据自己的需求选择是否修改
# AT ONBATT * START-TIMER power-off 300
# AT ONLINE * CANCEL-TIMER power-off
AT ONLINE * EXECUTE power-on
$ sudo chown -R nut:nut /var/run/nut/
$ sudo touch /usr/local/bin/upssched
$ sudo chmod +x /usr/local/bin/upssched
$ sudo vim /usr/local/bin/upssched
#!/bin/bash

case $1 in
    power-off)
    echo "The UPS has been on battery for 300 seconds and foreman is about to shut down." \
    | mail -s "NUT Master is about to shut down" [email protected]
    /sbin/upsmon -c fsd
  power-on)
    echo "The UPS is online now and the server has started." \
    | mail -s "NUT Master has started" [email protected]
    ;;
  *)
    logger -t upssched "Unrecognized command: $1"
    ;;
esac

演习

  1. 在自己的电脑上 ping Master
  2. 断开UPS电源
  3. 查看Master状态
    1. sudo systemctl status nut-client
    2. 查看控制台是否弹出通知
  4. 马上恢复UPS电源
  5. 查看控制台是否弹出电源恢复通知
  6. 断开UPS电源
  7. 等待UPS电量耗尽(对于此款UPS,两秒响一次即说明电量耗尽)
  8. 查看控制台是否弹出电量耗尽通知
  9. 检查Master是否断开SSH连接
  10. 检查 ping Master是否超时

配置权限

如果出现各种奇怪的报错,可以先检测权限,然后重启所有服务

$ sudo chown -R root:nut /etc/nut/
$ sudo chown -R nut:nut /var/run/nut/
$ sudo chmod -R 0770 /etc/nut/
$ sudo chmod 0640 /etc/nut/upsd.conf /etc/nut/upsd.users
$ sudo chmod -R 0770 /var/run/nut/

$ sudo systemctl restart nut-driver
$ sudo systemctl restart nut-server
$ sudo systemctl restart nut-client

0x05 Slave连接Master

Master监听端口

$ sudo vim /etc/nut/upsd.conf
LISTEN 0.0.0.0 3493
$ sudo systemctl restart nut-server

Windows电脑

安装WinNUT-Client

Releases · gawindx/WinNUT-Client

配置WinNUT-Client

演习

QNAP NAS

演习

0x06 配置上电后的WOL

Windows

在BIOS中查找Wake On Lan相关设置,不同机型情况不同,不再赘述

NAS

Master

$ sudo apt install wakeonlan
$ sudo vim /usr/local/bin/upssched
  power-on)
    ...
    # QNAP NAS WOL 
    wakeonlan [NAS的MAC地址]
    # Windows Workstation WOL
    wakeonlan [Windows电脑的MAC地址]

EOF

0x07 参考文章