Monitorización de UPS con NUT en Linux
NUT (Network UPS Tools) es la solución estándar en Linux para monitorizar SAIs/UPS (Sistemas de Alimentación Ininterrumpida) y configurar apagados automáticos ante fallos de alimentación, protegiendo los datos y el hardware del servidor. Esta guía cubre la configuración del driver, los modos de monitorización, los scripts de apagado, el compartir el UPS en red y las alertas.
Requisitos Previos
- Ubuntu 20.04/22.04 o Debian 11/12 / CentOS 7/8
- UPS conectado al servidor via USB, serial o SNMP
- Acceso root
- Para UPS en red: puerto TCP 3493 disponible
# Verificar que el UPS está conectado por USB
lsusb | grep -iE "ups|apc|eaton|cyberpower|powerware"
# Ver los dispositivos USB conectados con más detalle
lsusb -v 2>/dev/null | grep -iE "ups|apc|eaton"
Instalación de NUT
# Ubuntu/Debian
apt update
apt install -y nut nut-client nut-server
# CentOS/Rocky Linux
dnf install -y nut nut-client
# Verificar la instalación
upsc --version
# Ver los drivers disponibles en NUT
ls /lib/nut/ | grep drv
# El directorio de configuración de NUT
ls /etc/nut/
# nut.conf ups.conf upsd.conf upsd.users upsmon.conf
Detección y Configuración del Driver
# Escanear automáticamente los UPS conectados
nut-scanner -U # Escaneo USB
nut-scanner -S # Escaneo SNMP (en red)
nut-scanner -a # Escaneo completo
# La salida sugiere la configuración correcta:
# [ups]
# driver = usbhid-ups
# port = auto
# vendorid = 051D
# productid = 0002
# Configurar el driver en /etc/nut/ups.conf
cat << 'EOF' > /etc/nut/ups.conf
# Definición del UPS
# APC Back-UPS por USB
[mi-ups]
driver = usbhid-ups
port = auto
desc = "APC Back-UPS 1500VA"
# Opcional: especificar el serial si hay múltiples UPS
# serial = XXXXXXXXX
# Para UPS APC más antiguos que usan el driver apcsmart (comunicación serial)
# [mi-ups-serial]
# driver = apcsmart
# port = /dev/ttyS0
# desc = "APC Smart-UPS 1500"
# Para UPS Eaton con comunicación USB
# [ups-eaton]
# driver = usbhid-ups
# port = auto
# vendorid = 0463
# Para UPS via SNMP (en red)
# [ups-snmp]
# driver = snmp-ups
# port = 192.168.1.200
# snmp_version = v2c
# community = public
# desc = "UPS APC via SNMP"
EOF
# Probar que el driver puede comunicarse con el UPS
upsdrvctl start
# Ver los datos actuales del UPS
upsc mi-ups
# Ver todas las variables del UPS
upsc mi-ups@localhost
Configuración del Servidor NUT
# Configurar el modo de operación de NUT
cat << 'EOF' > /etc/nut/nut.conf
# Modo de operación de NUT:
# standalone: un UPS conectado localmente, monitorizado localmente
# netserver: UPS local, compartido con otros sistemas en la red
# netclient: sin UPS local, monitoriza un UPS remoto
MODE=standalone
EOF
# Configurar el servidor NUT (upsd)
cat << 'EOF' > /etc/nut/upsd.conf
# Configuración del servidor de datos NUT
# Escuchar en localhost (modo standalone)
LISTEN 127.0.0.1 3493
# Para compartir con la red:
# LISTEN 0.0.0.0 3493
# Máximas conexiones de clientes
MAXCONN 15
EOF
# Configurar los usuarios de NUT
cat << 'EOF' > /etc/nut/upsd.users
[admin]
password = ContraseñaAdmin
actions = SET
instcmds = ALL
[monitor]
password = ContraseñaMonitor
upsmon master
EOF
chmod 640 /etc/nut/upsd.users
# Iniciar los servicios NUT
systemctl enable nut-server nut-monitor
systemctl start nut-server nut-monitor
# Verificar el estado
systemctl status nut-server nut-monitor
# Verificar la conexión al UPS
upsc mi-ups@localhost
Modos de Monitorización
# Configurar el cliente de monitorización (upsmon)
cat << 'EOF' > /etc/nut/upsmon.conf
# Definición del UPS a monitorizar
# Formato: MONITOR <ups>@<host> <powervalues> <username> <password> <type>
MONITOR mi-ups@localhost 1 monitor ContraseñaMonitor master
# Número mínimo de fuentes de alimentación requeridas (importante en servidores con doble fuente)
MINSUPPLIES 1
# Tiempo de espera antes del apagado (segundos) después de recibir LOWBATT
FINALDELAY 5
# Número de segundos entre polls del estado del UPS
POLLFREQ 5
# Número de segundos entre polls cuando el UPS está en modo de fallo
POLLFREQALERT 5
# Script a ejecutar para notificaciones
NOTIFYCMD /etc/nut/notifyme.sh
# Comandos de apagado
SHUTDOWNCMD "/sbin/shutdown -h +0"
# Notificaciones a enviar
NOTIFYMSG ONLINE "El UPS %s ha recuperado la alimentación"
NOTIFYMSG ONBATT "El UPS %s está funcionando con batería"
NOTIFYMSG LOWBATT "CRÍTICO: Batería baja en el UPS %s - iniciando apagado"
NOTIFYMSG FSD "Apagado forzado por el UPS %s"
NOTIFYMSG COMMOK "Comunicación restablecida con el UPS %s"
NOTIFYMSG COMMBAD "ALERTA: Pérdida de comunicación con el UPS %s"
NOTIFYMSG SHUTDOWN "Iniciando apagado del sistema por el UPS %s"
NOTIFYMSG REPLBATT "La batería del UPS %s necesita ser reemplazada"
NOTIFYMSG NOCOMM "El UPS %s no está disponible"
# Configurar qué notificaciones activan el script
NOTIFYFLAG ONLINE SYSLOG+WALL
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT SYSLOG+WALL+EXEC
NOTIFYFLAG FSD SYSLOG+WALL+EXEC
NOTIFYFLAG COMMOK SYSLOG+WALL
NOTIFYFLAG COMMBAD SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+WALL
NOTIFYFLAG REPLBATT SYSLOG+WALL+EXEC
EOF
Scripts de Apagado Automático
# Script de notificación personalizado
cat << 'EOF' > /etc/nut/notifyme.sh
#!/bin/bash
# Script de notificación de eventos UPS
MENSAJE="$1"
FECHA=$(date '+%Y-%m-%d %H:%M:%S')
EMAIL="[email protected]"
HOSTNAME=$(hostname)
# Registrar el evento en el log
echo "${FECHA}: ${MENSAJE}" >> /var/log/nut-events.log
# Enviar email para eventos críticos
case "$NOTIFYTYPE" in
ONBATT|LOWBATT|FSD|COMMBAD|REPLBATT)
echo "Evento UPS en ${HOSTNAME}: ${MENSAJE}" | \
mail -s "[UPS ${NOTIFYTYPE}] ${HOSTNAME}" "$EMAIL"
;;
esac
EOF
chmod +x /etc/nut/notifyme.sh
# Script de apagado ordenado con gracia
cat << 'EOF' > /usr/local/bin/graceful-shutdown-on-ups.sh
#!/bin/bash
# Apagado ordenado cuando el UPS tiene batería baja
# Registrar el inicio del apagado
logger -t UPS-Shutdown "Iniciando apagado ordenado por batería baja del UPS"
# Notificar a los usuarios activos
wall "ATENCIÓN: El sistema se apagará en 60 segundos por fallo de energía (UPS batería baja)"
# Esperar 60 segundos para dar tiempo a guardar el trabajo
sleep 60
# Sincronizar el sistema de archivos
sync
# Apagar el sistema
shutdown -h now "Apagado por UPS - batería baja"
EOF
chmod +x /usr/local/bin/graceful-shutdown-on-ups.sh
Compartir el UPS en Red
Cuando múltiples servidores deben apagarse con el mismo UPS:
# En el servidor con el UPS conectado (servidor maestro):
# Editar /etc/nut/nut.conf
echo "MODE=netserver" > /etc/nut/nut.conf
# Editar /etc/nut/upsd.conf para escuchar en la red
cat << 'EOF' > /etc/nut/upsd.conf
# Escuchar en todas las interfaces (o especificar la IP de gestión)
LISTEN 0.0.0.0 3493
MAXCONN 15
EOF
# Añadir usuario para los clientes esclavos
cat << 'EOF' >> /etc/nut/upsd.users
[esclavo]
password = ContraseñaEsclavo
upsmon slave
EOF
# Abrir el firewall para NUT
ufw allow 3493/tcp comment "NUT UPS Server"
# Reiniciar los servicios
systemctl restart nut-server nut-monitor
# En cada servidor cliente (esclavo):
cat << 'EOF' > /etc/nut/nut.conf
MODE=netclient
EOF
cat << 'EOF' > /etc/nut/upsmon.conf
# Monitorizar el UPS en el servidor maestro
MONITOR [email protected] 1 esclavo ContraseñaEsclavo slave
MINSUPPLIES 1
FINALDELAY 5
SHUTDOWNCMD "/sbin/shutdown -h +0"
EOF
systemctl restart nut-monitor
Alertas y Notificaciones
# Ver el estado actual del UPS
upsc mi-ups@localhost
# Variables importantes a monitorizar:
# ups.status: OL (online), OB (on battery), LB (low battery)
# battery.charge: porcentaje de carga de la batería
# battery.runtime: tiempo restante estimado en segundos
# input.voltage: voltaje de entrada
# output.voltage: voltaje de salida
# Script para integración con Nagios/NRPE
cat << 'EOF' > /usr/lib/nagios/plugins/check_nut_ups.sh
#!/bin/bash
# Plugin Nagios para monitorizar el estado del UPS con NUT
UPS=${1:-"mi-ups@localhost"}
STATUS=$(upsc $UPS ups.status 2>/dev/null)
BATTERY=$(upsc $UPS battery.charge 2>/dev/null)
RUNTIME=$(upsc $UPS battery.runtime 2>/dev/null)
if [ -z "$STATUS" ]; then
echo "CRITICAL: No se puede conectar al UPS $UPS"
exit 2
fi
if echo "$STATUS" | grep -q "LB"; then
echo "CRITICAL: UPS batería baja! Estado: $STATUS, Batería: ${BATTERY}%, Tiempo restante: ${RUNTIME}s"
exit 2
elif echo "$STATUS" | grep -q "OB"; then
echo "WARNING: UPS en batería! Estado: $STATUS, Batería: ${BATTERY}%, Tiempo restante: ${RUNTIME}s"
exit 1
else
echo "OK: UPS online. Estado: $STATUS, Batería: ${BATTERY}%, Tiempo restante: ${RUNTIME}s"
exit 0
fi
EOF
chmod +x /usr/lib/nagios/plugins/check_nut_ups.sh
Solución de Problemas
# El driver no puede conectar al UPS
upsdrvctl start 2>&1
# Verificar permisos del dispositivo USB
ls -la /dev/bus/usb/$(lsusb | grep -i ups | awk '{print $2}' | head -1)/
# Añadir regla udev para permisos correctos
cat << 'EOF' > /etc/udev/rules.d/52-nut-ups.rules
# Dar permisos de lectura/escritura al grupo nut para el UPS APC
SUBSYSTEM=="usb", ATTR{idVendor}=="051d", ATTR{idProduct}=="0002", \
GROUP="nut", MODE="0664"
EOF
udevadm control --reload-rules
udevadm trigger
# Verificar los logs de NUT
journalctl -u nut-server -f
journalctl -u nut-monitor -f
cat /var/log/syslog | grep NUT
# Verificar la comunicación con el driver
upsdrvctl -D start mi-ups
# Verificar el estado de la batería
upsc mi-ups battery.charge
upsc mi-ups battery.runtime
# Error "Access denied" al ejecutar upsc
# Verificar los usuarios en upsd.users
grep -v "^#" /etc/nut/upsd.users
Conclusión
NUT proporciona una solución completa y fiable para la gestión de UPS en servidores Linux, garantizando que los sistemas se apagarán de forma ordenada antes de que la batería se agote completamente. La configuración de múltiples servidores monitorizando un único UPS a través de la red permite proteger toda una infraestructura de servidores con un solo dispositivo UPS. Mantener actualizado el firmware del UPS y revisar periódicamente la capacidad de la batería (las baterías de plomo-ácido duran entre 3-5 años) son prácticas esenciales para garantizar la efectividad de la protección.


