sta / websocket-sharp

A C# implementation of the WebSocket protocol client and server
http://sta.github.io/websocket-sharp
MIT License
5.73k stars 1.66k forks source link

Cannot deploy Secure Websocket Sharp server using ubuntu and nginx reverse proxy #740

Closed waggyman closed 11 months ago

waggyman commented 11 months ago

Hello there, currently I am facing some issue on deploying the Secured Websocket (WSS) using Websocket Sharp as the server.

Here is my code right now:

# main.cs

var wss = new WebSocketServer("wss://server_ip_address:9050");
wss.AddWebSocketService<MyWebSocketService>("/g11");
wss.Start();

And here is the nginx configuration:

server {
    server_name mydomain.com;
    root /var/www/laravelapp/public;

    location /g11 {
        proxy_pass http://server_ip_address:9050; # Assuming WebSocket server is running on port 9050
        proxy_http_version 1.1;  # you need to set this in order to use params below.
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header 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_read_timeout 86400; # Set a longer timeout if needed
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/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
}

Then I am connecting using my NodeJS Client

// client.js

const express = require('express');
const WebSocket = require('ws');

const server = express()
  .use((req, res) => {
    res.send("HELLO WORLD!")
  })
  .listen(3000, () => {
    let webSocket = new WebSocket('wss://mydomain.com:9050/g11');
    let el;

    webSocket.onopen = (event) => {
        console.log("WEBSOCKET OPENED");
        webSocket.send(`PING SERVER @ ${new Date().toUTCString()}`)
    }

    webSocket.onmessage = (event) => {
        console.log("EVENT RECEIVED", event.data);
    }
    console.log(`Listening on ${3000}`)
});

And when I run my node js client using :

node client.js

I got this error:

Error: Client network socket disconnected before secure TLS connection was established

Is there any missing configuration that I made from above snippets?

waggyman commented 11 months ago

I found the solution. You don't need to include the proxy_set_header Host anymore in the nginx configuration. Since the websocket sharp server not rely on HTTP.

Once I remove the proxy_set_header Host in the nginx conf. I can access the websocket using wss://mydomain.com/g11

waggyman commented 11 months ago

Correct nginx configuration

server {
    server_name mydomain.com;
    root /var/www/laravelapp/public;

    location /g11 {
        proxy_pass http://server_ip_address:9050; # Assuming WebSocket server is running on port 9050
        proxy_http_version 1.1;  # you need to set this in order to use params below.
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        #
        #proxy_set_header Host $host; #No need this because websocket not rely on HTTP
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/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
}
purpleguy99 commented 5 months ago

I found the solution. You don't need to include the proxy_set_header Host anymore in the nginx configuration. Since the websocket sharp server not rely on HTTP.

Once I remove the proxy_set_header Host in the nginx conf. I can access the websocket using wss://mydomain.com/g11

Alright, this is the solution. Thanks!