PVE 通过群晖连接UPS实现停电关机(基于NUT)

我的PVE(Proxmox VE)宿主机下的爱快+LEDE+黑群晖已经稳定运行一年多了,最近因为打雷突然停电,开始担心硬盘数据安全问题,于是开始研究如何通过UPS实现群晖、PVE等设备停电自动关机。

经查相关资料,发现APC(型号:Back-UPS-650)的UPS有停电通讯功能,且与群晖完美支持,并可通过群晖的网络UPS服务器实现PVE等设备联动断电关机。

群晖实现断电关机的方法:

1、购买一台APC的 BK650 UPS电源,此电源带USB通讯口,插到PVE主机上,并给黑群晖虚拟机添加USB设备(记得关闭、重启群晖虚拟机)
img

2、登录群晖管理页面,打开 控制面板->硬件和电源->不断电系统,可以看到UPS电源已被正确识别。
img

这里可以自行设置断电后群晖进入安全模式的时间。

在这里插入图片描述

PVE连接群晖UPS服务器实现自动关机的方法:

1、进入群晖控制面板->硬件和电源->不断电系统,启用网络UPS服务器,并点击允许的DiskStation设备,填入你的PVE管理IP(我的是:192.168.100.4)。

img

2、打开PVE的Shell界面,依次输入以下命令操作
①下载NUT套件

apt install nut -y

②编辑NUT配置文件

vim /etc/nut/nut.conf

(如未安装vim工具可以用 vi 命令,VIM工具比较方便修改,安装方法自行百度)

移动光标找到MODE参数项

将“MODE=”后面修改成如下参数(按键盘上的“i”进入编辑模式)

MODE=netclient

输入“:wq”保存退出

vim /etc/nut/upsmon.conf

找到 MONITOR 在下方增加一行

MONITOR ups@nas的ip 1 upsmon pass slave

③启动nut-client服务,并设置自动启动

systemctl start nut-client && systemctl enable nut-client

④测试是否成功连接UPS服务器

upsc ups@NAS IP

如显示如下信息则表示配置成功(不同设备信息不同)

Init SSL without certificate database
battery.charge: 100
battery.charge.low: 10
battery.charge.warning: 50
battery.date: not set
battery.mfr.date: 2019/03/20
battery.runtime: 2272
battery.runtime.low: 120
battery.type: PbAc
battery.voltage: 13.6
battery.voltage.nominal: 12.0
device.mfr: APC
device.model: Back-UPS 650
device.serial: 3B1912X62195
device.type: ups
driver.name: usbhid-ups
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 5
driver.parameter.port: auto
driver.version: DSM6-2-23656-180331
driver.version.data: APC HID 0.95
driver.version.internal: 0.38
input.sensitivity: low
input.transfer.high: 266
input.transfer.low: 165
input.voltage: 234.0
input.voltage.nominal: 220
ups.beeper.status: enabled
ups.delay.shutdown: 20
ups.firmware: 822.A3.I
ups.firmware.aux: A3
ups.load: 14
ups.mfr: APC
ups.mfr.date: 2019/03/20
ups.model: Back-UPS 650
ups.productid: 0002
ups.serial: 3B1912X62195
ups.status: OL
ups.timer.reboot: 0
ups.timer.shutdown: -1
ups.vendorid: 051d

Init SSL without certificate database
battery.charge: 100
battery.charge.low: 10
battery.charge.warning: 50
battery.date: not set
battery.mfr.date: 2017/11/11
battery.runtime: 1650
battery.runtime.low: 120
battery.type: PbAc
battery.voltage: 13.5
battery.voltage.nominal: 12.0
device.mfr: APC
device.model: Back-UPS 650
device.serial: 3B1745X17495
device.type: ups
driver.name: usbhid-ups
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 5
driver.parameter.port: auto
driver.version: DSM6-2-25510-201118
driver.version.data: APC HID 0.95
driver.version.internal: 0.38
input.sensitivity: low
input.transfer.high: 266
input.transfer.low: 165
input.transfer.reason: input voltage out of range
input.voltage: 244.0
input.voltage.nominal: 220
ups.beeper.status: enabled
ups.delay.shutdown: 20
ups.firmware: 822.A3.I
ups.firmware.aux: A3
ups.load: 26
ups.mfr: APC
ups.mfr.date: 2017/11/11
ups.model: Back-UPS 650
ups.productid: 0002
ups.serial: 3B1745X17495
ups.status: OL
ups.timer.reboot: 0
ups.timer.shutdown: -1
ups.vendorid: 051d

常用资源:

配置说明:

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
Start Network UPS Tools service:Yes #启动NUT服务,选择Yes

Enable Manual Config Only:No #只允许手动配置,选择No

UPS Mode:Netserver #UPS工作模式,选择Netserver为服务器模式

UPS IP Addresss:127.0.0.1 #UPS的IP地址,这个在Netserver模式下无法更改

UPS Name:ups #UPS主机名,必须是ups,否则群晖无法连接

UPS Monitor Username:monuser #UPS主机用户名

UPS Monitor Password:secret #UPS主机密码

UPS Slave Username:monuser #从机连接nut时所用的帐户名,必须是monuser

UPS Slave Password:secret #从机联机密码,必须是secret,这里特别注意,某些浏览器或插件会自动生成密码,请一定要手工输入secret六个英文半角字符。

UPS Driver:Usbhid-ups #UPS驱动,选择Usbhid-ups,兼容APC绝大多数产品

UPS Port:auto #端口,选择auto

Shutdown Mode:Time on Battery #关机模式,选择Time on Battery意味着在电池供电N分钟后会发送关机命令,具体时间在后面的选项设定

Battery Runtime Left:Battery Runtime #因为一些兼容性问题,电池剩余时间可能会显示错误的值,此时可以更改这个选项,确保显示正确

Time on battery before shutdown (minutes):8 #接上面的选项,设置UPS电池供电多少分钟后发送关机命令

Turn off UPS after shutdown:No #主机关机后将UPS也关机,打开这个选项以省电,建议选No,除非你的UPS有自动开机功能,否则来电后UPS不会工作,导致NAS也无法开机。

群晖UPS-NUT目录

1
/usr/syno/etc/ups/

upsmon.conf文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
MONITOR ups@IP地址 1 monuser secret slave

ups:是ups连接的名字。群晖的UPS服务器名字就是ups。

IP地址:就是UPS服务器的IP地址(群晖的IP地址)。

1:表示给系统供电的UPS数量。

monuser:群晖UPS连接的用户名
secret:群晖UPS连接的密码。

slave:表示当前设备作为客户端。

NOTIFYCMD 的路径也要改成软件的安装地址。修改完后,点击Apply。看Status中是否有Running as Application。注意,需要在群晖UPS服务器中设置客户端设备的IP,允许其连接。

/usr/syno/bin/synoups

我的群晖升级到了DSM7,断电后进入“安全模式”,硬盘挂起并不会自动关机。此时,需要先在“群晖控制面板”—“终端机和SNMP”—“启用SSH功能”上打勾,启用SSH功能,然后在Windows电脑上,使用SSH软件以root用户登录群晖,修改 /usr/syno/bin/synoups 文件,找到UPSSafeMode() ,在最后面加上一行poweroff。

群晖与PC共享UPS服务的解决方案

在这里插入图片描述

WinNUT-Client

群晖与PC共享UPS服务的解决方案

我的配置:

nut.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# The values of MODE can be:
# - none: NUT is not configured, or use the Integrated Power Management, or use
# some external system to startup NUT components. So nothing is to be started.
# - standalone: This mode address a local only configuration, with 1 UPS
# protecting the local system. This implies to start the 3 NUT layers (driver,
# upsd and upsmon) and the matching configuration files. This mode can also
# address UPS redundancy.
# - netserver: same as for the standalone configuration, but also need
# some more network access controls (firewall, tcp-wrappers) and possibly a
# specific LISTEN directive in upsd.conf.
# Since this MODE is opened to the network, a special care should be applied
# to security concerns.
# - netclient: this mode only requires upsmon.
#
# IMPORTANT NOTE:
# This file is intended to be sourced by shell scripts.
# You MUST NOT use spaces around the equal sign!

MODE=netclient

ups.conf

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# Network UPS Tools: example ups.conf
#
# --- SECURITY NOTE ---
#
# If you use snmp-ups and set a community string in here, you
# will have to secure this file to keep other users from obtaining
# that string. It needs to be readable by upsdrvctl and any drivers,
# and by upsd.
#
# ---
#
# This is where you configure all the UPSes that this system will be
# monitoring directly. These are usually attached to serial ports, but
# USB devices and SNMP devices are also supported.
#
# This file is used by upsdrvctl to start and stop your driver(s), and
# is also used by upsd to determine which drivers to monitor. The
# drivers themselves also read this file for configuration directives.
#
# The general form is:
#
# [upsname]
# driver = <drivername>
# port = <portname>
# < any other directives here >
#
# The section header ([upsname]) can be just about anything as long as
# it is a single word inside brackets. upsd uses this to uniquely
# identify a UPS on this system.
#
# If you have a UPS called snoopy, your section header would be "[snoopy]".
# On a system called "doghouse", the line in your upsmon.conf to monitor
# it would look something like this:
#
# MONITOR snoopy@doghouse 1 upsmonuser mypassword master
#
# It might look like this if monitoring in slave mode:
#
# MONITOR snoopy@doghouse 1 upsmonuser mypassword slave
#
# Configuration directives
# ------------------------
#
# These directives are used by upsdrvctl only and should be specified outside
# of a driver definition:
#
# maxretry: Optional. Specify the number of attempts to start the driver(s),
# in case of failure, before giving up. A delay of 'retrydelay' is
# inserted between each attempt. Caution should be taken when using
# this option, since it can impact the time taken by your system to
# start.
#
# The default is 1 attempt.
#
# retrydelay: Optional. Specify the delay between each restart attempt of the
# driver(s), as specified by 'maxretry'. Caution should be taken
# when using this option, since it can impact the time taken by your
# system to start.
#
# The default is 5 seconds.
#
# These directives are common to all drivers that support ups.conf:
#
# driver: REQUIRED. Specify the program to run to talk to this UPS.
# apcsmart, bestups, and sec are some examples.
#
# port: REQUIRED. The serial port where your UPS is connected.
# /dev/ttyS0 is usually the first port on Linux boxes, for example.
#
# sdorder: optional. When you have multiple UPSes on your system, you
# usually need to turn them off in a certain order. upsdrvctl
# shuts down all the 0s, then the 1s, 2s, and so on. To exclude
# a UPS from the shutdown sequence, set this to -1.
#
# The default value for this parameter is 0.
#
# nolock: optional, and not recommended for use in this file.
#
# If you put nolock in here, the driver will not lock the
# serial port every time it starts. This may allow other
# processes to seize the port if you start more than one by
# mistake.
#
# This is only intended to be used on systems where locking
# absolutely must be disabled for the software to work.
#
# maxstartdelay: optional. This can be set as a global variable
# above your first UPS definition and it can also be
# set in a UPS section. This value controls how long
# upsdrvctl will wait for the driver to finish starting.
# This keeps your system from getting stuck due to a
# broken driver or UPS.
#
# The default is 45 seconds.
#
# synchronous: optional. The driver work by default in asynchronous
# mode (i.e *synchronous=no*). This means that all data
# are pushed by the driver on the communication socket to
# upsd (Unix socket on Unix, Named pipe on Windows) without
# waiting for these data to be actually consumed. With
# some HW, such as ePDUs, that can produce a lot of data,
# asynchronous mode may cause some congestion, resulting in
# the socket to be full, and the driver to appear as not
# connected. By enabling the 'synchronous' flag
# (value = 'yes'), the driver will wait for data to be
# consumed by upsd, prior to publishing more. This can be
# enabled either globally or per driver.
#
# The default is 'no' (i.e. asynchronous mode) for backward
# compatibility of the driver behavior.
#
# Anything else is passed through to the hardware-specific part of
# the driver.
#
# Examples
# --------
#
# A simple example for a UPS called "powerpal" that uses the blazer_ser
# driver on /dev/ttyS0 is:
#
# [powerpal]
# driver = blazer_ser
# port = /dev/ttyS0
# desc = "Web server"
#
# If your UPS driver requires additional settings, you can specify them
# here. For example, if it supports a setting of "1234" for the
# variable "cable", it would look like this:
#
# [myups]
# driver = mydriver
# port = /dev/ttyS1
# cable = 1234
# desc = "Something descriptive"
#
# To find out if your driver supports any extra settings, start it with
# the -h option and/or read the driver's documentation.

# Set maxretry to 3 by default, this should mitigate race with slow devices:
# pollinterval = 1
maxretry = 3

# My Configration 我的配置

# [bk650]
# driver = usbhid-ups
# port = auto
# desc = "APC BK650 UPS"
# vendorid = 051d
# productid = 0002
# serial = 3B1745X17495

upsd.conf

1
LISTEN 0.0.0.0 3493

upsd.users

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
# --------------------------------------------------------------------------
#
# Example:
#
# [admin]
# password = mypass
# actions = SET
# instcmds = ALL
#

#
# --- Configuring for upsmon
#
# To add a user for your upsmon, use this example:
#
# [upsmon]
# password = pass
# upsmon master
# or
# upsmon slave
#
# The matching MONITOR line in your upsmon.conf would look like this:
#
# MONITOR myups@localhost 1 upsmon pass master (or slave)

# 管理员可set更改ups内变量参数,master可设置FSD关机标签,slave收到通知后关机
[admin]
actions = SET FSD
instcmds = ALL
password = pass
upsmon master

# 别的电脑连接使用此用户,从机帐号信息
[upsmon]
password = pass
upsmon slave

在这里插入图片描述

upsmon.conf

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
RUN_AS_USER root

MONITOR ups@192.168.199.180 1 upsmon pass slave

MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h"
NOTIFYCMD /usr/sbin/upssched
POLLFREQ 2
POLLFREQALERT 1
HOSTSYNC 15
DEADTIME 15
POWERDOWNFLAG /etc/killpower

NOTIFYMSG ONLINE "UPS %s on line power"
NOTIFYMSG ONBATT "UPS %s on battery"
NOTIFYMSG LOWBATT "UPS %s battery is low"
NOTIFYMSG FSD "UPS %s: forced shutdown in progress"
NOTIFYMSG COMMOK "Communications with UPS %s established"
NOTIFYMSG COMMBAD "Communications with UPS %s lost!"
NOTIFYMSG SHUTDOWN "Auto logout and shutdown proceeding"
NOTIFYMSG REPLBATT "UPS %s battery needs to be replaced"
NOTIFYMSG NOCOMM "UPS %s is unavailable"
NOTIFYMSG NOPARENT "UPSMon parent process died - shutdown impossible"

NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT SYSLOG+WALL
NOTIFYFLAG FSD SYSLOG+WALL+EXEC
NOTIFYFLAG COMMOK SYSLOG+WALL+EXEC
NOTIFYFLAG COMMBAD SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT SYSLOG+WALL
NOTIFYFLAG NOCOMM SYSLOG+WALL+EXEC
NOTIFYFLAG NOPARENT SYSLOG+WALL

RBWARNTIME 43200

NOCOMMWARNTIME 600

FINALDELAY 5

upssched.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
CMDSCRIPT /etc/nut/upssched-cmd
PIPEFN /etc/nut/upssched/upssched.pipe
LOCKFN /etc/nut/upssched/upssched.lock

AT ONBATT * START-TIMER onbatt 60
AT ONLINE * CANCEL-TIMER onbatt online
AT ONBATT * START-TIMER earlyshutdown 60
AT LOWBATT * EXECUTE onbatt
AT COMMBAD * START-TIMER commbad 600
AT COMMOK * CANCEL-TIMER commbad commok
AT NOCOMM * EXECUTE commbad
AT SHUTDOWN * EXECUTE powerdown
AT SHUTDOWN * EXECUTE powerdown

upssched-cmd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/sh
case $1 in
onbatt)
logger -t upssched-cmd "UPS running on battery"
;;
earlyshutdown)
logger -t upssched-cmd "UPS on battery too long, early shutdown"
/usr/sbin/upsmon -c fsd
;;
shutdowncritical)
logger -t upssched-cmd "UPS on battery critical, forced shutdown"
/usr/sbin/upsmon -c fsd
;;
upsgone)
logger -t upssched-cmd "UPS has been gone too long, can't reach"
;;
*)
logger -t upssched-cmd "Unrecognized command: $1"
;;
esac

upsset.conf

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
# Network UPS Tools - upsset.conf sample file
#
# This file is provided to ensure that you do not expose your upsd server
# to the world upon installing the CGI programs. Specifically, it keeps
# the upsset.cgi program from running until you have assured it that you
# have secured your web server's CGI directory.
#
# By default, your web server will probably let anyone access upsset.cgi
# once it is installed. This means that anyone could attempt to crack
# upsd logins since they would appear to be coming from your web server,
# rather than the outside world, slipping through any ACL/ACCESS definitions.
#
# For this reason, you *MUST* first secure your CGI programs before
# enabling upsset in this configuration file. If you can't do this in
# your web server, then you should *not* run this program.
#
# For Apache, the .htaccess file can be used in the directory with the
# programs. You'll need something like this:
#
# <Files upsset.cgi>
# deny from all
# allow from your.network.addresses
# </Files>
#
# You will probably have to set "AllowOverride Limit" for this directory in
# your server-level configuration file as well.
#
# If this doesn't make sense, then stop reading and leave this program alone.
#
# Assuming you have all this done (and it works), then you may uncomment
# the line below and start using upsset.cgi through your web browser.
#

###
### I_HAVE_SECURED_MY_CGI_DIRECTORY
I_HAVE_SECURED_MY_CGI_DIRECTORY
###

host.conf

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
# Network UPS Tools: example hosts.conf
#
# This file is used to control the CGI programs. If you have not
# installed them, you may safely ignore or delete this file.
#
# -----------------------------------------------------------------------
#
# upsstats will use the list of MONITOR entries when displaying the
# default template (upsstats.html). The "FOREACHUPS" directive in the
# template will use this file to find systems running upsd.
#
# upsstats and upsimage also use this file to determine if a host may be
# monitored. This keeps evil people from using your system to annoy
# others with unintended queries.
#
# upsset presents a list of systems that may be viewed and controlled
# using this file.
#
# -----------------------------------------------------------------------
#
# Usage: list systems running upsd that you want to monitor
#
# MONITOR <system> "<host description>"
#
# Examples:

MONITOR ups@192.168.199.180 "APC-BK650 UPS"
# MONITOR su2200@10.64.1.1 "Finance department"
# MONITOR matrix@shs-server.example.edu "Sierra High School data room #1"