n8n mit Nginx Reverse Proxy, TLS und Security Headers absichern
Stellen Sie Ihre selbst gehostete n8n-Instanz hinter Nginx mit TLS, Security Headers, Rate Limiting und Firewall-Regeln. Von einem offenen Port 5678 zu einem produktionsreifen Setup.
Dieses Tutorial stellt Ihre selbst gehostete n8n-Instanz hinter Nginx mit TLS, Security Headers, Rate Limiting und Firewall-Regeln. Sie gehen von einem offenen n8n auf Port 5678 zu einem produktionsreifen Setup, bei dem nur HTTPS-Traffic den Editor und die Webhooks erreicht.
Voraussetzungen:
- n8n läuft via Docker Compose auf einem VPS (n8n mit Docker Compose auf einem VPS installieren)
- Ein Domainname (z. B.
n8n.example.com) mit einem A-Record, der auf die IP Ihres Servers zeigt - SSH-Zugang zu Ihrem Server als Nicht-Root-Benutzer mit
sudo - Ports 80 und 443 in der Firewall Ihres Hosting-Anbieters geöffnet (Virtua Cloud öffnet diese standardmäßig)
Diese Anleitung geht von Ubuntu 24.04 LTS aus. Die Befehle funktionieren auf Debian 12 mit geringfügigen Anpassungen. n8n Version 2.x wird durchgehend verwendet.
Wie konfiguriere ich Nginx als Reverse Proxy für n8n mit WebSocket-Unterstützung?
Nginx sitzt zwischen dem Internet und n8n und leitet Anfragen an localhost:5678 weiter. Der n8n-Editor nutzt WebSocket-Verbindungen für Echtzeit-Updates. Ohne korrektes WebSocket-Proxying friert die Editor-Oberfläche ein und zeigt "Connection lost." Sie benötigen proxy_pass auf localhost:5678, HTTP/1.1 Upgrade Headers für WebSocket und die Umgebungsvariable N8N_PROXY_HOPS=1, damit n8n die echte Client-IP aus X-Forwarded-For liest.
Nginx installieren
sudo apt update && sudo apt install -y nginx
Prüfen Sie, ob Nginx läuft:
sudo systemctl status nginx
Sie sollten active (running) in grün sehen. Falls nicht, starten und aktivieren Sie es:
sudo systemctl enable --now nginx
Das Flag enable --now erledigt zwei Dinge: enable sorgt dafür, dass Nginx nach einem Neustart automatisch startet, und --now startet es sofort.
Nginx Server Block erstellen
Erstellen Sie eine neue Konfigurationsdatei für Ihre n8n-Domain:
sudo nano /etc/nginx/sites-available/n8n.example.com
Fügen Sie diese Konfiguration ein. Ersetzen Sie n8n.example.com durch Ihre tatsächliche Domain:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name n8n.example.com;
# Will be replaced by Certbot later
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
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;
proxy_buffering off;
proxy_cache off;
chunked_transfer_encoding off;
}
}
Der map-Block oben behandelt WebSocket-Upgrades. Wenn ein Browser einen Upgrade: websocket-Header sendet, leitet Nginx ihn durch. Für reguläre HTTP-Anfragen sendet er close. Das hält den n8n-Editor reaktionsfähig.
proxy_buffering off und proxy_cache off verhindern, dass Nginx die Server-Sent Events von n8n puffert, was den Editor verzögern würde.
Aktivieren Sie die Seite und testen Sie die Konfiguration:
sudo ln -s /etc/nginx/sites-available/n8n.example.com /etc/nginx/sites-enabled/
sudo nginx -t
Sie sollten Folgendes sehen:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Wenn der Test bestanden ist, laden Sie die Konfiguration neu:
sudo systemctl reload nginx
Prüfen Sie, ob n8n über Nginx erreichbar ist:
curl -s -o /dev/null -w "%{http_code}" http://n8n.example.com
Eine 200-Antwort bedeutet, dass Nginx den Traffic an n8n weiterleitet. Ein 502 bedeutet, dass n8n nicht auf Port 5678 läuft. Prüfen Sie es mit docker ps.
n8n-Umgebungsvariablen aktualisieren
Öffnen Sie Ihre n8n .env-Datei (im selben Verzeichnis wie Ihre docker-compose.yml):
nano ~/n8n-docker/.env
Fügen Sie diese Variablen hinzu oder aktualisieren Sie sie:
N8N_HOST=n8n.example.com
N8N_PROTOCOL=https
N8N_PROXY_HOPS=1
WEBHOOK_URL=https://n8n.example.com/
N8N_EDITOR_BASE_URL=https://n8n.example.com/
N8N_SECURE_COOKIE=true
Was jede Variable bewirkt:
| Variable | Wert | Zweck |
|---|---|---|
N8N_HOST |
Ihre Domain | Teilt n8n mit, welchen Hostnamen es in Webhook-URLs verwenden soll |
N8N_PROTOCOL |
https |
n8n generiert HTTPS-Webhook-URLs statt HTTP |
N8N_PROXY_HOPS |
1 |
n8n vertraut einer Ebene von X-Forwarded-For, um die echte Client-IP zu ermitteln |
WEBHOOK_URL |
Vollständige URL | Überschreibt die automatisch generierte Webhook-Basis-URL |
N8N_EDITOR_BASE_URL |
Vollständige URL | URL für E-Mail-Benachrichtigungen und SAML-Redirects |
N8N_SECURE_COOKIE |
true |
Cookies werden nur über HTTPS gesendet. Verhindert Session-Hijacking über unverschlüsseltes HTTP |
Starten Sie n8n neu, um die Änderungen zu übernehmen:
cd ~/n8n-docker && docker compose down && docker compose up -d
Prüfen Sie, ob n8n die neue Umgebung übernommen hat:
docker compose logs --tail=20 n8n | grep -i "editor\|webhook\|proxy"
Sie sollten Logzeilen mit Ihrer Domain und dem HTTPS-Protokoll sehen.
Wie füge ich Let's Encrypt TLS zu meinem n8n Reverse Proxy hinzu?
Certbot automatisiert die Ausstellung von Let's Encrypt-Zertifikaten und konfiguriert Nginx automatisch für TLS. Nach dem Ausführen von Certbot wird sämtlicher HTTP-Traffic auf HTTPS umgeleitet, und Ihr n8n-Editor sowie Webhooks sind bei der Übertragung verschlüsselt.
Certbot installieren
sudo apt install -y certbot python3-certbot-nginx
Zertifikat abrufen
sudo certbot --nginx -d n8n.example.com
Certbot wird:
- Über eine HTTP-01-Challenge verifizieren, dass Ihnen die Domain gehört
- Ein Zertifikat von Let's Encrypt abrufen
- Ihre Nginx-Konfiguration um TLS-Einstellungen und eine HTTP-zu-HTTPS-Weiterleitung ergänzen
Wenn Sie nach einer E-Mail-Adresse gefragt werden, geben Sie eine echte an. Dort erhalten Sie Warnungen bei fehlgeschlagenen Verlängerungen.
TLS-Funktion prüfen
curl -I https://n8n.example.com
Prüfen Sie die Antwort auf HTTP/2 200. Bei einem Zertifikatsfehler warten Sie einige Minuten auf die DNS-Propagierung.
Testen Sie die Zertifikatskette von Ihrem lokalen Rechner (nicht vom Server):
openssl s_client -connect n8n.example.com:443 -servername n8n.example.com </dev/null 2>/dev/null | head -20
Achten Sie auf Verify return code: 0 (ok).
Automatische Verlängerung prüfen
Certbot installiert einen systemd-Timer, der Zertifikate vor dem Ablauf erneuert. Bestätigen Sie, dass er aktiv ist:
sudo systemctl status certbot.timer
Sie sollten active (waiting) sehen. Testen Sie den Erneuerungsprozess ohne tatsächliche Erneuerung:
sudo certbot renew --dry-run
Ein erfolgreicher Dry Run bedeutet, dass Ihre Zertifikate automatisch alle 60-90 Tage erneuert werden.
Welche Security Headers benötigt n8n in der Produktion?
Security Headers teilen dem Browser mit, wie er die Inhalte Ihrer Seite behandeln soll. Ohne sie ist Ihr n8n-Editor anfällig für Clickjacking, MIME-Type-Sniffing-Angriffe und Cross-Site-Scripting. Fügen Sie sechs Header zu Ihrer Nginx-Konfiguration hinzu, um diese Lücken zu schließen.
Öffnen Sie die von Certbot geänderte Nginx-Konfiguration:
sudo nano /etc/nginx/sites-available/n8n.example.com
Fügen Sie innerhalb des server-Blocks, der auf Port 443 lauscht (den Certbot erstellt hat), diese Header oberhalb des location /-Blocks ein:
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' wss://n8n.example.com; frame-ancestors 'none'" always;
Ersetzen Sie n8n.example.com in der CSP-Direktive connect-src durch Ihre tatsächliche Domain. Der wss://-Eintrag erlaubt WebSocket-Verbindungen zum Editor.
Was jeder Header bewirkt:
| Header | Wert | Was er verhindert |
|---|---|---|
Strict-Transport-Security |
1 Jahr, Subdomains | Browser nutzt immer HTTPS. Verhindert SSL-Stripping-Angriffe |
X-Frame-Options |
DENY | Niemand kann Ihren n8n-Editor in einem iframe einbetten. Verhindert Clickjacking |
X-Content-Type-Options |
nosniff | Browser vertraut dem deklarierten MIME-Typ. Verhindert MIME-Confusion-Angriffe |
Referrer-Policy |
strict-origin-when-cross-origin | Begrenzt an externe Seiten weitergegebene Referrer-Informationen |
Permissions-Policy |
Kamera, Mikrofon, Geo verweigern | Browser blockiert Zugriff auf Hardware-APIs, die n8n nicht benötigt |
Content-Security-Policy |
Siehe oben | Kontrolliert, welche Skripte, Styles und Verbindungen der Browser zulässt |
Der CSP-Header ist der komplexeste. Der n8n-Editor verwendet Inline-Skripte und eval() für den Workflow-Builder, daher sind 'unsafe-inline' und 'unsafe-eval' für script-src erforderlich. Das ist ein bekannter Kompromiss. Die übrigen Direktiven sind restriktiv: nur Same-Origin-Ressourcen und WebSocket-Verbindungen zu Ihrer Domain.
Testen und neu laden:
sudo nginx -t && sudo systemctl reload nginx
Prüfen Sie, ob die Header vorhanden sind:
curl -sI https://n8n.example.com | grep -iE "strict-transport|x-frame|x-content|referrer|permissions|content-security"
Sie sollten alle sechs Header in der Ausgabe sehen. Falls einer fehlt, prüfen Sie die Konfigurationsdatei auf Tippfehler.
Wie konfiguriere ich die Firewall für n8n auf einem VPS?
UFW blockiert sämtlichen Traffic außer dem, den Sie explizit erlauben. Für n8n hinter Nginx müssen nur drei Ports offen sein: 22 (SSH), 80 (HTTP, für Certbot-Erneuerung und Weiterleitungen) und 443 (HTTPS). Port 5678, auf dem n8n direkt lauscht, muss von außen blockiert sein. Viele Anleitungen überspringen diesen Schritt und lassen n8n ohne TLS erreichbar.
Einen tieferen Einblick in UFW finden Sie unter Linux-VPS-Firewall mit UFW und nftables einrichten.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP - Certbot renewal'
sudo ufw allow 443/tcp comment 'HTTPS - n8n via Nginx'
sudo ufw enable
Wenn Sie gefragt werden, tippen Sie y zur Bestätigung. Prüfen Sie die Regeln:
sudo ufw status verbose
Sie sollten drei ALLOW-Regeln für die Ports 22, 80 und 443 sehen. Nichts anderes. Port 5678 ist nicht aufgelistet, was bedeutet, dass er blockiert ist.
Bestätigen Sie, dass n8n nicht direkt erreichbar ist. Von Ihrem lokalen Rechner:
curl -s --connect-timeout 3 http://n8n.example.com:5678 || echo "Connection refused - correct!"
Wenn Sie "Connection refused" oder einen Timeout erhalten, funktioniert die Firewall. Falls Sie eine n8n-Antwort erhalten, umgeht Docker wahrscheinlich UFW. Docker ändert iptables direkt und kann UFW-Regeln überschreiben.
n8n an localhost binden und Docker daran hindern, UFW zu umgehen
Die einfachste Lösung ist, n8n nur an localhost zu binden. Ändern Sie in Ihrer docker-compose.yml das Port-Mapping:
ports:
- "127.0.0.1:5678:5678"
Das stellt sicher, dass n8n nur Verbindungen vom selben Rechner akzeptiert. Nginx auf demselben Server kann es erreichen, externer Traffic nicht.
Starten Sie n8n neu:
cd ~/n8n-docker && docker compose down && docker compose up -d
Falls das allein nicht ausreicht (testen Sie erneut mit curl von Ihrem lokalen Rechner), können Sie auch Dockers iptables-Verwaltung deaktivieren. Bearbeiten Sie /etc/docker/daemon.json:
sudo nano /etc/docker/daemon.json
Fügen Sie hinzu:
{
"iptables": false
}
Dann starten Sie Docker neu:
sudo systemctl restart docker
cd ~/n8n-docker && docker compose up -d
Warnung: Das Setzen von "iptables": false hindert Docker daran, NAT- und Forwarding-Regeln zu erstellen. Das kann die Kommunikation zwischen Containern und den ausgehenden Internetzugang aus Containern unterbrechen. Falls Ihre n8n-Workflows HTTP-Anfragen an externe APIs senden (was meistens der Fall ist), testen Sie die ausgehende Konnektivität nach dieser Änderung. Die Localhost-Bindung allein reicht normalerweise aus.
Prüfen Sie erneut von Ihrem lokalen Rechner, dass Port 5678 nicht erreichbar ist.
Wie begrenze ich die Anfragerate für n8n-Webhook-Endpunkte in Nginx?
Rate Limiting schützt Ihre Webhook-Endpunkte vor Missbrauch und Denial-of-Service-Versuchen. Sie definieren eine Anfragerate pro IP-Adresse. Legitime Integrationen (GitHub, Stripe) senden Webhooks mit vorhersehbarer Rate. Ein Angreifer, der Ihre Webhook-URL bombardiert, erhält statt ausgelöster Workflows eine 429 Too Many Requests-Antwort.
Mehr zu Rate-Limiting-Strategien finden Sie unter Nginx Rate Limiting und DDoS-Schutz.
Fügen Sie eine limit_req_zone-Direktive oben in Ihrer Nginx-Konfigurationsdatei hinzu, außerhalb jedes server-Blocks, neben der bestehenden map-Direktive:
limit_req_zone $binary_remote_addr zone=webhooks:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=editor:10m rate=30r/s;
Das erstellt zwei Zonen:
webhooks: 10 Anfragen pro Sekunde pro IP. Für Callbacks externer Dienste.editor: 30 Anfragen pro Sekunde pro IP. Der Editor macht viele kleine API-Aufrufe und benötigt daher ein höheres Limit.
Fügen Sie innerhalb des server-Blocks, der auf 443 lauscht, einen separaten location-Block für Webhook-Pfade vor dem Haupt-location / hinzu:
# Rate limit webhook endpoints
location /webhook/ {
limit_req zone=webhooks burst=20 nodelay;
limit_req_status 429;
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
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;
# Generous timeout for long-running webhook workflows
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
location /webhook-test/ {
limit_req zone=webhooks burst=5 nodelay;
limit_req_status 429;
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
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;
}
Der Parameter burst=20 erlaubt kurze Spitzen von bis zu 20 Anfragen, bevor das Rate Limiting greift. Das deckt Fälle ab, in denen GitHub mehrere Webhook-Events aus einem einzelnen Push sendet. nodelay verarbeitet Burst-Anfragen sofort statt sie in eine Warteschlange zu stellen.
Fügen Sie im Haupt-location /-Block das Editor-Rate-Limit hinzu:
location / {
limit_req zone=editor burst=50 nodelay;
limit_req_status 429;
# ... existing proxy settings ...
}
Testen und neu laden:
sudo nginx -t && sudo systemctl reload nginx
Prüfen Sie, ob das Rate Limiting funktioniert, indem Sie einen Burst von Anfragen an einen Test-Webhook senden:
for i in $(seq 1 30); do
curl -s -o /dev/null -w "%{http_code} " https://n8n.example.com/webhook/test-rate-limit
done
echo
Sie sollten eine Mischung aus 404-Antworten (der Webhook-Pfad existiert nicht, das ist in Ordnung) und 429-Antworten sehen, sobald das Rate Limit greift.
Wie beschränke ich den n8n-Editor auf bestimmte IP-Adressen?
Standardmäßig kann jeder, der Ihre n8n-URL kennt, die Login-Seite aufrufen. IP-Allowlisting auf Nginx-Ebene fügt eine Schicht vor der eigenen Authentifizierung von n8n hinzu. Nur Anfragen von Ihrer IP-Adresse (oder Ihrem VPN) erreichen den Editor. Webhook-Endpunkte bleiben für das Internet offen, damit externe Dienste sie aufrufen können.
Fügen Sie einen neuen location-Block für die Editor-Pfade hinzu. Platzieren Sie ihn nach den Webhook-Locations und vor dem Haupt-location /:
# Restrict editor/API access to specific IPs
location /rest/ {
allow 203.0.113.50; # Your office/home IP
allow 10.0.0.0/8; # Your VPN range
deny all;
limit_req zone=editor burst=50 nodelay;
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
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;
proxy_buffering off;
}
Ersetzen Sie 203.0.113.50 durch Ihre tatsächliche IP. Finden Sie sie mit:
curl -4 ifconfig.me
Der Pfad /rest/ behandelt die API-Aufrufe des n8n-Editors. Der Haupt-location / bedient weiterhin das Editor-Frontend und Webhooks. Für eine strengere Absicherung können Sie auch den Root-Pfad einschränken und separate offene Locations nur für /webhook/ und /webhook-test/ anlegen.
Testen und neu laden:
sudo nginx -t && sudo systemctl reload nginx
Prüfen Sie von Ihrer erlaubten IP:
curl -s -o /dev/null -w "%{http_code}" https://n8n.example.com/rest/settings
Ein 200 bedeutet, dass Sie zugelassen sind. Von einer anderen IP (nutzen Sie ein Mobiltelefon, das nicht in Ihrem WLAN ist) rufen Sie https://n8n.example.com/rest/settings im Browser auf. Sie sollten 403 Forbidden erhalten.
Wie sichere ich n8n-Webhooks gegen unbefugten Zugriff?
Webhook-URLs sind standardmäßig öffentlich. Jeder, der die URL entdeckt oder errät, kann Ihre Workflows auslösen. Zwei Strategien schützen dagegen: Webhook-Pfade unvorhersehbar halten und HMAC-Signaturen innerhalb Ihrer Workflows validieren.
Produktions-Webhooks mit eindeutigen IDs verwenden
n8n generiert zwei Webhook-Pfade für jeden Webhook-Node:
- Test-URL:
/webhook-test/<id>(nur aktiv, solange der Editor geöffnet ist) - Produktions-URL:
/webhook/<id>(aktiv, wenn der Workflow aktiviert ist)
Die <id> ist standardmäßig eine UUID. Ändern Sie sie nicht in etwas Erratbares wie /webhook/github oder /webhook/stripe. Die zufällige UUID ist Ihre erste Verteidigungsschicht.
HMAC-Signaturen in Workflows validieren
Dienste wie GitHub und Stripe signieren ihre Webhook-Payloads mit einem gemeinsamen Secret. Ihr n8n-Workflow sollte diese Signatur verifizieren, bevor er die Daten verarbeitet.
Für einen GitHub-Webhook fügen Sie einen IF-Node nach dem Webhook-Node mit dieser Bedingung hinzu:
- In Ihren GitHub-Repository-Einstellungen legen Sie ein Webhook-Secret fest (generieren Sie eines mit
openssl rand -base64 32) - In Ihrem n8n-Workflow fügen Sie einen Code-Node nach dem Webhook-Node hinzu:
const crypto = require('crypto');
const secret = $env.GITHUB_WEBHOOK_SECRET;
const signature = $input.first().headers['x-hub-signature-256'];
const body = JSON.stringify($input.first().json);
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(body).digest('hex');
if (signature !== expected) {
throw new Error('Invalid webhook signature');
}
return $input.all();
- Speichern Sie das Secret in der n8n-Umgebung, nicht fest im Workflow codiert. Fügen Sie es zu Ihrer
.env-Datei hinzu:
GITHUB_WEBHOOK_SECRET=your-generated-secret-here
Und machen Sie es in der docker-compose.yml für n8n verfügbar:
environment:
- GITHUB_WEBHOOK_SECRET=${GITHUB_WEBHOOK_SECRET}
Für Stripe-Webhooks ist das Muster ähnlich, verwendet aber einen anderen Header (stripe-signature) und einen Timing-Safe-Vergleich. Prüfen Sie die Stripe-Dokumentation zur Webhook-Signaturprüfung für das aktuelle Signierverfahren.
n8n-Versionsinformationen verbergen
Standardmäßig enthält n8n Versionsinformationen in API-Antworten. Deaktivieren Sie die Versionsoffenlegung, um Aufklärung zu erschweren:
In Ihrer .env-Datei:
N8N_VERSION_NOTIFICATIONS_ENABLED=false
In Ihrer Nginx-Konfiguration fügen Sie innerhalb des server-Blocks hinzu:
server_tokens off;
Die Versionsoffenlegung hilft Angreifern, bekannte Schwachstellen in bestimmten n8n-Versionen gezielt auszunutzen. Das Verbergen zwingt sie zum blinden Ausprobieren.
Wie passe ich Timeouts und Upload-Limits für n8n an?
Manche n8n-Workflows laufen minutenlang und verarbeiten große Datenmengen oder warten auf externe APIs. Das Standard-Timeout von Nginx (60 Sekunden) bricht diese Anfragen ab. Datei-Upload-Workflows scheitern, wenn die Payload das Standard-Body-Limit von 1 MB überschreitet.
Fügen Sie im Haupt-location /-Block Ihres HTTPS-Servers hinzu oder aktualisieren Sie:
# Timeout tuning for long-running workflows
proxy_connect_timeout 60s;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
# Allow file uploads up to 50 MB
client_max_body_size 50m;
proxy_read_timeout 300s gibt Workflows bis zu 5 Minuten für eine Antwort. Passen Sie den Wert an die Ausführungszeit Ihres längsten Workflows an. Der Webhook-location-Block hat bereits eigene Timeout-Einstellungen aus dem Abschnitt zum Rate Limiting.
client_max_body_size 50m erlaubt Datei-Uploads bis 50 MB über Webhook- und Editor-Endpunkte. n8n-Workflows, die CSV-Importe, Bild-Uploads oder Dokumentkonvertierungen verarbeiten, benötigen dies.
Testen und neu laden:
sudo nginx -t && sudo systemctl reload nginx
Vollständige Nginx-Konfigurationsreferenz
Die vollständige Konfiguration nach allen Änderungen. Vergleichen Sie sie mit Ihrer Datei:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
limit_req_zone $binary_remote_addr zone=webhooks:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=editor:10m rate=30r/s;
server {
listen 80;
listen [::]:80;
server_name n8n.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name n8n.example.com;
ssl_certificate /etc/letsencrypt/live/n8n.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_tokens off;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' wss://n8n.example.com; frame-ancestors 'none'" always;
client_max_body_size 50m;
# Rate limit webhook endpoints
location /webhook/ {
limit_req zone=webhooks burst=20 nodelay;
limit_req_status 429;
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
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;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
location /webhook-test/ {
limit_req zone=webhooks burst=5 nodelay;
limit_req_status 429;
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
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;
}
# Restrict editor API to specific IPs
location /rest/ {
allow 203.0.113.50;
allow 10.0.0.0/8;
deny all;
limit_req zone=editor burst=50 nodelay;
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
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;
proxy_buffering off;
}
# Main location - editor frontend and fallback
location / {
limit_req zone=editor burst=50 nodelay;
limit_req_status 429;
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
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;
proxy_buffering off;
proxy_cache off;
chunked_transfer_encoding off;
proxy_connect_timeout 60s;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
Wie prüfe ich, ob WebSocket-Verbindungen im n8n-Editor funktionieren?
Der n8n-Editor verwendet eine WebSocket-Verbindung unter /rest/push, um Echtzeit-Updates zur Workflow-Ausführung zu erhalten. Wenn diese Verbindung fehlschlägt, sehen Sie "Connection lost"-Banner und der Editor aktualisiert sich nach Workflow-Ausführungen nicht.
Öffnen Sie den n8n-Editor in Ihrem Browser. Öffnen Sie die Browser-DevTools (F12), gehen Sie zum Tab "Netzwerk" und filtern Sie nach "WS" (WebSocket). Sie sollten eine Verbindung zu wss://n8n.example.com/rest/push mit Status 101 (Switching Protocols) sehen.
Von der Kommandozeile testen Sie das WebSocket-Upgrade:
curl -sI -H "Upgrade: websocket" -H "Connection: Upgrade" -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" -H "Sec-WebSocket-Version: 13" https://n8n.example.com/rest/push
Eine 101 Switching Protocols-Antwort bestätigt, dass das WebSocket-Proxying funktioniert. Ein 200 oder 400 bedeutet, dass die Upgrade-Header n8n nicht erreichen. Gehen Sie zurück und prüfen Sie die map-Direktive sowie die Upgrade/Connection-Proxy-Header.
Etwas hat nicht funktioniert?
n8n-Editor zeigt "Connection lost"
Das WebSocket-Proxying ist defekt. Prüfen Sie:
- Der Block
map $http_upgrade $connection_upgradeexistiert am Anfang der Konfiguration proxy_set_header Upgrade $http_upgradeundproxy_set_header Connection $connection_upgradesind imlocation /-Block vorhandenproxy_http_version 1.1ist gesetzt (WebSocket erfordert HTTP/1.1)
Prüfen Sie die Nginx-Logs:
sudo journalctl -u nginx -f
"502 Bad Gateway" nach Neustart
Der n8n-Container läuft nicht oder lauscht nicht auf Port 5678:
docker ps | grep n8n
docker compose logs --tail=50 n8n
Certbot-Erneuerung schlägt fehl
Prüfen Sie, ob der Timer läuft, und testen Sie manuell:
sudo systemctl status certbot.timer
sudo certbot renew --dry-run
Falls die Erneuerung fehlschlägt, stellen Sie sicher, dass Port 80 in UFW offen ist und der HTTP-Server-Block noch vorhanden ist (Certbot benötigt ihn für die HTTP-01-Challenge).
"403 Forbidden" von erlaubter IP
Ihre IP hat sich möglicherweise geändert. Prüfen Sie Ihre aktuelle IP mit curl -4 ifconfig.me und aktualisieren Sie die allow-Direktive in der Nginx-Konfiguration.
Rate Limiting zu aggressiv
Falls legitime Webhook-Sender 429-Fehler erhalten, erhöhen Sie die Werte für rate und burst in Ihren limit_req_zone- und limit_req-Direktiven. Beobachten Sie zuerst die Rate eingehender Anfragen:
sudo tail -f /var/log/nginx/access.log | grep webhook
Nächste Schritte
- Automatische Backups und Updates für Ihre n8n-Instanz einrichten (n8n in Produktion sichern und aktualisieren (Docker Compose + PostgreSQL))
- Mehr über Nginx Reverse Proxy-Muster erfahren (Nginx als Reverse Proxy konfigurieren)
- TLS-Konfiguration im Detail erkunden (Let's Encrypt SSL/TLS für Nginx einrichten auf Debian 12 und Ubuntu 24.04)
- Zurück zur Übersicht Workflow-Automatisierung (Workflow-Automatisierung auf einem VPS mit n8n selbst hosten)
Bereit, es selbst auszuprobieren?
Stellen Sie Ihren eigenen Server in Sekunden bereit. Linux, Windows oder FreeBSD. →