UPS & NUT

Uninterruptible Power Supplies & Network UPS Tools #

Clever name, right?

Uninterruptible Power Supplies #

During the past few months, I have been spending [quite a bit of money] on upgrades to my homelab. Amongst the last of these upgrades (hopefully the last for the foreseeable future as I am now unemployed) was a UPS, or uninterruptible power supply.

Now I won’t go into the details of what UPS one should get, as that’s highly dependent on your specific power needs, wanted features, et cetera. However, I highly recommend getting one that has “smart” features, or at least a way to communicate with a computer to initiate a safe shutdown. I also recommend trying to get one used, as it is typically drastically cheaper than buying a brand new model and a good UPS has user replacable batteries. For my network setup, I was able to get an Eaton 5SC750 used off eBay for ~$120.

A decent UPS in combination with NUT, or network UPS tools forms the basis for my network’s uninterruptible power delivery and shutdown scripts, and the configuration of which we will discuss in the following.

Network UPS Tools #

The following assumes you have root access.

Many commands will not work without elevated privileges (i.e. without using sudo)

Installation #

As usual, the following assumes a basic Debian installation.

Its rather funny acronym makes this rather easy to install:

apt install nut

If you are trying to set up NUT in a server-client setting, like I have, you can opt to install nut-client instead on client devices, as detailed in the next section.

Configuration #

Installing the base NUT package installs both nut-server and nut-client.

If you prefer to save the few megabytes that installing the entire nut package takes, you can opt to install nut on the server that is physically connected (via USB or serial) to the server, and install nut-client on the client devices.

Although I know it is probably very obvious, I feel like I should still make this clear:
ALL DEVICES with NUT installed should be receiving power from the UPS.

It doesn’t make sense to install NUT and run it on your PC if it is just going to turn off the second you lose power because you didn’t connect it to your UPS. You can’t run scripts without power.

NUT has four basic modes that starts specific parts of NUT. It must be changed from the default ’none’ in /etc/nut/nut.conf

The configuration file does a good job at detailing which mode does what:

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.

Server/Standalone #

To use NUT as a server (sending UPS information to clients), set mode to netserver in /etc/nut/nut.conf:

MODE=netserver

If you wish to use NUT to protect only the system it is connected to, you can set mode to standalone instead.

Once your UPS is connected, you should be able to find it using lsusb:

lsusb | grep UPS
Bus 001 Device 006: ID 0463:ffff MGE UPS Systems UPS

Now define your UPS to NUT by adding a section to /etc/nut/ups.conf:

[eaton]
driver = usbhid-ups
port = auto
vendorid = 0463
desc = "Eaton UPS"

You should now be able to start the driver:

upsdrvctl start
Network UPS Tools - UPS driver controller 2.7.3
Network UPS Tools - Generic HID driver 0.40 (2.7.2)
USB communication driver 0.33
Using subdriver: MGE HID 1.40

Now that we have started the driver, we should configure upsd which communicates with the driver. Add LISTEN directives to /etc/nut/upsd.conf:

LISTEN 127.0.0.1
LISTEN ::1

If you are using this server to communicate with other devices (mode=netserver), add another directive matching your local IP:

LISTEN 192.168.0.101

Now we must define user accounts to connect to upsd. Edit /etc/nut/upsd.users:

[admin]
password = securePassword2022
actions = SET
instcmds = ALL
upsmon master

[user]
password = 2022differentPassword
upsmon slave

admin and user are usernames. You can (and should) change these settings.

You should now be able to start the daemon and get the status of the UPS:

upsd
upsc eaton@localhost
...
battery.charge: 99
battery.charge.low: 20
...

Now all that is left is to configure the daemon monitor. We will detail that in the next section, because both the server and the client use the same process.

If you are using standalone, keep reading (you are basically running a local server for one machine, anyway, if you haven’t already realized).

Client #

If you are monitoring a daemon on the same device (already set mode to netserver or standalone), ignore the following.

Devices that will only be monitoring a server can use the netclient mode in /etc/nut/nut.conf:

MODE=netclient

Now you can monitor a daemon by adding the following line to /etc/nut/upsmon.conf:

MONITOR eaton@ups-server 1 user 2022differentPassword slave

ups-server is the address of the server running the daemon. If it on the same machine, this will be localhost.

The 1 means that there is one power supply connected to the UPS.

user and 2022differentPassword is the username and password described on the server’s /etc/nut/upsd.users file.

slave means that this system shuts down immediately when power goes critical. This is recommended for client machines listening to a server. If this is on the server, this value should be master instead, as it will allow the server to wait for the clients to shutdown first.

Now you can restart the monitor service to apply the settings:

systemctl restart nut-monitor

And you should be configured!

Advanced Configuration #

Sending email notifications #

The benefit of using NUT is that it allows you to run scripts in the event of a power event. We can leverage this to send email notifications.

To do this, we can begin by installing a command-line mail client. In this example, we’ll use s-nail:

apt install s-nail

Now, create a bash script and place it somewhere secure, such as inside a directory in /etc/nut/ with 750 file permissions:

chmod 0750 notify.sh
chown nut:nut notify.sh

Either copy the following and change the variables, or create your own script:

#!/bin/bash

message='Unknown error.'
recipients='email@email.tld email2@email.tld' # separate with a space

# SMTP Settings:
username='test' # IMPORTANT: Ensure that this is percent encoded.
password='TEST%20asdkf' # IMPORTANT: Ensure that this is percent encoded.
email='your-email@email.tld'
server='smtp.server.tld'

if [[ "$NOTIFYTYPE" = "ONBATT" ]]; then
message="UPS AC power was lost!"

elif [[ "$NOTIFYTYPE" = "ONLINE" ]]; then
message="UPS AC input has been restored."

elif [[ "$NOTIFYTYPE" = "LOWBATT" ]]; then
message="UPS Battery is LOW!!"

elif [[ "$NOTIFYTYPE" = "SHUTDOWN" ]]; then
message="UPS SHUTDOWN received!"

elif [[ "$NOTIFYTYPE" = "COMMOK" ]]; then
message="Communications Restored."

elif [[ "$NOTIFYTYPE" = "COMMBAD" ]]; then
message="Lost Communications with UPS!"

elif [[ "$NOTIFYTYPE" = "REPLBATT" ]]; then
message="UPS Battery needs to be replaced."

else
message="UPS Reported the notification type: $NOTIFYTYPE"
fi

echo ${message} | s-nail -S v15-compat -S "mta=smtp://${username}:${password}@${server}" -S smtp-auth=login -S smtp-use-starttls -S from="$UPSNAME <${email}>" -s "URGENT - UPS NOTIFICATION" ${recipients}

Now add the following line to /etc/nut/upsmon.conf:

NOTIFYCMD "/bin/bash /etc/nut/script/notify.sh"

Where /etc/nut/script/notify.sh is the location of the script you just created.

Sending text notifications #

Similarly, you can use the above script to send text messages. Most carriers allow customers to receive messages from emails to their phone numbers. You can easily look up the address your carrier has for your number by searching around, or using a website like this.

For example, a number 919-123-4567 on T-Mobile could use 9191234567@tmomail.com as a recipient to receive email notifications to SMS.