
SSL & Nginx Reverse Proxy: Next.js im aaPanel routen

Der Webserver-Stack steht, die Node.js-Prozesse laufen stabil im Hintergrund, und das Betriebssystem ist kompromisslos gehärtet. Doch bisher kommunizieren alle Dienste nur intern auf dem Server oder über ungesicherte HTTP-Verbindungen.
Wenn du moderne Server-Side-Rendering (SSR) Anwendungen wie Next.js betreibst, darfst du den Node.js-Prozess niemals direkt dem öffentlichen Internet aussetzen. Node.js ist extrem performant bei der Code-Ausführung, aber nicht dafür gebaut, tausende langsame TCP-Verbindungen offenzuhalten, SSL-Handshakes effizient zu berechnen oder Denial-of-Service-Angriffe (DDoS) abzuwehren.
Diese harte Netzwerkarbeit überlassen wir dem Meister seines Fachs: Nginx. In diesem vierten Teil unserer Masterclass richten wir Nginx als aaPanel Nginx Reverse Proxy ein. Nginx wird künftig auf den Standard-Ports 80 und 443 lauschen, den Traffic SSL-verschlüsseln, filtern und erst dann an den internen Next.js-Port (z. B. 3000) weiterleiten.
Automatisches SSL-Management mit Let's Encrypt im aaPanel
Bevor wir den Proxy konfigurieren, benötigen wir ein gültiges SSL-Zertifikat. aaPanel bietet eine vollständig integrierte Let's Encrypt-Verwaltung, die den gesamten Ausstellungs- und Erneuerungsprozess (ACME-Protokoll) automatisiert.
Wichtige Voraussetzungen: Damit Let's Encrypt dein Zertifikat über die "HTTP-01 Challenge" validieren kann, müssen zwei Bedingungen erfüllt sein:
Deine Domain (und die www-Subdomain) müssen per A-Record auf die IP-Adresse deines Servers zeigen.
Port 80 (HTTP) muss in der aaPanel-Firewall geöffnet sein, da Let's Encrypt über diesen Port ein temporäres Verzeichnis (
.well-known/acme-challenge/) auf deinem Server abfragt.
Das Zertifikat ausstellen:
Gehe im aaPanel zu Website und klicke auf den Namen deiner Domain, um die Einstellungen zu öffnen.
Wechsle in den Reiter SSL und wähle Let's Encrypt aus.
Markiere deine Hauptdomain und (falls vorhanden) die www-Version.
Klicke auf Apply (oder Issue).
Das Panel beantragt nun das Zertifikat, was in der Regel 15 bis 30 Sekunden dauert. Sobald es ausgestellt ist, aktiviere im selben Fenster oben rechts zwingend den Schalter Force HTTPS. Dadurch schreibt aaPanel automatisch eine 301-Umleitung in deine Nginx-Konfiguration, sodass HTTP-Traffic immer sicher auf HTTPS gezwungen wird.
Let's Encrypt Zertifikate sind 90 Tage gültig. Das aaPanel richtet automatisch einen Cronjob (Task Scheduler) ein, der die Zertifikate 30 Tage vor Ablauf selbstständig verlängert.

Den aaPanel Nginx Reverse Proxy konfigurieren
Nachdem das SSL-Zertifikat aktiv ist und HTTP-Traffic zwingend auf HTTPS umgeleitet wird, müssen wir unseren Node.js-Prozess an diese öffentliche, verschlüsselte Domain anbinden. Nginx muss wissen, dass eingehende Anfragen auf [https://deine-domain.de](https://deine-domain.de) nicht aus einem statischen HTML-Ordner bedient, sondern an den internen Next.js-Port (z. B. 3000) weitergereicht werden sollen.
Öffne im aaPanel die Website-Einstellungen deiner Domain und wechsle in den Reiter Config (oder Nginx Configuration). Hier siehst du die von aaPanel generierte Standard-Konfiguration. Wir überschreiben nun das Routing für das Wurzelverzeichnis.
Suche nach dem Standard-Block location / { ... } (oder füge ihn hinzu, falls nicht vorhanden). Dieser Block fängt alle Seitenaufrufe ab. Anstatt hier Dateien auszuliefern, weisen wir Nginx an, als Reverse Proxy zu agieren:
1location / {
2 proxy_pass http://127.0.0.1:3000;
3 proxy_http_version 1.1;
4 proxy_set_header Host $host;
5 proxy_set_header X-Real-IP $remote_addr;
6 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
7 proxy_set_header X-Forwarded-Proto $scheme;
8}Mit proxy_set_header stellen wir sicher, dass essenzielle Metadaten (wie die echte IP-Adresse des Nutzers) an den Node.js-Prozess durchgereicht werden. Ohne diese Zeilen sähe Next.js jede Anfrage so, als käme sie lokal von der IP 127.0.0.1.
Die WebSocket-Falle: Echtzeitverbindungen ermöglichen
Ein kritischer Punkt bei SSR-Frameworks wie Next.js oder interaktiven Chat-Applikationen ist die WebSocket-Verbindung. Next.js nutzt WebSockets für das Hot-Reloading in der Entwicklung und für Server-Sent Events (SSE) im Produktionsbetrieb.
WebSockets stellen eine permanente, bidirektionale TCP-Verbindung zwischen Browser und Server her. Der Verbindungsaufbau beginnt als reguläre HTTP-Anfrage, die vom Browser durch spezielle Header als Protokollwechselanfrage markiert wird.
Standardmäßig kommuniziert Nginx mit Backend-Servern jedoch über das alte HTTP/1.0-Protokoll und verwirft sogenannte "Hop-by-Hop"-Header. Das führt dazu, dass der erforderliche Protokollwechsel (Handshake) vom Nginx-Proxy blockiert wird. Die WebSocket-Verbindung bricht mit einem Fehler 400 (Bad Request) ab oder wird stillschweigend fallen gelassen.
Um dies zu beheben, müssen wir das HTTP-Upgrade-Protokoll in unserem aaPanel Nginx Reverse Proxy explizit erlauben. Wir erweitern unsere Konfiguration um die entscheidenden Upgrade-Header:
1location / {
2 proxy_pass http://127.0.0.1:3000;
3
4 # Zwingend HTTP/1.1 für WebSockets nutzen
5 proxy_http_version 1.1;
6
7 # WebSocket Upgrade Header durchschleifen
8 proxy_set_header Upgrade $http_upgrade;
9 proxy_set_header Connection "upgrade";
10
11 # Standard Proxy Header
12 proxy_set_header Host $host;
13 proxy_set_header X-Real-IP $remote_addr;
14 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
15 proxy_set_header X-Forwarded-Proto $scheme;
16
17 # Caching für WebSocket-Upgrades umgehen
18 proxy_cache_bypass $http_upgrade;
19}Speichere die Datei. Das aaPanel prüft die Syntax und lädt den Nginx-Dienst im Hintergrund automatisch neu. Deine Next.js-App ist nun sicher über HTTPS erreichbar, profitiert von der schützenden SSL-Terminierung durch Nginx und unterstützt fehlerfreie, bidirektionale Echtzeitverbindungen.

Kryptografisches Hardening: Das A+ Rating bei SSL Labs
Ein aktives Let's Encrypt-Zertifikat liefert dir im Browser ein Schloss-Symbol, garantiert aber noch lange keine Enterprise-Sicherheit. Wenn du deine Domain nach dem Standard-Setup von aaPanel im unabhängigen "Qualys SSL Labs" Test scannst, erhältst du meist nur ein durchschnittliches "B" Rating. Der Grund: Standardkonfigurationen schleppen oft aus Gründen der Abwärtskompatibilität veraltete Protokolle (wie TLS 1.0 oder 1.1) und schwache Verschlüsselungsalgorithmen (Cipher Suites) mit.
Um modernen Angriffen wie Protokoll-Downgrades, Session-Hijacking oder Man-in-the-Middle-Attacken vorzubeugen, müssen wir die Nginx-Konfiguration kryptografisch härten. Unser Ziel ist das begehrte A+ Rating.
Öffne im aaPanel erneut die Konfiguration deiner Webseite und navigiere zum Reiter Config. Wir passen nun den HTTPS-Serverblock (listen 443 ssl) gezielt an.
1. Veraltete Protokolle deaktivieren
Streiche alle Hinweise auf TLSv1 und TLSv1.1 aus der Konfiguration. Wir zwingen Nginx dazu, ausschließlich die hochsicheren Protokolle TLS 1.2 und TLS 1.3 zu akzeptieren.
2. Strikte Chiffren (Cipher Suites) erzwingen
Wir definieren eine exakte Liste von Verschlüsselungsalgorithmen. Veraltete Algorithmen (wie RSA-Schlüsselaustausch oder 3DES) werden blockiert. Wir nutzen ausschließlich Verfahren, die Authenticated Encryption with Associated Data (AEAD) und Perfect Forward Secrecy (PFS) bereitstellen.
3. OCSP Stapling aktivieren
Normalerweise muss der Browser des Nutzers bei der Zertifizierungsstelle (Let's Encrypt) nachfragen, ob dein Zertifikat noch gültig oder bereits widerrufen ist. Das kostet bei jedem Seitenaufruf wertvolle Latenz. Mit OCSP Stapling übernimmt dein Nginx-Server diese Abfrage im Hintergrund, speichert das Ergebnis zwischen und liefert den kryptografischen Beweis direkt im ersten Handshake mit aus. Dafür müssen wir Nginx einen schnellen DNS-Resolver (wie Cloudflare 1.1.1.1 oder Google 8.8.8.8) zuweisen.
4. Security Headers (HSTS)
Wir injizieren HTTP Strict Transport Security (HSTS). Damit befehlen wir dem Browser des Besuchers, diese Domain (und alle Subdomains) für die nächsten zwei Jahre (max-age=63072000) ausschließlich verschlüsselt aufzurufen, selbst wenn der Nutzer manuell http:// in die Adresszeile tippt.
Ersetze oder ergänze in deinem 443-Serverblock die entsprechenden Zeilen, sodass sie folgendem Aufbau entsprechen:
1# Protokoll-Einschränkung: Ausschließlich TLS 1.2 und TLS 1.3 zulassen
2 ssl_protocols TLSv1.2 TLSv1.3;
3
4 # AEAD-Cipher-Suites für TLS 1.2 (TLS 1.3 wählt eigene Ciphers)
5 ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
6 ssl_prefer_server_ciphers off;
7
8 # SSL-Session-Optimierung für schnelleren Handshake bei Wiederkehrern
9 ssl_session_timeout 1d;
10 ssl_session_cache shared:SSL:50m;
11 ssl_session_tickets off;
12
13 # OCSP Stapling Einstellungen
14 ssl_stapling on;
15 ssl_stapling_verify on;
16 # Pfad zum Fullchain-Zertifikat von aaPanel (Domainnamen anpassen!)
17 ssl_trusted_certificate /www/server/panel/vhost/cert/DEINE_DOMAIN/fullchain.pem;
18 resolver 1.1.1.1 8.8.8.8 valid=300s;
19 resolver_timeout 5s;
20
21 # HSTS & Erweiterte Sicherheits-Header für das A+ Rating
22 add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
23 add_header X-Frame-Options "SAMEORIGIN" always;
24 add_header X-Content-Type-Options "nosniff" always;
25 add_header Referrer-Policy "strict-origin-when-cross-origin" always;Speichere die Konfiguration. Wenn du deine Domain nun bei SSL Labs (ssllabs.com) testest, wirst du mit einem sauberen A+ Rating belohnt. Dein Reverse Proxy liefert Node.js-Inhalte jetzt extrem performant und mit maximaler kryptografischer Sicherheit aus.

Teil der Serie
Vom Localhost zum Produktivserver (Ubuntu & aaPanel)
Häufig gestellte Fragen (FAQ)
Der mit Abstand häufigste Grund ist ein blockierter Port 80. Die Zertifizierungsstelle nutzt für die Verifizierung die sogenannte HTTP-01-Challenge. Dabei versucht Let's Encrypt, eine Prüfdatei im Ordner .well-known/acme-challenge/ unverschlüsselt über Port 80 abzurufen. Wenn dieser Port in der aaPanel-Firewall (oder der externen Firewall deines Cloud-Providers) geschlossen ist, scheitert der Vorgang. Ein weiterer Grund kann ein noch nicht vollständig propagierter DNS-A-Record sein.
Nginx ist für schnelle HTTP-Requests konfiguriert und schließt inaktive Proxy-Verbindungen standardmäßig nach 60 Sekunden (proxy_read_timeout). Da WebSockets – beispielsweise für Chat-Funktionen oder Live-Dashboards – oft längere Zeit ohne aktiven Datentransfer im Leerlauf (Idle) verbleiben, kappt Nginx die Verbindung. Du kannst dieses Problem lösen, indem du die Direktiven proxy_read_timeout und proxy_send_timeout für den WebSocket-Location-Block auf einen deutlich höheren Wert (z. B. 86400s für 24 Stunden) setzt.
Ja. Beim OCSP Stapling fragt dein Nginx-Server regelmäßig bei Let's Encrypt nach, ob das Zertifikat noch gültig ist, und liefert diesen Beweis an den Browser des Nutzers aus. Um den Let's Encrypt Server zu erreichen, muss Nginx dessen Domainnamen auflösen. Ohne die Angabe eines verlässlichen Resolvers (wie resolver 1.1.1.1 8.8.8.8 valid=300s;) schlägt diese Abfrage stumm fehl. Die Verschlüsselung funktioniert zwar weiterhin, aber der Geschwindigkeitsvorteil des Staplings geht verloren und das A+ Rating ist in Gefahr.
Dein nächster Schritt: Security Headers & Performance Tuning
Wir haben Nginx als perfekten Reverse-Proxy für unsere Node.js-Prozesse konfiguriert und die SSL/TLS-Verschlüsselung auf ein kompromissloses Enterprise-Niveau (A+ Rating) gehoben. Die Kommunikation ist nun absolut abhörsicher.
Doch ein sicherer Transportweg schützt nicht vor Angriffen auf Applikationsebene. Standardmäßig sendet Nginx noch immer HTTP-Header, die potenziellen Angreifern unnötig viele Informationen liefern und Browser-Schutzmechanismen ungenutzt lassen.
Im fünften Teil der Masterclass modifizieren wir die Kern-Templates von Nginx direkt im aaPanel, damit unsere Anpassungen auch nach System-Updates erhalten bleiben. Wir implementieren mächtige Sicherheitsrichtlinien wie die Content-Security-Policy (CSP) gegen Cross-Site Scripting (XSS) und X-Frame-Options gegen Clickjacking. Um gleichzeitig die Ladezeiten für Next.js zu maximieren, werfen wir veraltete Gzip-Routinen über Bord und aktivieren die hochgradig effiziente Brotli-Kompression für alle statischen Assets.
Jetzt starten: Teil 5 – Security Headers & Fine-Tuning in Nginx: A+ Rating

Dietrich Bojko
Senior Webentwickler
Webinteger arbeitet seit vielen Jahren produktiv mit
Linux-basierten Entwicklungsumgebungen unter Windows.
Der Fokus liegt auf
performanten Setups mit WSL 2, Docker, PHP, Node.js und modernen
Build-Tools in realen Projekten –
nicht auf theoretischen Beispielkonfigurationen.
Die Artikel dieser Serie entstehen direkt aus dem täglichen Einsatz in Kunden- und Eigenprojekten und dokumentieren bewusst auch typische Fehler, Engpässe und bewährte Workarounds.


