DEV Community

Cover image for Safely Shutting Down Your Homelab During a UPS Outage with NUT
Mustafa ERBAY
Mustafa ERBAY

Posted on • Originally published at mustafaerbay.com.tr

Safely Shutting Down Your Homelab During a UPS Outage with NUT

Unexpected power outages in homelab or small server environments can lead to data corruption and hardware damage. To prevent this, using Network UPS Tools (NUT) to ensure automatic and safe shutdown of servers with uninterruptible power supplies (UPS) is critically important. NUT is an open-source solution that monitors a UPS and sends shutdown commands to connected servers in the event of a power failure.

In this guide, we will walk through how to set up and configure NUT in a homelab environment. The goal is to ensure that all servers on the network automatically shut down, preserving data integrity, when the UPS battery level drops below a certain threshold. This setup not only prevents data loss but also extends hardware lifespan, offering a trouble-free operating environment in the long run.

What is NUT and Why is it Important for a Homelab?

Network UPS Tools (NUT) is a software suite that can communicate with various UPS hardware and monitor their status. Essentially, it reads the power status of a UPS (such as whether AC power is present, battery level, estimated runtime) and transmits this information to other systems on the network. This allows servers to be safely shut down before battery power drops to critical levels during a power outage.

Homelab environments often contain storage servers, virtualization platforms, or media servers that house sensitive data. An unexpected power outage can lead to corruption of open files, databases, or operating system kernels on these systems. NUT eliminates these risks, significantly enhancing your homelab's resilience and data integrity.

ℹ️ NUT Components

A NUT system typically consists of three main components:

  • Driver: The software component that communicates directly with the UPS and reads its status information. Different drivers are used for each UPS model or connection type (USB, serial, SNMP).
  • upsd (UPS Daemon): A server daemon that broadcasts information received from the driver to other clients over the network. It runs on the system to which the UPS is connected.
  • upsmon (UPS Monitor): A client daemon that monitors the upsd server on the network and triggers defined actions (e.g., system shutdown) based on UPS status changes.

These components make it possible to centrally monitor the status of a UPS and manage multiple machines on the network according to that status. For example, an upsd service monitoring a UPS connected to a main server can ensure that other virtual machines or storage devices also benefit from this information and shut down at the appropriate time.

Preparing Your Homelab for UPS and NUT Installation

Before starting the NUT installation, you need to perform some preliminary preparations in your homelab environment. Correct UPS selection and physical connections are fundamental steps for successful integration. First, ensure that the UPS you will use is supported by NUT. Most modern USB or SNMP-enabled UPS units are compatible with NUT.

Connect your UPS directly to a server (typically the main server that will act as the NUT server) using a USB cable. If you have a UPS that communicates over the network via SNMP or a proprietary network protocol, a USB connection is not necessary. However, in most homelab scenarios, a USB connection is more common and cost-effective.

💡 System Requirements

It is preferable for the system where you will install NUT to be Linux-based. Distributions like Ubuntu, Debian, CentOS are widely supported. Additionally, NUT may require udev rules or USB access permissions to function. Before installation, ensure your system is up-to-date and necessary dependencies (e.g., libusb) are installed.

Preparation Steps:

  1. UPS Connection: Plug the UPS into an electrical outlet and connect it to the machine that will be the main NUT server using a USB cable.
  2. Check UPS Support: Find out your UPS model and the driver supported by NUT. The lsusb command can help you see the Vendor ID and Product ID of a USB-connected UPS. This information is important for selecting the correct NUT driver. The nut-scanner tool can automatically detect compatible devices and suggest drivers.
  3. Network Structure: If you have multiple servers, ensure that all servers are on the same network segment as the NUT server or have an accessible IP address. Make sure firewall rules do not block the ports used by upsd (default 3493).

These preliminary preparations will prevent many issues you might encounter during the installation process. Especially, UPS recognition and driver selection form the basis of NUT's operation.

NUT Server (upsd) Configuration

The heart of NUT, the upsd server, is the component that establishes a direct connection with the UPS and monitors its status. This server typically runs on the Linux machine to which the UPS is physically connected. Configuration steps involve ensuring the UPS is recognized with the correct driver and that its status information is broadcast over the network.

First, you need to install the NUT packages. On Ubuntu/Debian-based systems, you can use the following command:

sudo apt update
sudo apt install nut
Enter fullscreen mode Exit fullscreen mode

After installation, you need to edit the /etc/nut/ups.conf file to define your UPS. This file specifies which driver NUT should use and which port the UPS is connected to.

```ini title="/etc/nut/ups.conf"
[myups]
driver = usbhid-ups
port = auto
desc = "Homelab Main UPS"




Here, `[myups]` is the identifier name for the UPS. The `driver` parameter specifies the correct driver for your UPS. `usbhid-ups` is a standard driver for most USB HID-compatible UPS units. `port = auto` is usually sufficient for USB connections; however, if you are using a serial port, you might need to specify a value like `/dev/ttyS0`.

Next, you need to configure the `/etc/nut/upsd.conf` file to determine how the `upsd` server will behave. This file specifies which IP addresses `upsd` will accept connections from.



```ini title="/etc/nut/upsd.conf"
LISTEN 0.0.0.0 3493
Enter fullscreen mode Exit fullscreen mode

The LISTEN 0.0.0.0 3493 command ensures that upsd listens for connections from all network interfaces on the default port 3493. This is necessary for other servers on the network to be able to connect to upsd. For security reasons, you can make the LISTEN parameter more specific to listen on particular IP addresses or network interfaces.

Finally, in the /etc/nut/nut.conf file, you need to set the NUT mode to standalone or netserver. For this server, we should use MODE=standalone or MODE=netserver.

```ini title="/etc/nut/nut.conf"
MODE=standalone




Or, if this system will only communicate with the UPS and broadcast to the network:



```ini title="/etc/nut/nut.conf"
MODE=netserver
Enter fullscreen mode Exit fullscreen mode

After completing the configurations, restart the NUT services and check their status:

sudo systemctl restart nut-server nut-client
sudo systemctl status nut-server nut-client
Enter fullscreen mode Exit fullscreen mode

You can check the UPS status with the upsc myups@localhost command. If everything is configured correctly, you should see information such as the UPS's battery level, input/output voltages.

# Example Output (may vary)
# battery.charge: 100
# battery.runtime: 1800
# ups.status: OL
# input.voltage: 230.0
# output.voltage: 230.0
Enter fullscreen mode Exit fullscreen mode

This step verifies that the NUT server is successfully communicating with the UPS and is ready to broadcast information to the network.

NUT Client (upsmon) Configuration

Once the NUT server (the machine connected to the UPS) is configured, other servers and clients on the network need to monitor this UPS and shut down safely when necessary. This is done by configuring the upsmon daemon on each client machine. upsmon can run predefined scripts in response to specific UPS events (e.g., dropping battery level or power outage).

Install NUT packages on each client machine:

sudo apt update
sudo apt install nut
Enter fullscreen mode Exit fullscreen mode

Then, set the mode to netclient in the /etc/nut/nut.conf file:

```ini title="/etc/nut/nut.conf"
MODE=netclient




Now, edit the `/etc/nut/upsmon.conf` file to configure it to monitor the `upsd` server. This file specifies which UPS `upsmon` will monitor, what actions to take at which thresholds, and which user it will run as.



```ini title="/etc/nut/upsmon.conf"
RUN_AS_USER nut

MONITOR myups@192.168.1.100 1 admin pass master

MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h now"
NOTIFYCMD "/usr/bin/logger -t upsmon"

# Initiate shutdown when battery level drops below 20%
NOTIFYMSG ONLINE "UPS %s is back on mains power."
NOTIFYMSG ONBATT "UPS %s is running on battery power."
NOTIFYMSG LOWBATT "UPS %s battery level is critical!"
NOTIFYMSG FSD "UPS %s initiating safe shutdown."
NOTIFYMSG COMMBAD "UPS %s communication lost."
NOTIFYMSG COMMOK "UPS %s communication re-established."

NOTIFYFLAG ONLINE SYSLOG+WALL
NOTIFYFLAG ONBATT SYSLOG+WALL
NOTIFYFLAG LOWBATT SYSLOG+WALL
NOTIFYFLAG FSD SYSLOG+WALL
NOTIFYFLAG COMMBAD SYSLOG+WALL
NOTIFYFLAG COMMOK SYSLOG+WALL

# Initiate shutdown when battery level drops below 20%
# or remaining runtime is less than 5 minutes (300 seconds)
BATTERYLEVEL 20
BATTERYRUNTIME 300

# Shut down within 30 seconds after shutdown signal
FINALDELAY 30
Enter fullscreen mode Exit fullscreen mode

In the configuration above:

  • RUN_AS_USER nut: Ensures upsmon runs as the nut user.
  • MONITOR myups@192.168.1.100 1 admin pass master: Monitors the UPS named myups on the NUT server at 192.168.1.100. 1 is the number of UPS units to monitor (powervalue), admin and pass are the username and password (we will define this information in the upsd.users file on the upsd server). master indicates that this client has the authority to trigger the shutdown command.
  • SHUTDOWNCMD "/sbin/shutdown -h now": The safe shutdown command.
  • BATTERYLEVEL 20: Triggers the LOWBATT status when the battery level drops below 20%.
  • BATTERYRUNTIME 300: Triggers the LOWBATT status when the remaining runtime drops below 300 seconds (5 minutes).
  • FINALDELAY 30: Waits 30 seconds after the shutdown command is received.

For upsmon to connect to the upsd server, you need to define a user on the upsd side. Edit the /etc/nut/upsd.users file on the NUT server:

```ini title="/etc/nut/upsd.users"
[admin]
password = pass
actions = SET
instcmds = ALL
upsmon master

[monitor]
password = secret
upsmon slave




Here, the `[admin]` user allows `upsmon` to connect as `master`. A `monitor` user can also be defined for other clients connecting as `upsmon slave`.

After completing the configurations, restart the `nut-client` service on the client machines and check its status:



```bash
sudo systemctl restart nut-client
sudo systemctl status nut-client
Enter fullscreen mode Exit fullscreen mode

With these steps, your client machines will now be able to monitor the UPS status and be ready to shut down safely in the event of a power outage.

Diagram

Safe Shutdown Scripts and Testing

When the NUT client (upsmon) is configured, it shuts down the system by executing the command specified by the SHUTDOWNCMD parameter. While this command is usually a simple sudo /sbin/shutdown -h now, in some cases you might want to run a more complex script. For example, priority steps such as backing up databases, stopping virtual machines, or shutting down specific services might be necessary.

To create your own shutdown script, you can write a script that SHUTDOWNCMD will point to. For example, create a file named /etc/nut/ups_shutdown.sh and add content like this:

```bash title="/etc/nut/ups_shutdown.sh"

!/bin/bash

Log the shutdown event

logger "NUT: UPS battery level critical. Initiating safe shutdown."

Stop critical services gracefully

sudo systemctl stop postgresql

sudo systemctl stop docker

Shut down virtual machines (if any)

for vm in $(virsh list --name); do

virsh shutdown $vm

done

Wait for a short period for services/VMs to stop

sleep 10

Final system shutdown

/sbin/shutdown -h now




Don't forget to make this script executable: `sudo chmod +x /etc/nut/ups_shutdown.sh`. Then update `SHUTDOWNCMD` in the `upsmon.conf` file to point to this script: `SHUTDOWNCMD "/etc/nut/ups_shutdown.sh"`.

**Testing Process:**

Testing the shutdown scenario is a critical step. However, simulating a full power outage on a live system can be risky. A safer testing approach might include:

1.  **Disconnecting the UPS from Mains:** The simplest test is to disconnect the UPS from the mains power. When the UPS switches to battery power, check `upsmon` logs and notifications. You should observe systems starting to shut down when the battery level drops below the `BATTERYLEVEL` and `BATTERYRUNTIME` thresholds.
    *   You can monitor logs with `journalctl -u nut-client -f` or `tail -f /var/log/syslog`.
2.  **Manually Triggering `upsmon` Commands:** You can use the `upsmon -c fsd` command to trigger `upsmon`'s shutdown command. This command forces `upsmon` clients running in primary mode to shut down the UPS. However, this is not a full test and should be used with caution.
3.  **Using a Test Environment:** If possible, test the entire scenario using a copy of your homelab or a less critical test machine. This minimizes the risk of potential data loss.

> **⚠️ Caution!**
>
> When performing actual shutdown tests, consider the risk of data loss. Ensure your important data is backed up and that no critical operations are active during the test.

During testing, you can use NUT utilities like `upsc` and `upslog` to monitor UPS status and NUT events in detail. This will help you identify the root cause of any issues.

## Common Problems and Troubleshooting

It is possible to encounter some common problems during NUT installation and configuration. Correctly diagnosing and resolving these issues is important for ensuring the reliability of your system. Problems usually stem from the UPS driver, connection permissions, or network configuration.

**1. UPS Not Recognized or Driver Error:**

*   **Symptom:** The `upsc myups@localhost` command returns an error or the `nut-server` service fails to start. Driver loading errors appear in the `journalctl -u nut-server` output.
*   **Solution:**
    *   **Correct Driver:** Ensure that the `driver` parameter in `/etc/nut/ups.conf` matches your UPS model. Look for the correct driver in NUT documentation or on the UPS manufacturer's website.
    *   **USB Connection:** Ensure the USB cable is secure and the UPS is recognized by the computer (check with the `lsusb` command).
    *   **Permissions:** Ensure the `nut` user has access permissions to the USB device. `udev` rules usually set these permissions automatically, but sometimes manual intervention may be required. It might be necessary to add a custom rule under `/etc/udev/rules.d/`.

**2. `upsd` (NUT Server) Not Starting or Inaccessible from Network:**

*   **Symptom:** `systemctl status nut-server` output shows an error. Client machines cannot connect to `upsc myups@UPS_IP`.
*   **Solution:**
    *   **Port Conflict:** Ensure that port 3493 is not being used by another service (`sudo netstat -tulpn | grep 3493`).
    *   **Firewall:** Ensure that the firewall (ufw, firewalld) between the NUT server and clients is not blocking port 3493. Add a rule if necessary: `sudo ufw allow 3493/tcp`.
    *   **`LISTEN` Setting:** Ensure that the `LISTEN` parameter in `/etc/nut/upsd.conf` is set to the correct IP address or `0.0.0.0` (all interfaces).

**3. `upsmon` (NUT Client) Cannot Monitor UPS or Shutdown Not Triggered:**

*   **Symptom:** `COMMBAD` or `COMMOK` messages frequently change in `upsmon` logs, or the system does not shut down when the battery level drops.
*   **Solution:**
    *   **NUT Server Accessibility:** Ensure you can ping the NUT server's IP address from the client machine and connect to port 3493 via telnet.
    *   **`MONITOR` Parameter:** Ensure that the UPS name, IP address, username, and password in the `MONITOR` line of `/etc/nut/upsmon.conf` are correct. These values must match the definitions in the `upsd.users` file.
    *   **`BATTERYLEVEL` and `BATTERYRUNTIME` Thresholds:** Ensure that shutdown thresholds (battery level and remaining time) are set to realistic values and that these thresholds are reached during testing.
    *   **`SHUTDOWNCMD` Permissions:** Ensure that the shutdown script (if used) has executable permissions (`chmod +x`). Also, ensure the `nut` user has permission to run this script or the `shutdown` command with `sudo` (a file like `/etc/sudoers.d/nut-shutdown` can be created).

> **ℹ️ Check Logs**
>
> During troubleshooting, the commands `journalctl -u nut-server -f`, `journalctl -u nut-client -f`, and `tail -f /var/log/syslog` allow you to monitor NUT service and operating system event logs in real-time. These logs will provide important clues about where the problem started.

Knowing these common problems and their solutions will help your NUT installation proceed more smoothly.

## Advanced Configurations and Use in Commercial Environments

While a basic NUT setup is usually sufficient for homelab environments, NUT offers some advanced features for more complex scenarios or commercial use. These features can provide greater flexibility, redundancy, and automation.

**1. Monitoring Multiple UPS Units:**
If you have multiple UPS units in your homelab or systems powered by different power sources, `upsmon` can monitor multiple UPS units simultaneously. You just need to define a separate `MONITOR` line for each UPS in the `/etc/nut/upsmon.conf` file. This allows you to implement different shutdown strategies based on the status of each UPS.

**2. Redundant UPS Configurations:**
In commercial environments, redundant UPS units are often used to ensure high availability. NUT can be configured to switch to a secondary UPS if the primary UPS fails. This can be managed with `upsmon`'s `MINSUPPLIES` parameter and multiple `MONITOR` lines. The `MINSUPPLIES` value specifies the minimum number of working UPS units the system needs before issuing a shutdown command.

**3. SNMP-Enabled UPS Units:**
In large data centers or some advanced homelabs, UPS units can be connected directly to the network and managed via SNMP (Simple Network Management Protocol). NUT can communicate with such UPS units using the `snmp-ups` driver. This eliminates the need for a physical server connected to the UPS and provides more flexible management.



```ini title="/etc/nut/ups.conf (SNMP Example)"
[networkups]
  driver = snmp-ups
  port = 192.168.1.200:161:public
  desc = "Network-based UPS"
Enter fullscreen mode Exit fullscreen mode

Here, the port parameter specifies the UPS's IP address, SNMP port, and community string (default public).

4. Shutting Down Virtual Machines:
If your homelab uses a virtualization platform like Proxmox, VMware ESXi, or KVM, you can add commands to safely shut down virtual machines within the shutdown script triggered by upsmon. For example, for KVM, you can use the virsh shutdown <VM_NAME> command. This is a critical step for preserving the data integrity of virtual machines.

💡 Automation and Orchestration

In many projects where I developed enterprise software architecture, I've seen how critical these types of automation and orchestration steps are for uninterrupted system operation. A simple shutdown script can prevent a complex ERP system or a database cluster from suffering millions of dollars in damage. I always prefer an automation solution that fully covers the scenario.

These advanced features transform NUT from just a simple shutdown tool into an important part of your homelab or commercial environment's power management strategy. With correct configuration, you can ensure your systems remain secure and stable under all conditions.

Conclusion

Protecting data integrity and hardware lifespan in homelab environments is possible by developing a robust strategy against unexpected power outages. Network UPS Tools (NUT) is one of the cornerstones of this strategy. In this guide, we have covered what NUT is, how it works, and how to configure it step-by-step on both the server and client sides.

A proper NUT setup ensures that your servers automatically and safely shut down when your UPS switches to battery power. This prevents data loss and system damage that could result from open database connections, unfinished file operations, or operating system kernel corruption. We also touched upon common problems you might encounter during the installation process and their troubleshooting methods, aiming to provide you with a smoother experience.

It should be remembered that, as with any automation system, regularly testing your NUT setup and reviewing possible scenarios is critically important. This way, you can be sure that your system will perform as expected during a real power outage. Integrating NUT to enhance your homelab's resilience is one of the most valuable investments you can make.

Official Resources

Top comments (0)