Problema

Los entornos auto‑alojados que combinan varios VPS, dispositivos locales y servicios críticos (bases de datos, agentes IA, stacks de trading) suelen optar por una topología hub‑and‑spoke basada en WireGuard. Cuando la red crece, aparecen tres patrones de falla recurrentes:

  1. Conexiones inter‑nodo inestables: la pérdida de un peer o la caída del hub corta el acceso a bases de datos y a los procesos de recolección.
  2. Backups que dejan de estar cifrados o no se replican: la ausencia de una capa de cifrado de disco y de un proceso de sincronización fiable expone datos sensibles.
  3. Superficie de ataque ampliada: sin filtros de tráfico, IDS/IPS y control de acceso, cualquier nodo comprometido puede convertirse en punto de salida para ataques externos.

El reto es diseñar una arquitectura que mantenga la conectividad, garantice el cifrado de repositorios y minimice la exposición a amenazas, sin depender de servicios de terceros.

Causa

1. Configuración de WireGuard sin redundancia

Un hub único actúa como punto de paso para todo el tráfico. Si el hub se reinicia o su firewall bloquea accidentalmente el puerto UDP, los spokes quedan aislados. La falta de rutas de fallback y de keep‑alive agresivo agrava la situación.

2. Cifrado de disco parcial o manual

Usar LUKS solo en el volumen raíz y dejar los datos de backup en discos sin cifrar crea un vector de fuga. Además, la apertura manual de vaults (por ejemplo con Cryptomator) rompe la automatización y genera ventanas de tiempo sin protección.

3. Falta de capas de detección y mitigación

Instalar únicamente un firewall básico permite tráfico no inspeccionado. Sin CrowdSec, Suricata o fail2ban, los intentos de fuerza bruta, escaneos de puertos o conexiones sospechosas pasan desapercibidos y pueden escalar rápidamente.

4. Ausencia de monitorización centralizada

Sin Netdata, Prometheus o alertas de n8n, los síntomas aparecen como caídas inesperadas en lugar de ser anticipados. La falta de métricas de latencia WireGuard y de uso de disco impide detectar cuellos de botella antes de que provoquen pérdida de datos.

Solución

1. Topología WireGuard con hub redundante y keep‑alive

  • Despliega dos hubs en regiones diferentes (por ejemplo LA y Frankfurt). Cada spoke mantiene peers simultáneos con ambos hubs.
  • Configura PersistentKeepalive = 25 en todos los peers para forzar paquetes de mantenimiento y detectar caídas rápidamente.
  • Usa rutas de fallback en la tabla de rutas del cliente: si la ruta a hub‑A falla, el tráfico se redirige automáticamente a hub‑B.

2. Cifrado de disco completo con LUKS2 y claves rotativas

  • Crea dos volúmenes LUKS por nodo: uno para el sistema y otro para datos de backup. Monta el segundo en /mnt/backup.
  • Genera una clave maestra en un vault de hardware (YubiKey o Nitrokey) y distribúyela mediante ssh‑agent forwarding solo a los procesos de backup.
  • Programa cryptsetup para abrir el volumen en el arranque usando un keyfile almacenado en un directorio root-only y protegido por chmod 0400.

3. Cadena de seguridad con CrowdSec → Suricata → fail2ban

  • Instala CrowdSec en el hub y en cada spoke. Configura los escenarios ssh-bf, wireguard-bruteforce y tor-exit para que envíen eventos a Suricata vía socket.
  • Suricata actúa como IDS/IPS en modo inline, aplicando reglas de ET PROTOCOLS y bloqueando tráfico sospechoso antes de que llegue al kernel.
  • fail2ban monitorea los logs de Suricata y CrowdSec, creando bans temporales en iptables para IPs que superen umbrales definidos.

4. Automatización de backups cifrados

  • Usa rsync + OpenSSL o restic para copiar bases de datos y archivos de configuración a /mnt/backup. Restic ya cifra los datos y gestiona snapshots.
  • Programa el job con systemd timer que se dispara cada 6 h, abre el vault LUKS, ejecuta el backup y cierra el volumen al terminar.
  • Replicación entre nodos mediante rclone sobre el túnel WireGuard, con la opción --crypt para una capa de cifrado adicional en tránsito.

5. Monitorización y alertas

  • Despliega Netdata en cada nodo y configura un dashboard central en el hub. Incluye métricas de wg0 (peers, handshake, transfer), uso de disco LUKS y eventos de CrowdSec.
  • Conecta n8n a los webhooks de Netdata y CrowdSec para enviar SMS vía Twilio cuando:
    • Un handshake WireGuard supera los 30 s.
    • Un backup falla o el volumen LUKS no se abre.
    • Suricata detecta una regla de alto riesgo.

Cuándo aplicar esta solución

  • Entornos multi‑VPS con datos sensibles (finanzas, IA, coleccionables) que requieren acceso constante desde varios puntos.
  • Políticas de cero confianza donde ningún nodo debe almacenar claves en texto plano.
  • Escenarios de alta disponibilidad donde la caída del hub no puede interrumpir la recolección de datos ni los procesos de trading.
  • No es necesario si la infraestructura es monolítica (un solo servidor) o si los datos no son críticos y pueden almacenarse en la nube sin cifrado adicional.

Código

# WireGuard peer configuration (spoke)
[Interface]
PrivateKey = <spoke_private_key>
Address = 10.10.10.2/32
DNS = 1.1.1.1

[Peer]
PublicKey = <hubA_public_key>
Endpoint = hubA.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25

[Peer]
PublicKey = <hubB_public_key>
Endpoint = hubB.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
# LUKS2 setup for backup volume
cryptsetup luksFormat /dev/sdb1 --type luks2
cryptsetup open /dev/sdb1 backup_crypt --key-file /root/backup.key
mkfs.ext4 /dev/mapper/backup_crypt
mount /dev/mapper/backup_crypt /mnt/backup
# Restic backup job (systemd service)
[Unit]
Description=Restic backup to encrypted LUKS volume
After=network-online.target

[Service]
Type=oneshot
ExecStartPre=/usr/bin/cryptsetup open /dev/sdb1 backup_crypt --key-file /root/backup.key
ExecStart=/usr/local/bin/restic -r /mnt/backup backup /var/lib/postgresql
ExecStartPost=/usr/bin/cryptsetup close backup_crypt

Verificación

  1. Conectividad WireGuard: wg show debe listar ambos peers con latest handshake reciente (menos de 30 s).
  2. Estado LUKS: lsblk -f muestra el volumen backup_crypt montado en /mnt/backup. Intentar desmontar sin cerrar la sesión (cryptsetup close) debe fallar.
  3. Backup exitoso: restic snapshots muestra un snapshot reciente con la hora programada.
  4. Alertas de seguridad: Genera un intento de conexión SSH fallido y verifica que crowdsec envía un evento a Suricata y que fail2ban crea un ban (iptables -L -n | grep <IP>).

Notas adicionales

  • Rotación de claves: programa una rotación trimestral de la keyfile LUKS mediante cryptsetup reencrypt --new-key-file.
  • TLS fingerprint: si usas impers para ocultar la huella TLS, asegúrate de que la lista de fingerprints esté sincronizada entre todos los peers; de lo contrario, el handshake fallará silenciosamente.
  • Tor como salida: cuando el hub egress pasa por un nodo Tor, verifica la latencia con curl --socks5-hostname <tor_ip>:9050 https://ifconfig.me. Si supera 300 ms, considera balancear tráfico crítico por una ruta directa.
  • Escalado de Suricata: en nodos con alta carga, habilita af-packet para evitar pérdidas de paquetes y ajusta max_pending_packets según la capacidad de la NIC.