---
layout: post
title: NUT and UPS on Linux
date: 2021-04-09 17:30:00
tags: untagged
author: neko
---

# Preface

The following information was collected for my wiki in the process of setting up a UPS for my home storage system in mid 2020. I think these instructions might prove interesting for someone looking to do the same. This document covers setting up NUT in a Master/Slave configuration aswell as a routine for an emergency shutdown in case of a power failure.

# Prequisites

* NUT must support your UPS.[^1]
* Make sure the UPS is detected when plugged in by checking `dmesg` and `lsusb`, look out for related information like "usb device connected"

[^1]:check [Compatibility](https://networkupstools.org/stable-hcl.html) for more details

# NUT

NUT (Network UPS Tools) is the linux standard way of monitoring a UPS and taking actions in case of a power failure.

Generally, all configuration is under `/etc/nut`. 

A general config file for the full stack, called `/etc/nut/nut.conf` is supplied that allows setting up in which mode the stack is supposed to run: 

* `none`: NUT is disabled
* `standalone`: Use this if you are only having this single system on the UPS. This launches all 3 component layers
* `netserver`: same as standalone, launching all 3 component layers, but allowing for remote access to have remote systems take actions
* `netclient`: this only launches `upsmon` to take action upon a remote machine

NUT comes with a driver part, accessed via `upsc`, that queries the UPS for information. The configuration file for the client is `/etc/nut/ups.conf` and contains information on how to access the UPS.

The server part of NUT, called `upsd`, allows accessing the information supplied by the client over the network. This is used for querying the UPS from remote machines. The related config file is `/etc/nut/upsd.conf`. Whoever is allowed to access the server is handled in `/etc/nut/upsd.users`.

The last part of the stack is `upsmon`. This part handles monitoring for changes in the UPS in case of a power failure and taking actions. `upsmon` can access `upsd` remotely or locally. `upsmon` is configured via `/etc/nut/upsmon.conf`

# Installing and setting up NUT

## Installing required packages

NUT is available in all major distros. For Debian, the following command should install the NUT Server, Client and the upsmon monitoring utility.

```
apt install nut
```

## Mode setting

Edit the `nut.conf` and set the mode to either `standalone`, `netserver` or `netclient`. For my configuration, `netserver` is used as a secondary machine needs to access the information to shut down aswell.

```
MODE=netserver
```

## Driver setup

If available, run `nut-scanner` to search for compatible UPS system. This might not be available on Debian. If not, go through the compatibility list of compatible devices linked below in the links section to see what driver supports your device.

Edit the driver configuration file and add a new UPS section. Name the UPS something you remember. You need it to access the UPS.

```
[upsname]
  driver = <your driver>
  port = auto
```

For my UPS, the Eaton Ellipse Eco 650, I chose:

```
[eaton]
  driver = usbhid-ups
  port = auto
```

## Server setup

If the stack was set to `netserver`, we now need to edit the server config file. Firstly, by default the server only listens to localhost. Uncomment the listen directive and allow accesses from your local network or specific hosts:

```
LISTEN 0.0.0.0 3493
```

Now set up users in the `upsd.users` configuration. I set up a master user for the host system, and a slave user for all the systems that will access the information remotely. Select names for your users

```
[masterusername]
  password = pass
  upsmon master

[slaveusername]
  password = pass
  upsmon slave
```

## upsmon setup

Lastly we need to set up what happens if a power failure is detected. For that, edit the `upsmon.conf` and add a `MONITOR` configuration directive. Take care to use the username of the master user.

```
MONITOR upsname@localhost 1 masterusername password <master or slave>
```

The supplied number in field 3 is the amount of required UPS devices to keep the systems running. In most cases, this will be 1. For a professional setup you might want more than a single UPS running.

In case of the Eaton UPS the following directive was used:

```
MONITOR eaton@localhost 1 monmaster pass master
```

Now make sure the supplied command for shutting down is correct. The directive should already be in your configuration. Find the line:

```
SHUTDOWNCMD "/sbin/shutdown -h +0"
```

Mind that this command may not be right for everyone. Mind that sometimes services take a long time to shut down. Change it out with a script if needed. 

In case of a software RAID system, take special care: shutting down may be unsafe and may lead to long resync times after reboot. For my system, I used the following script: 

```bash
#!/bin/sh

# shutdown script for upsmon
# remounts all filesystems as read only, then sets the raid to readonly and powers down

# print out warnings on my impact printer
echo "$(date) Emergency shutdown signal recieved from UPS, shutting down" | /usr/bin/lpr

# alert everyone currently on the system
wall "Emergency system shutdown due to power outage."

# set all mountpoints of the shared folders to read only
/usr/bin/mount -o remount,ro /media/share/Books/
/usr/bin/mount -o remount,ro /media/share/Images/
/usr/bin/mount -o remount,ro /media/share/Music/
/usr/bin/mount -o remount,ro /media/share/Pictures/
/usr/bin/mount -o remount,ro /media/share/Videos/

# sync the drives
/usr/bin/sync

# switch of smbd
/usr/sbin/service smbd stop

# umount the share folders
/usr/bin/umount /media/share/*

# disable the volume group
/usr/sbin/vgchange -a n share

# set the raid to read only
/usr/sbin/mdadm --readonly /dev/md127

# finally power down the system
/sbin/shutdown -h +0

```

## Slave setup

If another machine is supposed to listen to the UPS aswell, install NUT on that machine and set the mode to `netclient`. Edit the `upsmon.conf` and add corresponding `MONITOR` directive:

```
MONITOR upsname@server 1 slaveusername password slave
```

In case of the EATON, this was supplied on the NAS system that runs as a slave: 

```
MONITOR eaton@pve.local 1 monslave pass slave
```

## Final notes

After the setup is finished, a shutdown sequence test should be done. After all servers have shut down, the UPS should recognise the load dropping and launch a power cycle. This should restart all servers (if set up correctly in the BIOS).

# Testing and debugging

To access the UPS and query information, `upsc <upsname>@<server>` can be used.

To control the driver, a utility called `upsdrvctrl` is supplied. Launching it as `upsdrvctl start` should tell you more information about the connected UPS.

To test the full shutdown sequence, `upsmon -c fsd` will trigger a shutdown as if the power would've failed. **Careful**: This will shut down the servers.

`upsdrvctl -t shutdown` will give information about the shutdown sequence without actually triggering it.

# Helpful links

[Configuration notes](https://networkupstools.org/docs/user-manual.chunked/ar01s06.html)
[Archwiki Setup Guide](https://wiki.archlinux.org/index.php/Network_UPS_Tools)
[Compatibility List](https://networkupstools.org/stable-hcl.html)