Instalación y configuración de NUT con PeaNUT en Debian 13

nut

¿Que es NUT?

NUT (Network UPS Tools) es un conjunto de herramientas de código abierto para monitorizar sistemas de alimentación ininterrumpida (SAI o UPS). NUT permite consultar el estado del SAI (tensión de entrada, carga, estado de la batería, etc.), avisar cuando se va la corriente y, sobre todo, apagar de forma ordenada los equipos antes de que la batería se agote, evitando cortes bruscos que puedan corromper datos.

En este tutorial vamos a instalar y configurar NUT en Debian 13, monitorizando un SAI conectado por USB. En mi caso el servidor es una Raspberry Pi 5 con arquitectura ARM de 64 bits (aarch64), pero NUT está disponible en los repositorios oficiales de Debian tanto para amd64 como para arm64, por lo que la instalación y la configuración son idénticas en ambas arquitecturas.

Requisitos

  • Debian 13 instalado (en este caso sobre Raspberry Pi 5, arquitectura aarch64).
  • Un SAI con conexión USB al servidor.
  • Privilegios de sudo o root.

Conexión del SAI y detección USB

Con el SAI conectado por USB al servidor, comprobamos que el sistema lo detecta con el comando lsusb:

root@nut:~# lsusb
Bus 004 Device 002: ID 0001:0000 Fry's Electronics MEC0003
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

En la primera línea vemos el SAI. Es importante apuntar el idVendor y el idProduct (en este caso 0001:0000), ya que muchos SAI económicos comparten el mismo chip de comunicación y no traen un identificador único; indicárselos a NUT de forma explícita evita que el driver se confunda si hay varios dispositivos USB.

Instalación de NUT

NUT se instala directamente desde los repositorios oficiales de Debian 13. El metapaquete nut arrastra tanto el servidor (nut-server) como el cliente (nut-client):

root@nut:~# apt install nut -y

Podemos comprobar la versión instalada con:

root@nut:~# upsd -V
Network UPS Tools upsd 2.8.1

NUT se compone de tres piezas que vamos a configurar por orden:

  • El driver: habla con el SAI (por USB en nuestro caso) y expone sus datos. Se configura en /etc/nut/ups.conf.
  • upsd: el servidor de red que sirve esos datos a los clientes. Se configura en /etc/nut/upsd.conf y /etc/nut/upsd.users.
  • upsmon: el cliente que vigila el estado y ejecuta el apagado seguro. Se configura en /etc/nut/upsmon.conf.

Configuración del driver (ups.conf)

Editamos /etc/nut/ups.conf para definir nuestro SAI. Como es un SAI de tipo Megatec/Q1 (muy habituales), usamos el driver genérico nutdrv_qx, que se comunica por USB (libusb):

root@nut:~# nano /etc/nut/ups.conf
maxretry = 3

[ups]
    driver = nutdrv_qx
    port = auto
    vendorid = 0001
    productid = 0000
    user = root
    desc = "SAI del homelab (MEC0003)"

Unas notas importantes:

  • [ups] es el nombre interno con el que nos referiremos al SAI en el resto de comandos.
  • port = auto deja que el driver localice el dispositivo por USB automáticamente.
  • vendorid/productid son los que apuntamos con lsusb; ayudan al driver a elegir el dispositivo correcto.
  • user = root: en este caso el nodo USB pertenece a root, por lo que el driver necesita ejecutarse como root para poder abrirlo. Si el dispositivo USB tuviera permisos para el usuario nut, podríamos omitir esta línea.

Arrancamos el driver para comprobar que se comunica con el SAI:

root@nut:~# upsdrvctl start
Network UPS Tools - UPS driver controller 2.8.1
Network UPS Tools - Generic Q* USB/Serial driver 0.36 (2.8.1)
Using subdriver: Q1 0.08

La línea Using subdriver: Q1 0.08 confirma que el driver ha detectado el SAI y sabe hablar con él.

Configuración de upsd y usuarios

El servidor upsd es el que ofrece los datos por red. Editamos /etc/nut/upsd.conf para indicar en qué interfaces escucha (por defecto solo escucha en localhost; aquí lo abrimos a la red para poder consultarlo desde otros equipos y desde el panel web):

LISTEN 0.0.0.0 3493
LISTEN ::1 3493

A continuación definimos los usuarios en /etc/nut/upsd.users. Creamos uno para la monitorización (upsmon) y otro de administración para poder enviar comandos al SAI:

[monitor]
    password = ClavePorMonitor
    upsmon primary

[admin]
    password = ClaveDeAdmin
    actions = SET
    instcmds = ALL

Por último, en /etc/nut/nut.conf indicamos que este equipo actúa como servidor NUT (driver + upsd + upsmon en la misma máquina):

MODE=netserver

Habilitamos y arrancamos los servicios:

root@nut:~# systemctl enable --now nut-server nut-monitor

Consultar el estado del SAI con upsc

Con todo en marcha, ya podemos consultar el SAI con upsc. Primero listamos los SAI disponibles:

root@nut:~# upsc -l
ups

Y consultamos todas sus variables:

root@nut:~# upsc ups
battery.voltage: 27.5
device.type: ups
driver.name: nutdrv_qx
driver.version: 2.8.1
driver.version.data: Q1 0.08
driver.version.internal: 0.36
driver.version.usb: libusb-1.0.28 (API: 0x100010a)
input.frequency: 50.1
input.voltage: 232.8
input.voltage.fault: 233.3
output.voltage: 232.8
ups.beeper.status: enabled
ups.delay.shutdown: 30
ups.delay.start: 180
ups.load: 20
ups.status: OL
ups.type: offline / line interactive

Las variables más útiles son:

  • ups.status: el estado del SAI. OL (On Line) significa que está alimentado por la red eléctrica; OB (On Battery) que está tirando de la batería; y LB (Low Battery) que la batería está baja.
  • ups.load: el porcentaje de carga que está soportando el SAI.
  • input.voltage / output.voltage: tensión de entrada y de salida.
  • battery.voltage: tensión de la batería.

También podemos consultar una variable concreta indicándola después del nombre del SAI:

root@nut:~# upsc ups ups.status
OL

Apagado seguro con upsmon

La verdadera utilidad de NUT es apagar el equipo de forma ordenada cuando la batería está a punto de agotarse. De eso se encarga upsmon, que se configura en /etc/nut/upsmon.conf. La línea clave es MONITOR, donde indicamos qué SAI vigilar y con qué usuario:

MONITOR ups@localhost 1 monitor ClavePorMonitor primary
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"
  • ups@localhost es el SAI a vigilar (nombre@servidor).
  • El 1 es el número de fuentes de alimentación que alimenta este SAI.
  • monitor y ClavePorMonitor son el usuario y la contraseña que definimos en upsd.users.
  • primary indica que este equipo es el que está conectado físicamente al SAI y el responsable de apagarlo.
  • SHUTDOWNCMD es el comando que se ejecutará cuando la batería esté crítica.

Además, upsmon puede ejecutar un script ante cada evento mediante NOTIFYCMD y los NOTIFYFLAG, muy útil para enviarnos un correo cuando se va la luz (evento ONBATT) o cuando vuelve (ONLINE):

NOTIFYCMD "/etc/nut/notify.sh"
NOTIFYFLAG ONBATT   SYSLOG+WALL+EXEC
NOTIFYFLAG ONLINE   SYSLOG+EXEC
NOTIFYFLAG LOWBATT  SYSLOG+WALL+EXEC

Panel web con PeaNUT

upsc está muy bien para la consola, pero para el día a día es más cómodo un panel gráfico. PeaNUT es un panel web ligero que se conecta a upsd y muestra el estado del SAI de forma visual. Lo desplegamos fácilmente con Docker.

Nota sobre la arquitectura ARM: al correr sobre una Raspberry Pi (aarch64) hay que usar imágenes de contenedor multiarquitectura. La imagen brandawg93/peanut publica variantes para arm64, por lo que Docker descargará automáticamente la correcta; no hay que hacer nada especial.

Creamos un docker-compose.yml para PeaNUT:

services:
  peanut:
    image: brandawg93/peanut:latest
    container_name: peanut
    restart: always
    ports:
      - 8087:8080
    environment:
      WEB_USERNAME: admin
      WEB_PASSWORD: ClaveWebPeaNUT

En la configuración de PeaNUT le indicamos la dirección del servidor upsd (host y puerto 3493). Levantamos el contenedor:

root@nut:~# docker compose up -d

Y accedemos con el navegador a la IP del servidor seguida del puerto 8087:

peanut-login

Una vez dentro, PeaNUT nos muestra un panel con el estado del SAI en tiempo real: el porcentaje de carga, una gráfica con las tensiones de entrada y salida, y el estado de la batería.

peanut-dashboard1

En este SAI los indicadores de “Carga de batería” y “Duración de la batería” aparecen como N/A. No es un error de configuración, sino una limitación del propio equipo: solo informa de la tensión de la batería (battery.voltage), pero no del porcentaje de carga ni de la autonomía estimada. Es algo habitual en los SAI más económicos.

Si bajamos en la página, PeaNUT lista además todas las variables que expone el SAI (las mismas que veíamos con upsc) en una cómoda tabla:

peanut-dashboard2

Prueba de funcionamiento

Para comprobar que el apagado seguro funciona, la forma más fiable es simular un corte real: desenchufamos la entrada de red del SAI. Al hacerlo, el estado cambia de OL a OB y upsmon dispara el evento ONBATT:

root@nut:~# upsc ups ups.status
OB

Si dejamos que la batería siga bajando, cuando llegue al umbral crítico el estado pasará a OB LB y upsmon ejecutará el SHUTDOWNCMD, apagando el equipo de forma ordenada. Al volver la corriente, el estado regresa a OL.

Con esto ya tenemos el SAI monitorizado con NUT en Debian 13, con apagado seguro ante cortes de luz y un cómodo panel web con PeaNUT para vigilarlo de un vistazo.