Hoe NGINX Instellen Als Reverse Proxy Voor Veilige WebSockets?

Gepubliceerd 12 juli 2024

Probleem: WebSocket-verbindingen Beveiligen met NGINX

Het opzetten van een reverse proxy voor WebSocket-verbindingen kan moeilijk zijn, vooral wanneer je het veilig wilt houden. NGINX is een webserver die deze taak kan uitvoeren, maar je moet weten hoe je het correct moet instellen.

NGINX Configureren voor Veilige WebSocket Proxy

NGINX Installatie Opzetten

Om NGINX in te stellen voor een veilige WebSocket proxy, moet je het op je server installeren. Hier zijn de stappen:

  1. Update je pakketbeheerder:

    sudo apt update
  2. Installeer NGINX:

    sudo apt install nginx
  3. Start de NGINX service:

    sudo systemctl start nginx
  4. Schakel NGINX in om bij het opstarten te starten:

    sudo systemctl enable nginx

SSL/TLS Certificaat Configuratie

Voor veilige WebSocket-verbindingen heb je SSL/TLS-certificaten nodig. Zo verkrijg en configureer je ze:

  1. Installeer Certbot voor gratis Let's Encrypt certificaten:

    sudo apt install certbot python3-certbot-nginx
  2. Verkrijg een certificaat voor je domein:

    sudo certbot --nginx -d jouwdomein.com
  3. Volg de aanwijzingen om de certificaatinstallatie te voltooien.

NGINX Configuratie voor WebSocket Proxy

Stel nu NGINX in om WebSocket-verbindingen te proxyen:

  1. Open het NGINX configuratiebestand:

    sudo nano /etc/nginx/sites-available/default
  2. Voeg deze configuratie toe om WebSocket-ondersteuning in te schakelen:

    server {
       listen 443 ssl;
       server_name jouwdomein.com;
    
       ssl_certificate /etc/letsencrypt/live/jouwdomein.com/fullchain.pem;
       ssl_certificate_key /etc/letsencrypt/live/jouwdomein.com/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";
       }
    }

    Vervang jouwdomein.com met je domein en backend_host met het adres van je WebSocket-server.

  3. Sla het bestand op en sluit de editor af.

  4. Test de NGINX configuratie:

    sudo nginx -t
  5. Als de test slaagt, herlaad NGINX:

    sudo systemctl reload nginx

Deze configuratie stelt NGINX in om te luisteren op poort 443 voor SSL-verbindingen, de SSL-certificaten te gebruiken die je eerder hebt verkregen, en WebSocket-verbindingen naar je backend-server te proxyen.

Example: WebSocket Time-outs Afhandelen

Om te voorkomen dat WebSocket-verbindingen een time-out krijgen, kun je deze richtlijnen toevoegen aan je NGINX configuratie:

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;
}

Dit stelt de lees- en verzend-time-outs in op 1 uur (3600 seconden), wat helpt om langdurige WebSocket-verbindingen te behouden.

WebSocket Proxy-instellingen Implementeren

Proxy Pass Richtlijnen

Om de proxy_pass richtlijn in te stellen voor WebSocket-verkeer in NGINX:

  1. Open je NGINX configuratiebestand:

    sudo nano /etc/nginx/sites-available/default
  2. Voeg in het location-blok voor WebSocket-verbindingen de proxy_pass richtlijn toe:

    location /websocket/ {
       proxy_pass http://jouw_websocket_server;
    }

    Vervang "jouw_websocket_server" met het adres van je WebSocket-server.

Tip: Gebruik SSL voor WebSocket-verbindingen

Om je WebSocket-verbindingen te beveiligen, gebruik SSL/TLS. Wijzig je proxy_pass richtlijn om HTTPS te gebruiken:

location /websocket/ {
    proxy_pass https://jouw_websocket_server;
}

Dit helpt de gegevens te beschermen die tussen de client en de server worden verzonden.

Header Aanpassingen

Om de headers in te stellen voor WebSocket-communicatie:

  1. Voeg in hetzelfde location-blok deze header-aanpassingen toe:

    location /websocket/ {
       proxy_pass http://jouw_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;
    }

    Deze headers helpen de oorspronkelijke clientinformatie te behouden bij het doorgeven via de proxy.

Connection Upgrade Afhandeling

Om WebSocket-verbinding-upgrades te beheren via NGINX:

  1. Voeg deze richtlijnen toe aan je location-blok:

    location /websocket/ {
       proxy_pass http://jouw_websocket_server;
       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "upgrade";
    }

    De 'Upgrade' en 'Connection' headers zijn nodig voor de WebSocket-protocol handshake.

  2. Sla het bestand op en sluit de editor af.

  3. Test je NGINX configuratie:

    sudo nginx -t
  4. Als de test succesvol is, herlaad NGINX:

    sudo systemctl reload nginx

Deze instellingen stellen NGINX in staat om WebSocket-verbindingen af te handelen, inclusief de initiële handshake en communicatie.

NGINX Fijnafstellen voor Optimale WebSocket-prestaties

Timeout Instellingen

Om langdurige WebSocket-verbindingen af te handelen, pas je de proxy_read_timeout instelling aan in je NGINX configuratie:

  1. Open je NGINX configuratiebestand:

    sudo nano /etc/nginx/sites-available/default
  2. Voeg in je WebSocket location-blok de proxy_read_timeout richtlijn toe of wijzig deze:

    location /websocket/ {
       proxy_pass http://jouw_websocket_server;
       proxy_read_timeout 3600s;
    }

    Dit stelt de lees-timeout in op 1 uur (3600 seconden), wat goed is voor de meeste WebSocket-applicaties.

  3. Je kunt ook proxy_send_timeout toevoegen:

    proxy_send_timeout 3600s;

Buffergrootte Optimalisatie

Om buffergroottes te optimaliseren voor WebSocket-verkeer:

  1. Voeg in hetzelfde location-blok deze richtlijnen toe:

    location /websocket/ {
       proxy_pass http://jouw_websocket_server;
       proxy_buffering off;
       proxy_buffer_size 4k;
       proxy_buffers 4 4k;
    }
    • proxy_buffering off: Dit schakelt buffering van reacties van de geproxyde server uit, wat vaak goed is voor WebSocket-verbindingen.
    • proxy_buffer_size 4k: Dit stelt de grootte in van de buffer voor het lezen van het eerste deel van de reactie van de geproxyde server.
    • proxy_buffers 4 4k: Dit stelt het aantal en de grootte van buffers in voor een enkele verbinding.
  2. Als je grote berichten verwacht, moet je mogelijk deze waarden verhogen:

    proxy_buffer_size 8k;
    proxy_buffers 8 8k;
  3. Sla het bestand op en sluit de editor af.

  4. Test je NGINX configuratie:

    sudo nginx -t
  5. Als de test slaagt, herlaad NGINX:

    sudo systemctl reload nginx

Testen en Probleemoplossing

Veilige WebSocket-verbindingen Verifiëren

Om je WebSocket proxy-setup te testen:

  1. Gebruik online WebSocket-testtools:

    • Bezoek websocket.org/echo.html
    • Voer je WebSocket-URL in (wss://jouwdomein.com/websocket)
    • Klik op "Connect" en controleer of de verbinding werkt
  2. Gebruik commandoregel-tools:

    • Installeer wscat: npm install -g wscat
    • Maak verbinding met je WebSocket-server: wscat -c wss://jouwdomein.com/websocket
    • Stuur een bericht en controleer of je een reactie krijgt
  3. Controleer NGINX-logs:

    • Bekijk foutlogs: sudo tail -f /var/log/nginx/error.log
    • Bekijk toegangslogs: sudo tail -f /var/log/nginx/access.log
  4. Gebruik browser ontwikkelaarstools:

    • Open je webapplicatie
    • Ga naar het Network-tabblad
    • Filter op WebSocket-verbindingen
    • Controleer of de verbinding is opgezet en berichten worden verzonden/ontvangen

Tip: Gebruik Browser Console voor WebSocket Debugging

Open de console van je browser (meestal F12 of Ctrl+Shift+I) en voeg de volgende code toe om WebSocket-gebeurtenissen te monitoren:

var ws = new WebSocket("wss://jouwdomein.com/websocket");
ws.onopen = function() { console.log("WebSocket verbonden"); };
ws.onmessage = function(evt) { console.log("Ontvangen: " + evt.data); };
ws.onclose = function() { console.log("WebSocket gesloten"); };
ws.onerror = function(err) { console.log("WebSocket fout: ", err); };

Dit zal WebSocket-gebeurtenissen in realtime loggen, wat je helpt verbindingsproblemen te debuggen.

Veelvoorkomende Problemen en Oplossingen

  1. Verbinding geweigerd:

    • Controleer of je WebSocket-server draait
    • Verifieer dat de proxy_pass richtlijn naar het juiste adres en poort wijst
  2. SSL-certificaatfouten:

    • Zorg ervoor dat je SSL-certificaten geldig zijn en niet verlopen
    • Controleer of de certificaatbestanden correct worden gerefereerd in de NGINX configuratie
  3. WebSocket-handshake mislukt:

    • Verifieer dat de Upgrade en Connection headers correct zijn ingesteld
    • Zorg ervoor dat proxy_http_version is ingesteld op 1.1
  4. Time-outs tijdens langdurige verbindingen:

    • Verhoog proxy_read_timeout en proxy_send_timeout waarden
    • Implementeer een ping-pong mechanisme in je WebSocket-applicatie
  5. Grote berichten worden niet verzonden:

    • Verhoog client_max_body_size in je NGINX configuratie
    • Pas proxy_buffer_size en proxy_buffers indien nodig aan
  6. Cross-Origin Resource Sharing (CORS) problemen:

    • Voeg headers toe om CORS toe te staan:
      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';
  7. HTTP/2 compatibiliteitsproblemen:

    • Bij gebruik van HTTP/2, voeg proxy_set_header Connection ""; toe aan je location-blok