Network UPS Tools (NUT) - zbrewer/homelab GitHub Wiki

I'm using an old APC Back-UPS ES 750 to power my ISP's ONT and a few other devices outside of my server rack. This can't be monitored by any of the devices it is powering (or over the network) directly so I installed Network UPS Tools (NUT for short) on an old first-gen Raspberry Pi by following this guide. This allows me to monitor the UPS over the network and shut it down when the low battery threshold is reached.

In addition, I have an Eaton 5PX-2200RT with an Eaton Network Card-MS installed in my server rack to power everything there. I still use NUT to monitor this UPS from the servers that it protects, but this time via SNMP connection to the Eaton UPS's network card instead of direct USB. This allows each server to connect to the UPS directly instead of having to communicate with (and host) a central NUT server for this UPS. In addition, it allows me to configure the behavior for each server (such as the low battery threshold) independently, if desired.

Installation

Server/Standalone/Primary Mode

Start by setting up Linux on whatever machine will be monitoring your UPS. This could already be done (for example, if monitoring from Proxmox or TrueNAS) but you could also create a new Linux LXC or VM somewhere.

If setting up a new Raspberry Pi for monitoring, install the Raspberry Pi OS using the latest installer from their website. Headless install mode is particularly convenient to set up the installed OS on the SD card with an SSH server, password, and IP address so that you never have to plug a monitor in.

After installing the OS, SSHing in, and ensuring that all of the packages are updated. If connecting the UPS via USB, plug it in and check that it is detected by taking a look at the output of:

$ lsusb

Alternatively, configure SNMP in the settings of the UPS's network card (ideally SNMP v3 so that there is some authentication) and test to make sure that it can be reached from the server on which NUT will be installed. This may involve configuring the firewall to allow the NUT server to reach the UPS's network card on the appropriate port (usually UDP and port 161). The connection test can be performed by installing the snmp package and then using a command such as the following:

$ snmpwalk -v3 -l authNoPriv -u <user> -A <password> <ip_address> <base_oid>

See the man pages for more command options.

Assuming the UPS is detected/reachable, install the NUT packages from the official repositories with the following command:

$ sudo apt-get update && sudo apt-get install nut nut-client nut-server

Next, configure the UPS in NUT by editing /etc/nut/ups.conf to contain the following at the bottom (the text in the brackets is the name of the UPS and can be whatever you like):

[apc-ups]
driver = usbhid-ups
port = auto
desc = "APC Back-UPS ES 750"

If using an Eaton UPS (or any other that supports monitoring/control over SNMP), the snmp-ups driver should be used. This requires installing the nut-snmp package (in addition to those listed above) and configuring NUT with the access credentials such as in the example below. The full documentation is available here.

[eaton-5px2200rt]
desc = "Server Room Eaton 5PX2200RT"
driver = snmp-ups
port = <UPS network card IP address>
mibs = auto
snmp_version = v3
secLevel = authNoPriv
secName = readuser
authPassword = <password>

Also note that, if you're planning on overriding the low battery threshold on the Eaton UPS, it won't set the low battery flag when this new threshold is reached. Instead, you'll need to configure this here in ups.conf on the NUT server side. See the instructions below for how to do this.

Next, edit /etc/nut/upsmon.conf to contain the following:

# MONITOR <system> <powervalue> <user> <password> ("master"|"slave")
MONITOR apc-ups@localhost 1 monuser <password> master

In this example, apc-ups is the name configured above, upsmon will be the monitoring user, and <password> will be replaced with the password. Note that the username and password here can be anything and will only be used by secondary clients of this NUT server, if any (see below for instructions on how to set that UP). Next, edit /etc/nut/upsd.users to contain the same user:

[monuser]
   password = <password>
   upsmon master

With that done, if this NUT server will be a primary host that other NUT servers connect to, enable the server mode by changing the last line of /etc/nut/nut.conf to:

MODE=netserver

If, on the other hand, this NUT server will operate in standalone mode (no clients connected to it), you can make the last line of /etc/nut/nut.conf:

MODE=standalone

Finally, if using the netserver mode, edit /etc/nut/upsd.conf to set the monitoring interface (see this thread). This file should contain:

LISTEN 127.0.0.1 3493
LISTEN ::1 3493
LISTEN 0.0.0.0 3493

Next, restart the server and type:

$ upsc <ups-name-from-ups.conf>@localhost

Information about the UPS should be printed out and the basic install should be complete. Remote servers can now be set up to read this data (using the username and password configured) if netserver mode was used.

Web Interface

If a web server for monitoring the UPS status is also desired, the following steps can be taken.

First, install the required packages:

$ sudo apt-get install apache2 nut-cgi

Next, edit /etc/nut/hosts.conf to contain:

MONITOR <ups-name>@localhost "Readable UPS Name"

Now, enable CGI in the web server and restart it:

$ a2enmod cgi
$ systemctl restart apache2

Finally, uncomment the following line in /etc/nut/upsset.conf:

### I_HAVE_SECURED_MY_CGI_DIRECTORY

The web interface should now be accessible at http://<ip_address>/cgi-bin/nut/upsset.cgi and the monitoring page will be at http://<ip_address>/cgi-bin/nut/upsstats.cgi. The username and password required to access them are the same as configured earlier.

TrueNAS

TrueNAS has a NUT integration built-in that can be configured via the GUI. See the instructions here for more information.

Client/Secondary Mode

If you would like additional clients to monitor a primary NUT server (that has been set up in netserver mode), they can be configured as NUT clients. This is useful in cases such as with the APC UPS where the UPS may have a single USB connection but you want it to be monitored by more than one server. Upon reaching a low battery state, the primary NUT server will signal each of the clients to shutdown before shutting itself down and turning off the UPS..

To do this, first install the nut package:

$ sudo apt-get install nut

Next, edit the /etc/nut/nut.conf file so that the mode is set as netclient.

Finally, edit /etc/nut/upsmon.conf to contain the appropriate line to monitor the remote server. This will be in the form:

MONITOR <ups-name@host> <powervalue> <username> <password> ("primary"|"secondary")

In the case of my Eaton UPS, this looks like:

MONITOR [email protected] 1 monuser <password> secondary

Finally, with that configured, start the nut client with the upsmon start command. You should be able to confirm that it is communicating with the primary NUT server using the upsc ups-name@host command (for example, upsc [email protected]). This should print the UPS information.

Additional Configuration

Power Off Behavior

By default, when a low battery threshold is reached (based on either time remaining or battery percentage, whichever happens first) the NUT server(s) connected to that UPS will begin shutting down. What exactly happens here depends on the mode that it is running in.

If the NUT server is in standalone mode, it will shut itself down and signal the UPS to turn off when it is done.

If it is in netserver mode, it will signal its clients (running in netclient mode and with the secondary designation in their MONITOR stanza in /etc/nut/upsmon.conf) to shut down and then wait a pre-designated amount of time for those operations to complete. It will then shut itself down and signal the UPS to turn off when it is done.

Finally, if it is in netclient mode, it will receive the shutdown command from the primary server when the primary server determines that the low battery condition has been reached and it will shut itself down.

This behavior can be configured based on the options below:

Low Battery Threshold

By default, the UPS defines the low battery threshold and NUT respects this. More advanced UPSs (such as the Eaton UPS I use) allow this threshold to be configured directly on the UPS; however, it doesn't set the low battery flag to initiate server shutdown on the UPS side. Instead, this value must be set in NUT and it must be told to ignore the low battery flag from the UPS. This is also useful when using simpler UPSs (such as the APC UPS I have), where this may not be a configuration option at all. Finally, this technique is also useful if there are some clients that you would like to turn off before the UPS-defined low battery threshold has been reached (for load shedding).

In order to change the default low battery threshold, edit the configuration for the UPS in the /etc/nut/ups.conf file. Add the ignorelb option to ignore the UPS's low battery status and then specify a new percentage remaining with override.battery.charge.low and/or a new time (in seconds) remaining with override.battery.runtime.low. For example, for the APC UPS, this might look like:

[truenas-ups]
driver = usbhid-ups
port = auto
desc = "APC Back-UPS ES 750"
ignorelb
override.battery.charge.low = 60
override.battery.runtime.low = 300

Note, however, that this is only an option if NUT is running in standalone or netserver mode and that changes to the netserver will affect its clients as well.

These options can be reloaded without restarting the server using the upsdrvctl start command.

UPS Shutdown

Sometimes, it may not be desirable to shut down the UPS when the server running NUT shuts down. For example, if there are many clients of an SNMP UPS with different shutdown thresholds configured, the clients that shutdown earlier shouldn't cause the UPS to power off since there are still other clients running. On the other hand, in a simple example like with the APC NUT server, shutting down the UPS might be exactly what is desired.

Direct connections likely support UPS Shutdown by default while SNMP connections with a read-only user likely won't allow this. That being said, you can test whether or not shutting down the UPS itself from a given NUT server works but using the command: upsmon -c fsd. This will attempt to power cycle the UPS (as if power was lost and then restored). If the UPS power cycles, NUT will shut it down after the NUT server shuts off. If the UPS doesn't shut down, NUT won't be able to turn it off.

In the event that NUT is able to turn the UPS off, but you don't want it to, you can comment out the POWERDOWNFLAG line in /etc/nut/upsmon.conf to prevent the POWERDOWN file (flag) that is checked at shutdown from being written. Alternatively, you could remove or comment out the line (at least the /sbin/upsdrvctl shutdown portion that actually shuts down the UPS) in the shutdown script located at /usr/lib/systemd/system-shutdown/nutshutdown.

Telegraf/InfluxDB

UPS statistics can be exported to InfluxDB using the native UPSD plugin. The documentation specifies the input plugin parameters that should be set but this mostly just amounts to setting the NUT server IP address, port, and login credentials. The Telegraf config file I use can be found here.

Telegraf can then be run on the same machine as NUT (using localhost/127.0.0.1 as the server) or via Docker. Installing Telegraf natively can be accomplished as per the Telegraf docs. A Docker setup can be completed using the files here. In the Docker case, put the telegraf.conf (renamed to apc-network-shelf-telegraf.conf), docker-compose.yaml, and env (rename to .env) files in a directory together. Set the username, password, and InfluxDB token in the .env file and remove any containers from docker-compose.yaml file that aren't needed. Start Docker with docker compose up -d from the same directory.

These metrics can then be displayed in Grafana using the dashboard configuration here.

⚠️ **GitHub.com Fallback** ⚠️