Problema

En infraestructuras con varios nodos Proxmox y varios servidores de backup (PBS), mantener todos los dispositivos encendidos todo el tiempo genera un consumo energético innecesario y aumenta la superficie de ataque. La solución típica consiste en usar Wake‑on‑LAN (WoL) para encender los PBS justo antes de iniciar los trabajos de copia y apagarlos al terminar. Cuando se añaden más hosts y rutas de backup, la coordinación se vuelve compleja:

  • Cada PBS puede ser requerido por varios hosts a distintas horas.
  • Los trabajos de sincronización entre PBS (replicación off‑site) también necesitan una ventana de encendido.
  • Los administradores suelen mezclar scripts de hook, cron y API, lo que genera condiciones de carrera y servidores que permanecen encendidos por error.
  • La gestión de credenciales (contraseñas vs. tokens) y los permisos de SSH pueden quedar demasiado amplios, comprometiendo la seguridad.

El patrón que surge es “encendido/apagado manual o parcialmente automatizado que no escala”, donde la falta de una capa de orquestación provoca desperdicio de recursos y fallos intermitentes en los backups.

Causa

  1. Ausencia de un plano de rutas centralizado – Cada host conoce solo sus propios backups; no hay un registro único que indique cuándo un PBS debe estar activo para atender a varios orígenes simultáneamente.
  2. Uso de cron o systemd en cada nodo – Los disparadores locales no comparten estado, de modo que dos nodos pueden lanzar WoL al mismo tiempo sin saber que el otro ya lo hizo, o peor, que el PBS ya está encendido por otra ruta.
  3. Credenciales de superusuario – Claves SSH sin restricciones permiten ejecutar cualquier comando, lo que dificulta auditar quién apagó o encendió el servidor.
  4. Falta de monitorización de actividad – Sin un endpoint que indique “PBS idle”, los scripts de apagado pueden dispararse antes de que termine una replicación o una verificación de integridad.
  5. Configuraciones estáticas – Cambios en la topología (nuevo host, nuevo PBS) requieren edición manual de varios archivos, lo que genera inconsistencias.

Solución

Implementar una capa ligera de orquestación que:

  1. Defina rutas de backup – Un archivo JSON/YAML que describa cada flujo: origen(es) Proxmox, destino PBS, ventana horaria, días de la semana y política de retención.
  2. Centralice la lógica de encendido/apagado – Un único daemon (por ejemplo, escrito en Go o Python) que lea las rutas, calcule el próximo “wake window” y envíe paquetes WoL solo una vez por PBS, sin importar cuántas rutas lo necesiten.
  3. Utilice API tokens con alcance limitado – En lugar de contraseñas, generar tokens de API de Proxmox con permisos de lectura de VM y creación de snapshots; para el apagado, una clave SSH restringida a sudo /sbin/poweroff en el PBS.
  4. Exposición de métricas – Endpoint Prometheus que informe estado de cada PBS (on/off, próxima ventana, última ejecución). Esto permite crear alertas en Grafana o Home‑Assistant.
  5. Modo “External” – Cuando el cliente ya gestiona los horarios de backup mediante hooks, la orquestación solo vigila la actividad (por ejemplo, consultas a la API de PBS) y apaga el servidor cuando no hay tareas en cola.
  6. Verificación programada – Ruta de tipo “Verify” que ejecuta pbs restore --dry-run o pbs verify para asegurar que los datos almacenados son recuperables, sin necesidad de encender el servidor si ya está activo.

Arquitectura mínima

+-------------------+        +-------------------+
| Proxmox Host A    |        | Proxmox Host B    |
| (API)             |        | (API)             |
+--------+----------+        +----------+--------+
         |                               |
         |  JSON route definition        |
         +------------+------------------+
                      |
               +------+------+
               | Orquestador |
               | (Docker)    |
               +------+------+
                      |
          +-----------+-----------+
          |                       |
   +------+------+          +-----+------+
   | PBS 1 (WoL) |          | PBS 2 (WoL)|
   +------+------|          +-----+------+
          |                       |
   (SSH poweroff)           (SSH poweroff)

El orquestador se ejecuta en un contenedor aislado; su única interacción externa es el envío de paquetes WoL (UDP 9) y la ejecución de ssh con la clave restringida.

Cuándo aplicar esta solución

Se recomienda cuando:

  • Hay más de un nodo Proxmox que necesita respaldar en el mismo PBS.
  • Se desea replicar backups entre varios PBS (off‑site) y no se quiere mantener todos encendidos todo el tiempo.
  • Los horarios de backup no son idénticos entre hosts, pero comparten ventanas que pueden consolidarse.
  • Se busca reducir la superficie de ataque limitando credenciales a comandos concretos.
  • Se necesita visibilidad centralizada (Prometheus, Grafana) del estado de los PBS.

No es necesario si:

  • Solo existe un único host y un único PBS, y el consumo energético no es crítico.
  • La infraestructura ya usa una solución comercial que incluye gestión de energía.
  • No se dispone de acceso a la API de Proxmox (por ejemplo, en entornos SaaS sin control).

Código

# Wake on LAN para un PBS específico
etherwake -i eth0 00:11:22:33:44:55

# Apagado seguro vía SSH con clave restringida
ssh -i /etc/ssh/keys/pbs_poweroff.key \
    -o StrictHostKeyChecking=no \
    root@pbs01 "sudo /sbin/poweroff"

Ejemplo de definición de ruta en YAML (puede almacenarse en /etc/joulenap/routes.yaml):

routes:
  - name: "backup-prod"
    type: "backup"
    hosts: ["pve01", "pve02"]
    target: "pbs01"
    schedule: "02:00"
    days: ["mon","wed","fri"]
    retention: "30d"
  - name: "sync-offsite"
    type: "sync"
    source: "pbs01"
    destination: "pbs02"
    direction: "push"
    schedule: "04:00"
    days: ["sun"]
  - name: "external-monitor"
    type: "external"
    target: "pbs02"
    schedule: "00:00"
    idle_timeout: "15m"
  - name: "verify-backups"
    type: "verify"
    target: "pbs01"
    schedule: "03:30"
    days: ["tue","thu"]

El orquestador lee este archivo, agrupa por target y calcula la ventana más temprana que cubra todas las rutas asociadas. En el caso de external-monitor, simplemente vigila la cola de trabajos mediante la API de PBS y ejecuta el apagado cuando la cola está vacía durante el tiempo configurado.


## Verificación
1. **Comprobar que el PBS se despierta** – Después de que el orquestador envíe el paquete WoL, ejecutar `ping -c 3 pbs01` y validar que responde.  
2. **Revisar métricas** – Acceder a `http://orquestador:9100/metrics` y buscar `pbs_up{target="pbs01"} 1`.  
3. **Ejecutar una copia de prueba** – Lanzar manualmente un backup desde uno de los hosts y observar que el orquestador no envía un segundo WoL.  
4. **Verificar apagado** – Tras la finalización del trabajo, confirmar que `ssh root@pbs01 "systemctl is-active poweroff.target"` devuelve `inactive` y que el host deja de responder al ping.  
5. **Chequear logs** – El contenedor del orquestador escribe en stdout; buscar líneas como `INFO wake sent to 00:11:22:33:44:55` y `INFO poweroff executed on pbs01`.

## Notas adicionales
* **Sincronización de relojes** – WoL depende de que la BIOS del PBS tenga la hora correcta; usar NTP en los servidores de gestión evita que la ventana calculada quede desfasada.  
* **Redes VLAN** – Si los PBS están en una VLAN distinta, asegúrate de que el switch permite el broadcast UDP 9 o configura un proxy WoL en la VLAN de origen.  
* **Limitar intentos** – El orquestador debería reintentar el WoL un máximo de tres veces con intervalos de 30 s; después, marcar la ruta como fallida y enviar una alerta.  
* **Escalabilidad** – Para cientos de PBS, considera almacenar las rutas en una base de datos ligera (SQLite) y exponer una API REST que permita añadir o modificar rutas sin reiniciar el contenedor.  
* **Seguridad de la clave SSH** – Genera la clave con `ssh-keygen -t ed25519 -f pbs_poweroff.key -N ""` y en el `authorized_keys` del PBS usa `command="/sbin/poweroff",no-port-forwarding,no-agent-forwarding,no-pty`.  

Con esta arquitectura, los entornos Proxmox con múltiples hosts y servidores de backup pueden mantener sus PBS apagados la mayor parte del tiempo, reducir costos energéticos y mantener una superficie de ataque mínima, sin sacrificar la fiabilidad de los backups.