Problem: Absicherung von WebSocket-Verbindungen mit NGINX
Das Einrichten eines Reverse Proxy für WebSocket-Verbindungen kann schwierig sein, besonders wenn man es sicher gestalten möchte. NGINX ist ein Webserver, der diese Aufgabe erfüllen kann, aber man muss wissen, wie man ihn richtig konfiguriert.
Konfiguration von NGINX für sicheren WebSocket-Proxy
NGINX-Installation einrichten
Um NGINX für einen sicheren WebSocket-Proxy einzurichten, müssen Sie ihn auf Ihrem Server installieren. Hier sind die Schritte:
-
Aktualisieren Sie Ihren Paketmanager:
sudo apt update
-
Installieren Sie NGINX:
sudo apt install nginx
-
Starten Sie den NGINX-Dienst:
sudo systemctl start nginx
-
Aktivieren Sie NGINX, damit es beim Systemstart automatisch startet:
sudo systemctl enable nginx
SSL/TLS-Zertifikat-Konfiguration
Für sichere WebSocket-Verbindungen benötigen Sie SSL/TLS-Zertifikate. So erhalten und konfigurieren Sie diese:
-
Installieren Sie Certbot für kostenlose Let's Encrypt-Zertifikate:
sudo apt install certbot python3-certbot-nginx
-
Beantragen Sie ein Zertifikat für Ihre Domain:
sudo certbot --nginx -d ihredomain.de
-
Folgen Sie den Anweisungen, um die Zertifikatinstallation abzuschließen.
NGINX-Konfiguration für WebSocket-Proxy
Nun richten Sie NGINX ein, um WebSocket-Verbindungen zu proxyen:
-
Öffnen Sie die NGINX-Konfigurationsdatei:
sudo nano /etc/nginx/sites-available/default
-
Fügen Sie diese Konfiguration hinzu, um WebSocket-Unterstützung zu aktivieren:
server { listen 443 ssl; server_name ihredomain.de; ssl_certificate /etc/letsencrypt/live/ihredomain.de/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ihredomain.de/privkey.pem; location /websocket/ { proxy_pass http://backend_host; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
Ersetzen Sie
ihredomain.de
durch Ihre Domain undbackend_host
durch die Adresse Ihres WebSocket-Servers. -
Speichern Sie die Datei und beenden Sie den Editor.
-
Testen Sie die NGINX-Konfiguration:
sudo nginx -t
-
Wenn der Test erfolgreich ist, laden Sie NGINX neu:
sudo systemctl reload nginx
Diese Konfiguration richtet NGINX so ein, dass es auf Port 443 für SSL-Verbindungen lauscht, die zuvor erhaltenen SSL-Zertifikate verwendet und WebSocket-Verbindungen zu Ihrem Backend-Server weiterleitet.
Beispiel: Umgang mit WebSocket-Timeouts
Um zu verhindern, dass WebSocket-Verbindungen unterbrochen werden, können Sie diese Direktiven zu Ihrer NGINX-Konfiguration hinzufügen:
location /websocket/ {
proxy_pass http://backend_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
Dies setzt die Lese- und Sendetimeouts auf 1 Stunde (3600 Sekunden), was bei langlebigen WebSocket-Verbindungen hilft.
Implementierung von WebSocket-Proxy-Einstellungen
Proxy Pass-Direktiven
So richten Sie die proxy_pass-Direktive für WebSocket-Verkehr in NGINX ein:
-
Öffnen Sie Ihre NGINX-Konfigurationsdatei:
sudo nano /etc/nginx/sites-available/default
-
Fügen Sie im location-Block für WebSocket-Verbindungen die proxy_pass-Direktive hinzu:
location /websocket/ { proxy_pass http://ihr_websocket_server; }
Ersetzen Sie "ihr_websocket_server" durch die Adresse Ihres WebSocket-Servers.
Tipp: SSL für WebSocket-Verbindungen verwenden
Um Ihre WebSocket-Verbindungen abzusichern, verwenden Sie SSL/TLS. Ändern Sie Ihre proxy_pass-Direktive, um HTTPS zu verwenden:
location /websocket/ {
proxy_pass https://ihr_websocket_server;
}
Dies hilft, die zwischen Client und Server übertragenen Daten zu schützen.
Header-Modifikationen
So richten Sie die Header für die WebSocket-Kommunikation ein:
-
Fügen Sie im selben location-Block diese Header-Modifikationen hinzu:
location /websocket/ { proxy_pass http://ihr_websocket_server; 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; }
Diese Header helfen, die ursprünglichen Client-Informationen beim Durchlaufen des Proxys beizubehalten.
Handhabung von Connection Upgrades
So verwalten Sie WebSocket-Verbindungs-Upgrades durch NGINX:
-
Fügen Sie diese Direktiven zu Ihrem location-Block hinzu:
location /websocket/ { proxy_pass http://ihr_websocket_server; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
Die 'Upgrade'- und 'Connection'-Header sind für den WebSocket-Protokoll-Handshake erforderlich.
-
Speichern Sie die Datei und beenden Sie den Editor.
-
Testen Sie Ihre NGINX-Konfiguration:
sudo nginx -t
-
Wenn der Test erfolgreich ist, laden Sie NGINX neu:
sudo systemctl reload nginx
Diese Einstellungen ermöglichen es NGINX, WebSocket-Verbindungen zu handhaben, einschließlich des initialen Handshakes und der Kommunikation.
Feinabstimmung von NGINX für optimale WebSocket-Leistung
Timeout-Einstellungen
Um langlebige WebSocket-Verbindungen zu handhaben, passen Sie die proxy_read_timeout-Einstellung in Ihrer NGINX-Konfiguration an:
-
Öffnen Sie Ihre NGINX-Konfigurationsdatei:
sudo nano /etc/nginx/sites-available/default
-
Fügen Sie in Ihrem WebSocket-Location-Block die proxy_read_timeout-Direktive hinzu oder ändern Sie sie:
location /websocket/ { proxy_pass http://ihr_websocket_server; proxy_read_timeout 3600s; }
Dies setzt den Lese-Timeout auf 1 Stunde (3600 Sekunden), was für die meisten WebSocket-Anwendungen gut ist.
-
Sie können auch proxy_send_timeout hinzufügen:
proxy_send_timeout 3600s;
Optimierung der Puffergröße
Um die Puffergrößen für WebSocket-Verkehr zu optimieren:
-
Fügen Sie im selben Location-Block diese Direktiven hinzu:
location /websocket/ { proxy_pass http://ihr_websocket_server; proxy_buffering off; proxy_buffer_size 4k; proxy_buffers 4 4k; }
- proxy_buffering off: Dies schaltet die Pufferung von Antworten vom Proxy-Server aus, was oft gut für WebSocket-Verbindungen ist.
- proxy_buffer_size 4k: Dies setzt die Größe des Puffers für das Lesen des ersten Teils der Antwort vom Proxy-Server.
- proxy_buffers 4 4k: Dies legt die Anzahl und Größe der Puffer für eine einzelne Verbindung fest.
-
Wenn Sie große Nachrichten erwarten, müssen Sie diese Werte möglicherweise erhöhen:
proxy_buffer_size 8k; proxy_buffers 8 8k;
-
Speichern Sie die Datei und beenden Sie den Editor.
-
Testen Sie Ihre NGINX-Konfiguration:
sudo nginx -t
-
Wenn der Test erfolgreich ist, laden Sie NGINX neu:
sudo systemctl reload nginx
Testen und Fehlerbehebung
Überprüfung sicherer WebSocket-Verbindungen
So testen Sie Ihre WebSocket-Proxy-Einrichtung:
-
Verwenden Sie Online-WebSocket-Testtools:
- Besuchen Sie websocket.org/echo.html
- Geben Sie Ihre WebSocket-URL ein (wss://ihredomain.de/websocket)
- Klicken Sie auf "Connect" und prüfen Sie, ob die Verbindung funktioniert
-
Verwenden Sie Kommandozeilen-Tools:
- Installieren Sie wscat:
npm install -g wscat
- Verbinden Sie sich mit Ihrem WebSocket-Server:
wscat -c wss://ihredomain.de/websocket
- Senden Sie eine Nachricht und prüfen Sie, ob Sie eine Antwort erhalten
- Installieren Sie wscat:
-
Überprüfen Sie NGINX-Logs:
- Fehlerprotokolle anzeigen:
sudo tail -f /var/log/nginx/error.log
- Zugriffsprotokoll
- Fehlerprotokolle anzeigen:
e anzeigen: sudo tail -f /var/log/nginx/access.log
- Verwenden Sie Browser-Entwicklertools:
- Öffnen Sie Ihre Webanwendung
- Gehen Sie zum Netzwerk-Tab
- Filtern Sie nach WebSocket-Verbindungen
- Prüfen Sie, ob die Verbindung aufgebaut wird und Nachrichten gesendet/empfangen werden
Tipp: Browser-Konsole für WebSocket-Debugging verwenden
Öffnen Sie die Konsole Ihres Browsers (normalerweise F12 oder Strg+Umschalt+I) und fügen Sie den folgenden Code hinzu, um WebSocket-Ereignisse zu überwachen:
var ws = new WebSocket("wss://ihredomain.de/websocket");
ws.onopen = function() { console.log("WebSocket verbunden"); };
ws.onmessage = function(evt) { console.log("Empfangen: " + evt.data); };
ws.onclose = function() { console.log("WebSocket geschlossen"); };
ws.onerror = function(err) { console.log("WebSocket-Fehler: ", err); };
Dies protokolliert WebSocket-Ereignisse in Echtzeit und hilft Ihnen bei der Fehlersuche bei Verbindungsproblemen.
Häufige Probleme und Lösungen
-
Verbindung verweigert:
- Prüfen Sie, ob Ihr WebSocket-Server läuft
- Stellen Sie sicher, dass die proxy_pass-Direktive auf die richtige Adresse und den richtigen Port zeigt
-
SSL-Zertifikatfehler:
- Stellen Sie sicher, dass Ihre SSL-Zertifikate gültig und nicht abgelaufen sind
- Überprüfen Sie, ob die Zertifikatdateien in der NGINX-Konfiguration korrekt referenziert sind
-
WebSocket-Handshake schlägt fehl:
- Überprüfen Sie, ob die Upgrade- und Connection-Header korrekt gesetzt sind
- Stellen Sie sicher, dass proxy_http_version auf 1.1 gesetzt ist
-
Timeouts bei lang laufenden Verbindungen:
- Erhöhen Sie die Werte für proxy_read_timeout und proxy_send_timeout
- Implementieren Sie einen Ping-Pong-Mechanismus in Ihrer WebSocket-Anwendung
-
Große Nachrichten werden nicht übertragen:
- Erhöhen Sie client_max_body_size in Ihrer NGINX-Konfiguration
- Passen Sie proxy_buffer_size und proxy_buffers bei Bedarf an
-
Cross-Origin Resource Sharing (CORS)-Probleme:
- Fügen Sie Header hinzu, um CORS zu erlauben:
add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
- Fügen Sie Header hinzu, um CORS zu erlauben:
-
HTTP/2-Kompatibilitätsprobleme:
- Wenn Sie HTTP/2 verwenden, fügen Sie
proxy_set_header Connection "";
zu Ihrem Location-Block hinzu
- Wenn Sie HTTP/2 verwenden, fügen Sie