Torna al Blog
Tutorial

Audit di sicurezza n8n: checklist per proteggere la tua istanza

Checklist pratica e completa per mettere in sicurezza la tua istanza n8n: reverse proxy, SSL, autenticazione, rate limiting, crittografia credenziali e backup.

Team n8n.it- Specialisti in Automazione30 marzo 20269 min read
Audit di sicurezza n8n: checklist per proteggere la tua istanza

Perché la sicurezza di n8n è fondamentale?

La tua istanza n8n contiene alcune delle informazioni più sensibili della tua azienda: credenziali API, token di accesso, webhook endpoint e logiche di business. Una compromissione non significa solo che qualcuno vede i tuoi workflow, significa che ha accesso a tutti i servizi collegati: CRM, email, database, sistemi di pagamento.

Questa guida è una checklist pratica, ordinata per priorità, che puoi seguire passo-passo per verificare e migliorare la sicurezza della tua istanza n8n.

Quali azioni di sicurezza fare immediatamente?

1.1 Reverse proxy con Nginx

Mai esporre n8n direttamente su internet. Il server web integrato in n8n non è progettato per gestire traffico diretto. Usa Nginx come reverse proxy.

Configurazione base di Nginx per n8n:

server {
    listen 80;
    server_name n8n.tuodominio.it;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name n8n.tuodominio.it;

    ssl_certificate /etc/letsencrypt/live/n8n.tuodominio.it/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/n8n.tuodominio.it/privkey.pem;

    # Header di sicurezza
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" always;

    # Limita dimensione upload
    client_max_body_size 16M;

    # Timeout per webhook lunghi
    proxy_read_timeout 300s;
    proxy_connect_timeout 60s;

    location / {
        proxy_pass http://127.0.0.1:5678;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WebSocket support (per l'editor)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Checklist:

  • Nginx installato e configurato come reverse proxy
  • Redirect HTTP -> HTTPS attivo
  • Header di sicurezza impostati
  • WebSocket configurato per l'editor
  • client_max_body_size limitato

1.2 SSL/TLS con Let's Encrypt

Il certificato SSL è obbligatorio, non opzionale:

# Installa Certbot
apt install certbot python3-certbot-nginx

# Ottieni certificato
certbot --nginx -d n8n.tuodominio.it

# Verifica rinnovo automatico
certbot renew --dry-run

# Cron per rinnovo (aggiunto automaticamente da Certbot)
# 0 12 * * * /usr/bin/certbot renew --quiet

Checklist:

  • Certificato SSL attivo e valido
  • Rinnovo automatico configurato e testato
  • Solo TLS 1.2+ permesso (TLS 1.0 e 1.1 disabilitati)

1.3 Autenticazione

n8n supporta diversi metodi di autenticazione. Come minimo, configura username e password:

# .env di n8n
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin_tuo_nome
N8N_BASIC_AUTH_PASSWORD=password_molto_lunga_e_complessa_32_caratteri_minimo

Regole per la password:

  • Minimo 32 caratteri
  • Generata con un password manager (non inventata)
  • Mai riutilizzata da altri servizi
  • Cambiata ogni 90 giorni

Per team con più utenti, configura l'autenticazione LDAP o SAML (disponibile nei piani enterprise).

Checklist:

  • Autenticazione attiva (non accessibile senza login)
  • Password forte (32+ caratteri, generata casualmente)
  • Password diversa da quelle usate altrove

1.4 Crittografia delle credenziali

n8n cripta le credenziali salvate con una chiave di cifratura. Assicurati che sia impostata correttamente:

# Genera una chiave di cifratura casuale
N8N_ENCRYPTION_KEY=chiave_casuale_generata_con_openssl_rand_hex_32

Per generare una chiave sicura:

openssl rand -hex 32

Attenzione: se perdi questa chiave, perdi l'accesso a tutte le credenziali salvate in n8n. Conservala in un posto sicuro (password manager, vault) separato dal server.

Checklist:

  • N8N_ENCRYPTION_KEY impostata con chiave casuale
  • Chiave salvata in un luogo sicuro separato dal server
  • File .env con permessi 600 (solo owner)

Quali protezioni attivare nella prima settimana?

2.1 Rate limiting su Nginx

Proteggi n8n da brute force e abuso dei webhook:

# Nella sezione http {} di nginx.conf
limit_req_zone $binary_remote_addr zone=n8n_general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=n8n_webhook:10m rate=30r/s;
limit_req_zone $binary_remote_addr zone=n8n_auth:10m rate=3r/m;

# Nel server block di n8n
server {
    # ... configurazione SSL ...

    # Rate limit per login
    location /rest/login {
        limit_req zone=n8n_auth burst=5 nodelay;
        proxy_pass http://127.0.0.1:5678;
        # ... proxy headers ...
    }

    # Rate limit per webhook
    location /webhook/ {
        limit_req zone=n8n_webhook burst=50 nodelay;
        proxy_pass http://127.0.0.1:5678;
        # ... proxy headers ...
    }

    # Rate limit generale
    location / {
        limit_req zone=n8n_general burst=20 nodelay;
        proxy_pass http://127.0.0.1:5678;
        # ... proxy headers ...
    }
}

Checklist:

  • Rate limiting attivo per endpoint di login (max 3/minuto)
  • Rate limiting attivo per webhook (max 30/secondo)
  • Rate limiting generale (max 10/secondo)

2.2 Fail2ban per blocco IP

Installa fail2ban per bloccare automaticamente IP che tentano brute force:

apt install fail2ban

Crea un filtro per n8n in /etc/fail2ban/filter.d/n8n.conf:

[Definition]
failregex = ^<HOST> .* "POST /rest/login HTTP.*" 401
ignoreregex =

E il jail in /etc/fail2ban/jail.d/n8n.conf:

[n8n]
enabled = true
port = http,https
filter = n8n
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 600
bantime = 3600

Checklist:

  • fail2ban installato e attivo
  • Filtro per n8n configurato
  • Ban automatico dopo 5 tentativi falliti

2.3 Firewall (UFW)

Configura il firewall per permettere solo il traffico necessario:

# Reset e configura
ufw default deny incoming
ufw default allow outgoing

# Permetti SSH (cambia porta se diversa)
ufw allow 22/tcp

# Permetti HTTP/HTTPS
ufw allow 80/tcp
ufw allow 443/tcp

# Attiva
ufw enable

# Verifica
ufw status verbose

Importante: n8n sulla porta 5678 non deve essere accessibile dall'esterno. Solo Nginx (porta 80/443) deve essere esposto.

Checklist:

  • UFW attivo con policy deny-by-default
  • Solo porte 22, 80, 443 aperte
  • Porta 5678 NON accessibile dall'esterno

2.4 Variabili d'ambiente sicure

Non inserire mai credenziali direttamente nei workflow. Usa le variabili d'ambiente di n8n:

# .env
N8N_EXTERNAL_STORAGE_S3_ACCESS_KEY=AKIA...
N8N_EXTERNAL_STORAGE_S3_SECRET_KEY=secret...

# Oppure usa Docker secrets
docker secret create n8n_encryption_key ./encryption_key.txt

Checklist:

  • Nessuna credenziale hardcoded nei workflow
  • File .env con permessi 600
  • Docker secrets per dati sensibili (se usi Docker Swarm)

Quali misure di hardening avanzato implementare?

3.1 Sicurezza dei webhook

I webhook sono l'endpoint più esposto della tua istanza n8n. Proteggili:

Usa webhook con autenticazione header:

URL: https://n8n.tuodominio.it/webhook/ordini-woocommerce
Header: X-Webhook-Secret: token_segreto_generato_casualmente

Nel workflow n8n, aggiungi un nodo IF che verifica l'header:

// Nel nodo Function/Code
const expectedSecret = $env.WEBHOOK_SECRET_WOOCOMMERCE;
const receivedSecret = $input.first().headers['x-webhook-secret'];

if (receivedSecret !== expectedSecret) {
  throw new Error('Webhook non autorizzato');
}

Usa URL non prevedibili:

SBAGLIATO: /webhook/ordini
GIUSTO:    /webhook/a7f3b2c1-ordini-9d4e

Checklist:

  • Ogni webhook ha autenticazione (header secret o HMAC)
  • URL webhook non prevedibili
  • Validazione del payload nel workflow

3.2 Aggiornamenti regolari

n8n rilascia aggiornamenti frequenti che includono fix di sicurezza:

# Con Docker Compose
docker compose pull
docker compose up -d

# Verifica versione
docker exec n8n n8n --version

Checklist:

  • Procedura di aggiornamento documentata
  • Aggiornamenti applicati entro 7 giorni dal rilascio
  • Backup prima di ogni aggiornamento

3.3 Logging e audit

Configura n8n per registrare le attività:

# Logging
N8N_LOG_LEVEL=info
N8N_LOG_OUTPUT=console,file
N8N_LOG_FILE_LOCATION=/data/logs/n8n.log
N8N_LOG_FILE_MAX_SIZE=20

# Esecuzioni
EXECUTIONS_DATA_SAVE_ON_ERROR=all
EXECUTIONS_DATA_SAVE_ON_SUCCESS=all
EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=true

Configura la rotazione dei log:

# /etc/logrotate.d/n8n
/data/logs/n8n.log {
    daily
    rotate 30
    compress
    missingok
    notifempty
}

Checklist:

  • Logging attivo su file
  • Rotazione log configurata
  • Esecuzioni salvate (successi e errori)
  • Log accessibili per audit

3.4 Isolamento con Docker

Se usi Docker (consigliato), configura l'isolamento correttamente:

# docker-compose.yml
services:
  n8n:
    image: n8nio/n8n:latest
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    read_only: true
    tmpfs:
      - /tmp
    volumes:
      - n8n_data:/home/node/.n8n
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      # ... altre variabili ...
    networks:
      - n8n_network
    # NON esporre la porta 5678 all'esterno
    # ports:
    #   - "5678:5678"  # NO!
    expose:
      - "5678"  # Solo internamente alla rete Docker

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - /etc/letsencrypt:/etc/letsencrypt:ro
    networks:
      - n8n_network

networks:
  n8n_network:
    driver: bridge

volumes:
  n8n_data:

Checklist:

  • n8n in container Docker isolato
  • Porta 5678 non esposta all'esterno (solo expose, non ports)
  • no-new-privileges attivo
  • Volume dati persistente

Come configurare backup e disaster recovery per n8n?

4.1 Backup automatico dei dati n8n

#!/bin/bash
# /opt/scripts/backup-n8n.sh

BACKUP_DIR="/opt/backups/n8n"
DATE=$(date +%Y%m%d_%H%M%S)
N8N_DATA="/var/lib/docker/volumes/n8n_data/_data"

mkdir -p "$BACKUP_DIR"

# Esporta workflow
docker exec n8n n8n export:workflow --all --output="/tmp/workflows_${DATE}.json"
docker cp n8n:/tmp/workflows_${DATE}.json "$BACKUP_DIR/"

# Esporta credenziali (criptate)
docker exec n8n n8n export:credentials --all --output="/tmp/credentials_${DATE}.json"
docker cp n8n:/tmp/credentials_${DATE}.json "$BACKUP_DIR/"

# Backup database SQLite
cp "$N8N_DATA/database.sqlite" "$BACKUP_DIR/database_${DATE}.sqlite"

# Comprimi
tar -czf "$BACKUP_DIR/n8n_backup_${DATE}.tar.gz" \
  "$BACKUP_DIR/workflows_${DATE}.json" \
  "$BACKUP_DIR/credentials_${DATE}.json" \
  "$BACKUP_DIR/database_${DATE}.sqlite"

# Pulisci file temporanei
rm "$BACKUP_DIR/workflows_${DATE}.json" \
   "$BACKUP_DIR/credentials_${DATE}.json" \
   "$BACKUP_DIR/database_${DATE}.sqlite"

# Mantieni solo gli ultimi 30 backup
find "$BACKUP_DIR" -name "n8n_backup_*.tar.gz" -mtime +30 -delete

echo "Backup completato: $BACKUP_DIR/n8n_backup_${DATE}.tar.gz"

Aggiungi al crontab:

# Backup giornaliero alle 3:00
0 3 * * * /opt/scripts/backup-n8n.sh >> /var/log/n8n-backup.log 2>&1

Checklist:

  • Backup automatico giornaliero attivo
  • Backup include workflow, credenziali e database
  • Retention policy definita (es. 30 giorni)
  • Backup testato con restore (almeno 1 volta/mese)
  • Backup copiato su storage esterno (non solo sullo stesso server)

Qual è la checklist di sicurezza completa per n8n?

Priorità critica (giorno 1)

  • Reverse proxy Nginx configurato
  • SSL/TLS attivo con rinnovo automatico
  • Autenticazione con password forte
  • Chiave di cifratura impostata e salvata

Priorità alta (prima settimana)

  • Rate limiting attivo
  • Fail2ban configurato
  • Firewall UFW attivo
  • Variabili d'ambiente per credenziali

Priorità media (primo mese)

  • Webhook protetti con secret
  • Procedura aggiornamenti definita
  • Logging e audit attivi
  • Docker con isolamento corretto

Priorità normale (ongoing)

  • Backup automatici testati
  • Disaster recovery plan documentato
  • Review sicurezza trimestrale
  • Aggiornamenti applicati regolarmente

Ogni punto di questa checklist riduce la superficie di attacco della tua istanza. Non serve implementarli tutti in un giorno, ma ignora quelli di priorità critica a tuo rischio.


Hai dubbi sulla sicurezza della tua istanza n8n? Contattaci per un audit di sicurezza personalizzato.

T

Team n8n.it

Specialisti in Automazione

Siamo un team di esperti n8n focalizzati sull'automazione dei processi aziendali e la sicurezza delle implementazioni self-hosted.

Articoli correlati