How to Shutdown Your Servers In Case of Power Failure — UPS, NUT & Co.
At our school there are always power outages. Sometimes they last only a few seconds, sometimes several hours. To ensure that our IT infrastructure does not suffer from this, we have installed a UPS for our servers and network devices. These help to bridge short power outages (up to 1 hour) or fluctuations in current. For any lengthy outages, we automatically shut down our servers when the UPS reaches critical battery level. For this we use NUT (Network UPS Tools).
Our setup consists of the following components:
Set up UPS in NUT on the Raspberry Pi
For the Raspberry Pi we use the standard Raspian Stretch Lite Image. Note that SSH has not been enabled by default since 2016. The different ways to reactivate SSH are documented here. After reactivating SSH, you can now log on to the Raspberry Pi (the IP of the Raspberry Pi can be found out from a computer in the same network with avahi-browse -ar or you can connect a monitor and keyboard). We will need the IP later, so it makes sense to give the Raspberry Pi a static IP.
Next we install the NUT server with
sudo apt-get install nut-client nut-server usbutils
If the UPS is connected via USB (as in our case), you can check with lsusb if it was detected. This is what the output on the Raspberry Pi looks like:
$ lsusb Bus 001 Device 004: ID 10af: 0000 Liebert Corp. UPS Bus 001 Device 003: ID 0424: ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. Bus 001 Device 001: ID 1d6b: 0002 Linux Foundation 2.0 root hub
In the first line you can see that our Liebert UPS has been recognized.
Now we have to configure our UPS in the file /etc/nut/ups.conf. For our UPS, the entry looks like this:
[gxt4] driver = usbhid-ups port = car productid = 0000 desc = “Emerson Liebert GXT 4”
On the Network UPS Tools website, you will find a list of all supported UPS and which driver works best.
Next, we want to test whether the settings are correct, the UPS Daemon can communicate with the UPS. For this purpose we start upsd with
sudo upsdrvctl start
A successful output should look something like this:
Network UPS Tools — UPS driver controller 2.7.2 Network UPS Tools — Generic HID driver 0.38 (2.7.2) USB communication driver 0.32 Using subdriver: Belkin HID 0.16
NUT contains a small program to test the communication with UPS. It is called upsc and outputs all readable UPS parameters.
$ upsc gxt4 Init SSL without certificate database battery.charge: 100 battery.charge. low: 20 battery.charge. warning: 0 battery.type: PbAc battery.voltage: 0.0 battery.voltage. nominal: 0.0 device.mfr: Emerson Network Power device.model: Liebert GXT4 device.serial: 1607000060AFC23 device.type: ups driver.name: usbhid-ups driver.parameter. pollfreq: 30 driver.parameter. pollinterval: 2 driver.parameter. port: auto driver.parameter. productid: 0000 driver.version: 2.7.2 driver.version. data: Belkin HID 0.16 driver.version. internal: 0.38 ups.mfr: Emerson Network Power ups.model: Liebert GXT4 ups.productid: 0000 ups.serial: 1607000060AFC23 ups.status: OL CHRG ups.vendorid: 10af
Now our UPS is successfully installed. Next we set up the NUT server, the UPS monitor upsmon and two more users for the master and the slaves.
Configuring the NUT Server
In /etc/nut/nut/nut.conf we specify that the Raspberry Pi is our master:
The UPS Daemon (upsd) is running on the NUT server. It is responsible for the (physical) connection to UPS. The individual clients/slaves use the upsmon to access the status of the UPS. In this way, multiple clients can always know the status of the UPS and, if necessary, initiate shutdown when UPS delivers the status “On Low Battery”.
In order for our NUT server to be accessible from the net, the following lines have to be added to /etc/nut/upsd.conf (adjust IP please):
LISTEN 127.0.0.0.1 LISTEN 192.168.1.2 #IP of the Raspberry Pis
Next, we define the users that a client can use to log on to the master (in the file /etc/nut/upsd.user):
[upsmaster] password = secret upsmon master
[upremote] password = secret upsmon slave
In order for upsmon to monitor the UPS, we now need to add a final entry in /etc/nut/upsmon.conf:
MONITOR gxt4@localhost 1 upsmaster secret master
In order to know if all services are running correctly, you can check the status of the server and the local clients on the Raspberry Pi (because it should be shut down when there is no more power) with the following commands:
$ sudo systemctl status nut-server $ sudo systemctl status user-client
Now our master is set up and the clients or slaves can be configured.
Set up clients/slaves (e. g. server, other computers)
First, the necessary packages must be installed on a client:
sudo apt-get install nut-client
This time we only have to edit two files. In /etc/nut/nut/nut.conf we set the mode:
Then we need to tell upsmon which UPS to monitor (in /etc/nut/upsmon.conf):
MONITOR [email protected] upsremote secret slave
The IP and password have to be adjusted. Please also note the slave at the end! Finally, restart the corresponding service and check that everything is running:
$ sudo systemctl restart user-client $ sudo systemctl status user-client
Congratulations! Now everything should be set up, but how can you test that it really works?
The following command triggers the shutdown signal (as it would be in the event of a power failure):
$ sudo upsmon -c fsd
NUT is another great open source project that allows very flexible customizations. This PDF contains many more (complex) application scenarios. While I’m writing this article, we’re out of power again and all our servers have been shut down 🙂