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.

Perché la sicurezza di n8n è importante
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.
Livello 1: fondamentali (fai subito)
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_sizelimitato
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_KEYimpostata con chiave casuale - Chiave salvata in un luogo sicuro separato dal server
- File
.envcon permessi 600 (solo owner)
Livello 2: protezione attiva (fai entro la 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
.envcon permessi 600 - Docker secrets per dati sensibili (se usi Docker Swarm)
Livello 3: hardening avanzato (fai entro il primo mese)
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, nonports) -
no-new-privilegesattivo - Volume dati persistente
Livello 4: backup e disaster recovery
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)
Riepilogo checklist completa
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.
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

Il costo reale di n8n self-hosted: server, manutenzione e tempo
n8n è gratuito, ma il self-hosting ha costi nascosti. Analizziamo il TCO reale: server, SSL, backup,...
Leggi di più
I 7 errori più comuni con n8n in produzione (e come evitarli)
Errori reali che abbiamo visto in decine di installazioni n8n in produzione: nessun error handling, ...
Leggi di più
n8n e AI Agent: come automatizzare senza perdere il controllo
Guida pratica per usare gli AI Agent in n8n con guardrail, human-in-the-loop, validazione output, mo...
Leggi di più