alexle135 Animiertes Logo
8 Min. Lesezeit

Nginx als Reverse Proxy einrichten – mit SSL/TLS in 20 Minuten

Ich hab lange Apache genutzt. Dann hab ich Nginx entdeckt. Hier zeig ich dir, wie du Nginx als Reverse Proxy einrichtest – mit Let's Encrypt SSL.

Nginx als Reverse Proxy einrichten – mit SSL/TLS in 20 Minuten

Warum ich zu Nginx gewechselt bin

Ich hatte eine Node.js-App auf Port 3000 laufen. Zugriff nur via http://meinserver.de:3000 – unprofessionell.

Ich wollte:

  • ✅ Zugriff via https://meinserver.de (ohne Port)
  • ✅ SSL/TLS-Verschlüsselung (das grüne Schloss im Browser)
  • ✅ Mehrere Apps auf einem Server

Lösung: Nginx als Reverse Proxy.

Was ist ein Reverse Proxy?

Die kurze Antwort: Ein Reverse Proxy nimmt Anfragen entgegen und leitet sie an die richtige App weiter.

Die Analogie: Stell dir Nginx als Empfangschef in einem Hotel vor:

  • Gast (Browser) kommt und sagt: “Ich möchte zu Zimmer app1.de”
  • Empfangschef (Nginx) prüft die Liste und sagt: “Das ist Port 3000, ich leite weiter”
  • Zimmer (Backend-App) antwortet

Ohne Reverse Proxy: Jede App braucht einen eigenen Port und ist direkt erreichbar.

Mit Reverse Proxy: Nginx ist der einzige Einstiegspunkt. Er verteilt Anfragen intern.

Was du brauchst

  • Linux-Server (Ubuntu, Debian, oder ähnlich)
  • Root-Zugriff (sudo)
  • Domain (z.B. meinserver.de)
  • Backend-App (z.B. Node.js auf Port 3000)
  • 20 Minuten Zeit

Schritt 1: Nginx installieren

# Update
sudo apt update

# Nginx installieren
sudo apt install nginx -y

# Prüfen ob läuft
sudo systemctl status nginx

Testen: Öffne deinen Browser: http://deine-server-ip

Du solltest die “Welcome to nginx!” Seite sehen.

Schritt 2: Nginx-Config verstehen

Wichtige Verzeichnisse

# Haupt-Config
/etc/nginx/nginx.conf

# Site-Configs (verfügbare Sites)
/etc/nginx/sites-available/

# Aktivierte Sites (Symlinks)
/etc/nginx/sites-enabled/

# Logs
/var/log/nginx/access.log
/var/log/nginx/error.log

Standard-Config deaktivieren

# Standard-Site deaktivieren
sudo rm /etc/nginx/sites-enabled/default

Schritt 3: Reverse Proxy Config erstellen

Szenario

Du hast eine Node.js-App auf Port 3000. Domain: app.meinserver.de

Config-Datei erstellen

sudo nano /etc/nginx/sites-available/app.meinserver.de

Basic Reverse Proxy Config

server {
    listen 80;
    listen [::]:80;
    server_name app.meinserver.de;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        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;
    }
}

Was passiert hier?

  • listen 80 – Nginx hört auf Port 80 (HTTP)
  • server_name – Nur Anfragen für diese Domain werden bearbeitet
  • proxy_pass – Anfragen werden an localhost:3000 weitergeleitet
  • proxy_set_header – Header werden korrekt weitergegeben

Config aktivieren

# Symlink erstellen
sudo ln -s /etc/nginx/sites-available/app.meinserver.de /etc/nginx/sites-enabled/

# Config testen
sudo nginx -t

# Nginx neu laden
sudo systemctl reload nginx

Testen: Öffne http://app.meinserver.de – du solltest deine App sehen.

Schritt 4: SSL/TLS mit Let’s Encrypt

Certbot installieren

sudo apt install certbot python3-certbot-nginx -y

Zertifikat erstellen

sudo certbot --nginx -d app.meinserver.de

Was passiert:

  1. Certbot prüft, ob die Domain auf deinen Server zeigt
  2. Erstellt SSL-Zertifikat
  3. Passt Nginx-Config automatisch an
  4. Richtet Auto-Renewal ein

Fragen während der Installation:

  • Email: Deine Email (für Ablauf-Warnungen)
  • Terms: Akzeptieren (ja)
  • Redirect HTTP → HTTPS: Ja (empfohlen)

Ergebnis: Deine Config wird automatisch erweitert:

server {
    server_name app.meinserver.de;

    location / {
        proxy_pass http://localhost:3000;
        # ... proxy headers ...
    }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/app.meinserver.de/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/app.meinserver.de/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = app.meinserver.de) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    listen [::]:80;
    server_name app.meinserver.de;
    return 404; # managed by Certbot
}

Testen: Öffne https://app.meinserver.de – grünes Schloss im Browser!

Schritt 5: Mehrere Apps einrichten

Szenario

  • app1.meinserver.de → Port 3000
  • app2.meinserver.de → Port 4000
  • api.meinserver.de → Port 5000

Config für app2

sudo nano /etc/nginx/sites-available/app2.meinserver.de
server {
    listen 80;
    listen [::]:80;
    server_name app2.meinserver.de;

    location / {
        proxy_pass http://localhost:4000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        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;
    }
}
# Aktivieren
sudo ln -s /etc/nginx/sites-available/app2.meinserver.de /etc/nginx/sites-enabled/

# SSL hinzufügen
sudo certbot --nginx -d app2.meinserver.de

# Nginx neu laden
sudo systemctl reload nginx

Wiederholen für alle weiteren Apps.

Häufige Fehler (die ich gemacht habe)

Fehler 1: “502 Bad Gateway”

Ursache: Die Backend-App auf Port 3000 läuft nicht.

Lösung:

# Prüfen ob App läuft
curl http://localhost:3000

# Falls nicht: App starten
# Für Node.js:
node app.js

# Oder mit PM2 (empfohlen):
pm2 start app.js
pm2 save
pm2 startup

Fehler 2: DNS zeigt nicht auf Server

Ursache: Domain ist nicht korrekt konfiguriert.

Lösung:

# Prüfen ob Domain auf Server zeigt
dig app.meinserver.de

# Oder:
nslookup app.meinserver.de

DNS-Record sollte deine Server-IP anzeigen.

Wo konfigurieren: Bei deinem Domain-Provider (z.B. Namecheap, Cloudflare):

A-Record: app.meinserver.de → 161.97.110.21

Fehler 3: Certbot schlägt fehl

Ursache: Domain zeigt nicht auf Server oder Port 80 ist blockiert.

Lösung:

# Prüfen ob Port 80 offen ist
sudo netstat -tuln | grep :80

# Firewall-Regel hinzufügen (falls nötig)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Fehler 4: Nginx startet nicht

Ursache: Syntax-Fehler in Config.

Lösung:

# Config testen
sudo nginx -t

# Fehler anzeigen
sudo journalctl -xeu nginx

Nützliche Nginx-Befehle

BefehlWas es macht
sudo systemctl start nginxNginx starten
sudo systemctl stop nginxNginx stoppen
sudo systemctl restart nginxNginx neu starten
sudo systemctl reload nginxConfig neu laden (ohne Neustart)
sudo systemctl status nginxStatus anzeigen
sudo nginx -tConfig testen (vor Reload!)
sudo tail -f /var/log/nginx/error.logError-Log live anzeigen
sudo tail -f /var/log/nginx/access.logAccess-Log live anzeigen

Erweiterte Config-Optionen

Rate Limiting (DDoS-Schutz)

# In /etc/nginx/nginx.conf im http-Block
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

# In deiner Site-Config
server {
    location / {
        limit_req zone=mylimit burst=20;
        proxy_pass http://localhost:3000;
        # ... rest ...
    }
}

Was passiert: Maximal 10 Requests pro Sekunde pro IP. Burst erlaubt kurze Spitzen.

Gzip-Kompression aktivieren

# In /etc/nginx/nginx.conf
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss;

Effekt: Responses werden komprimiert → schnellere Ladezeiten.

Client Max Body Size (für File-Uploads)

server {
    # Erlaube Uploads bis 100MB
    client_max_body_size 100M;

    location / {
        proxy_pass http://localhost:3000;
        # ...
    }
}

WebSocket-Support

Bereits in der Basic-Config enthalten via:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';

Falls nicht: Ergänzen für Socket.io, WebSockets, etc.

SSL-Zertifikat erneuern

Let’s Encrypt-Zertifikate laufen nach 90 Tagen ab.

Auto-Renewal prüfen:

# Certbot erstellt automatisch einen Cronjob
sudo certbot renew --dry-run

Manuell erneuern:

sudo certbot renew
sudo systemctl reload nginx

Cronjob prüfen:

sudo crontab -l
# Sollte etwas wie:
# 0 */12 * * * certbot renew --quiet

Performance-Tipps

1. HTTP/2 aktivieren

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    # ... rest ...
}

Reload:

sudo systemctl reload nginx

2. Caching aktivieren

# In http-Block in nginx.conf
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;

# In Site-Config
location / {
    proxy_cache my_cache;
    proxy_cache_valid 200 60m;
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
    proxy_pass http://localhost:3000;
    # ...
}

3. Keep-Alive erhöhen

# In nginx.conf
keepalive_timeout 65;
keepalive_requests 100;

Monitoring & Logs

Access-Log analysieren

# Top 10 IPs nach Requests
sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

# Status-Codes zählen
sudo awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

Error-Log durchsuchen

# Nur Errors
sudo grep "error" /var/log/nginx/error.log

# Letzte 50 Zeilen
sudo tail -50 /var/log/nginx/error.log

Sicherheits-Tipps

1. Security-Header setzen

server {
    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 Referrer-Policy "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src 'self';" always;

    location / {
        # ...
    }
}

2. Server-Token verstecken

# In nginx.conf im http-Block
server_tokens off;

Effekt: Nginx-Version wird nicht mehr in Responses angezeigt.

3. IP-Whitelisting (optional)

location /admin {
    allow 192.168.1.0/24;  # Nur lokales Netz
    deny all;
    proxy_pass http://localhost:3000;
}

Fazit

Nginx als Reverse Proxy hat meine Server-Verwaltung vereinfacht.

Vorher: Jede App auf eigenem Port, kein SSL, unprofessionell.

Nachher:

  • ✅ Alle Apps via HTTPS erreichbar
  • ✅ Ein zentraler Einstiegspunkt
  • ✅ Let’s Encrypt SSL automatisch
  • ✅ Performance-Optimierungen möglich

Zeitaufwand: 20-30 Minuten (erste App) Schwierigkeitsgrad: Anfänger-Mittel Lohnt sich? Definitiv. Standard für Production.

Mein Tipp: Fang mit einer App an. Wenn das läuft, weitere hinzufügen.

Bei Fragen: schneider@alexle135.de


Quellen:

Das könnte dich auch interessieren

← Zurück zur Übersicht