Categorías

Tags

hardening – G-Project

Tag: hardening

  • n8n en self-hosting: hardening, backups y colas para producción

    n8n en self-hosting: hardening, backups y colas para producción

    Introducción

    El despliegue de n8n en infraestructura propia (self-hosting) es una decisión estratégica para equipos que requieren soberanía absoluta sobre sus datos, integraciones con redes internas y control granular sobre los costes de ejecución. Sin embargo, pasar de una instancia de desarrollo a un entorno de producción resiliente requiere abandonar la configuración por defecto basada en SQLite y ejecuciones en memoria.

    Para soportar cargas de trabajo intensivas, evitar la pérdida de datos y garantizar la disponibilidad, es necesario implementar una arquitectura distribuida, aplicar políticas de seguridad estrictas (hardening) y establecer rutinas de recuperación. Este artículo detalla cómo configurar n8n para producción utilizando Queue Mode, PostgreSQL, Redis y prácticas estándar de operaciones.

    Arquitectura para Producción: Queue Mode

    El modo de ejecución estándar de n8n procesa los flujos de trabajo en el mismo proceso de Node.js que sirve la interfaz de usuario. En producción, esto provoca cuellos de botella y caídas por falta de memoria (OOM). La solución es el Queue Mode (modo de colas), que separa las responsabilidades en diferentes procesos.

    Componentes necesarios

    Para escalar horizontalmente, la arquitectura se divide en:

    1. Nodo Principal (Main): Sirve la interfaz web, la API y gestiona la programación de tareas (cron, polling). Solo debe existir uno.
    2. Nodos Webhook: Procesos dedicados exclusivamente a recibir peticiones HTTP entrantes. Pueden escalar horizontalmente detrás de un balanceador de carga.
    3. Nodos Worker: Procesos en segundo plano que ejecutan el trabajo pesado. Consumen tareas de la cola y pueden escalar según la demanda.
    4. Redis: Actúa como el broker de mensajes (cola) que comunica el nodo principal/webhook con los workers.
    5. PostgreSQL: Base de datos centralizada que almacena credenciales, flujos, historial de ejecuciones y usuarios.

    Configuración de variables de entorno

    Para activar esta arquitectura, debes configurar las siguientes variables de entorno en tus contenedores Docker. A continuación, un ejemplo de las variables clave para cada tipo de nodo:

    Para todos los nodos (Main, Webhook, Worker):

    # Base de datos
    DB_TYPE=postgresdb
    DB_POSTGRESDB_DATABASE=n8n
    DB_POSTGRESDB_HOST=postgres
    DB_POSTGRESDB_PORT=5432
    DB_POSTGRESDB_USER=n8n_user
    DB_POSTGRESDB_PASSWORD=tu_password_seguro

    Broker de colas

    EXECUTIONS_MODE=queue QUEUE_BULL_REDIS_HOST=redis QUEUE_BULL_REDIS_PORT=6379 QUEUE_BULL_REDIS_PASSWORD=tu_redis_password

    Específico para el nodo Webhook:

    WEBHOOK_URL=https://n8n.tudominio.com
    # Indica que este proceso solo actúa como webhook
    N8N_HOST=n8n.tudominio.com
    

    El comando de inicio en Docker para los workers debe ser worker, y para los webhooks webhook. El nodo principal arranca con el comando por defecto.

    Hardening y Seguridad

    Una instancia de n8n en producción maneja credenciales de múltiples servicios de terceros. Proteger esta información y el acceso a la plataforma es crítico.

    Gestión de credenciales y encriptación

    n8n encripta las credenciales en la base de datos utilizando una clave secreta. Si pierdes esta clave, perderás el acceso a todas las cuentas conectadas.

    Debes definir estáticamente la variable N8N_ENCRYPTION_KEY con una cadena criptográficamente segura (por ejemplo, generada con openssl rand -hex 32). Nunca dejes que n8n genere esta clave dinámicamente en producción, ya que un reinicio del contenedor sin persistencia de archivos invalidaría todas tus credenciales.

    N8N_ENCRYPTION_KEY=d8f9...[cadena_de_64_caracteres]...3a2b
    

    Restricción de red y proxy inverso

    Nunca expongas los puertos de n8n (5678) directamente a Internet. Utiliza un proxy inverso como Nginx, Traefik o Caddy para gestionar la terminación SSL/TLS y filtrar el tráfico.

    Si utilizas nodos Webhook dedicados, configura tu proxy inverso para enrutar el tráfico de la siguiente manera:

    • Rutas /webhook/* y /webhook-test/* -> Balanceador de carga de los nodos Webhook.
    • Resto del tráfico (/, /rest/*, etc.) -> Nodo Principal.

    Además, bloquea el acceso a la interfaz web desde IPs públicas si tu equipo opera bajo una VPN corporativa. Solo las rutas de webhooks deben ser accesibles públicamente.

    Control de ejecución y aislamiento

    Por defecto, n8n permite ejecutar comandos del sistema (nodo Execute Command) y escribir en el sistema de archivos. En un entorno endurecido, debes restringir esto:

    # Deshabilitar nodos peligrosos si no son estrictamente necesarios
    NODES_EXCLUDE=n8n-nodes-base.executeCommand

    Restringir el acceso al sistema de archivos

    N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true

    Estrategia de Backups y Persistencia

    La persistencia en n8n se divide en dos áreas: la base de datos relacional (PostgreSQL) y los archivos estáticos (si utilizas nodos de lectura/escritura de archivos locales).

    Respaldo de la base de datos (PostgreSQL)

    El método más fiable para respaldar n8n es realizar volcados regulares de la base de datos PostgreSQL. Esto captura usuarios, flujos, credenciales encriptadas y el historial de ejecución.

    Configura un cron job en una máquina segura o utiliza un sidecar container para ejecutar pg_dump diariamente:

    #!/bin/bash
    FECHA=$(date +%Y%m%d_%H%M%S)
    ARCHIVO_BACKUP="/backups/n8n_db_$FECHA.sql.gz"

    PGPASSWORD="tu_password_seguro" pg_dump -h postgres -U n8n_user -d n8n | gzip > $ARCHIVO_BACKUP

    Eliminar backups más antiguos de 30 días

    find /backups/ -type f -name "*.sql.gz" -mtime +30 -exec rm {} ;

    Exportación de workflows vía CLI

    Como capa adicional de seguridad y para facilitar el control de versiones (Git), es recomendable exportar los flujos de trabajo en formato JSON de forma regular utilizando la CLI de n8n. Esto permite restaurar flujos individuales sin tener que restaurar toda la base de datos.

    En el nodo principal, puedes ejecutar:

    docker exec -it n8n-main n8n export:workflow --all --output=/backups/workflows/
    docker exec -it n8n-main n8n export:credentials --all --output=/backups/credentials/ --decrypted
    

    Nota: La exportación de credenciales desencriptadas (--decrypted) es un riesgo de seguridad masivo. Solo debe hacerse en entornos altamente controlados y los archivos resultantes deben ser encriptados inmediatamente (por ejemplo, con GPG o SOPS).

    Limpieza de datos históricos (Pruning)

    Una base de datos de n8n sin mantenimiento crecerá indefinidamente debido al historial de ejecuciones, degradando el rendimiento. Configura la limpieza automática mediante variables de entorno en el nodo principal:

    # Mantener solo las ejecuciones fallidas o las recientes
    EXECUTIONS_DATA_PRUNE=true
    EXECUTIONS_DATA_MAX_AGE=168 # Horas (7 días)
    EXECUTIONS_DATA_PRUNE_MAX_COUNT=50000
    

    Monitorización y Recuperación ante Fallos

    Para garantizar el tiempo de actividad, debes saber qué ocurre dentro de tu instancia antes de que los usuarios reporten fallos.

    Health checks y métricas

    n8n expone endpoints de salud que deben ser consumidos por tu orquestador (Docker Swarm, Kubernetes) o balanceador de carga para reiniciar contenedores bloqueados.

    • /healthz: Devuelve 200 OK si el servicio está levantado.

    Para monitorización avanzada, habilita el endpoint de Prometheus. Esto te permitirá visualizar en Grafana métricas clave como el número de ejecuciones activas, uso de memoria y tasa de errores.

    N8N_METRICS=true
    N8N_METRICS_PREFIX=n8n_
    

    Gestión de memoria y timeouts

    Los flujos de trabajo mal diseñados (por ejemplo, bucles infinitos o procesamiento de archivos masivos en memoria) pueden tumbar un worker. Para mitigar esto, establece límites estrictos de tiempo de ejecución y gestiona la memoria de Node.js.

    # Forzar el timeout de ejecuciones atascadas (en segundos)
    EXECUTIONS_TIMEOUT=3600
    EXECUTIONS_TIMEOUT_MAX=7200

    Configurar el límite de memoria de V8 (Node.js) para los workers (ej. 2GB)

    NODE_OPTIONS="--max-old-space-size=2048"

    Conclusión

    Desplegar n8n en producción requiere tratarlo como cualquier otra pieza crítica de infraestructura backend. La transición al Queue Mode con Redis y PostgreSQL elimina los problemas de concurrencia, mientras que una política estricta de variables de entorno y proxy inverso asegura la plataforma. Combinando esto con rutinas de backup automatizadas mediante pg_dump y la CLI de n8n, obtendrás un motor de automatización robusto, escalable y preparado para integraciones de nivel empresarial.