3

My website is running via HTTPS at a public hoster and connects to a node server that is running on a Raspberry PI.

There is also a piece of hardware (lets call it decoder) in the same network with the PI which sends a data stream via TCP. The purpose of the PI is to read that stream and send it via WebSocket to the browser. So the goal is to output that stream on my website.

Now I'm running in a mixes content problem and have no idea how to solve it.

What I have done so far is to install an nginx webserver on the PI and have installed a Letsencrypt certificate. Both are running fine (tested via normal https:// call in a webbrowser).

The Websocket connection without SSL works fine as well and I get the data, but with SSL wont work. I guess that the problem is, that the decoder is not able to handle SSL.

So how can I "send", "convert", "tunnel" or "proxy" the non-SSL data stream to a HTTPS server?

Update

@Jake Holzinger: you are absolutely right. The given information was not enough. Sorry! I try to clarify:

  1. nginx is without any further modification. So it is the configuration which comes from the installation
  2. the website (Angular) does a let connection = new WebSocket('wss://domain:port');
  3. The node server looks like follows:

    const net = require('net');
    const fs = require('fs');
    const https = require('https');
    const date = require('date-and-time');
    const config = require('./server-config.json');
    const httpProxy = require('http-proxy');
    
    //  SSL SERVER
    try {
        const privateKey = fs.readFileSync('/etc/letsencrypt/live/' + config.DNSROUTER + '/privkey.pem', 'utf8');
        const certificate = fs.readFileSync('/etc/letsencrypt/live/' + config.DNSROUTER + '/cert.pem', 'utf8');
        const ca = fs.readFileSync('/etc/letsencrypt/live/' + config.DNSROUTER + '/chain.pem', 'utf8');
    
        const options = {
                key: privateKey,
                cert: certificate,
                ca: ca
        };
    
        let proxy = httpProxy.createServer({
            target: 'ws://localhost:9030',
            ssl: {
                key: privateKey,
                cert: certificate
            }
        }).listen(9031);
    }
    catch (e) {
        console.log("LETSENCRYPT certificates not found! No SSL!");
        console.log(e)
    }
    
    /**
     *  server
     */
    let connections = {};
    let WebSocketServer = require('ws').Server;
    
    // start WS via HTTP
    const wss1 = new WebSocketServer({port: 9030});
    
    wss1.on('connection', function(ws) {
        CLIENTS.push(ws);
        console.log('connection via HTTP');
    
        ws.on('close', function () {
            console.log('close HTTP!');
            CLIENTS = CLIENTS.filter(item => item != ws);
        })
    })
    
    
    /**
     *  client
     */
    let connect = function() {
    
                    console.log(now(), 'Starting server...');
    
                    const socket = net.createConnection({ port: config.PORT, host: config.HOST }, () => {
                        console.log('Connected to server!');
                    })
    
                    socket.on('connect', () => {
                        console.log(now(), 'Connected to server!');
    
                        socket.on('data', data => {
                            sendAll(data);
                        });
                    });
    
                    socket.on('error', data => {
                        console.log(now(), "Connnection refused:", data.errno,data.code,"(IP:", data.address + ":" + data.port + ")");
    
                        setTimeout(() => {
                            socket.removeAllListeners();
    
                            console.log(now(),"Reconnecting...");
                            connect();
                        }, 1000);
                    });
    
                    socket.on('end', () => {
                        console.log(now(), 'Disconnected from server');
                        console.log(now(), "Reconnecting...");
    
                        socket.removeAllListeners();
                        connect();
                    });
    }
    
    connect();
    

I hope that this will get a better impression. Thx for your help!

Lars
  • 920
  • 1
  • 14
  • 34
  • Does the client (web browser) attempt to create a secure websocket connection (`wss://`) when you are browsing over a secure connection (`https://`)? Can you provide your NGINX configuration? Can you share your server code? There is not enough information here to provide a detailed answer. – Jake Holzinger Feb 25 '19 at 21:59

1 Answers1

0

Now I solved this issue in a different way.

Instead of creating a proxy server node implementation, I've have created the reverse-proxy on nginx webserver level to proxy all HTTPS -> HTTP calls to the PI. The code below is working fine for me now.

sudo nano /etc/nginx/sites-available/default

and change the content like this:

server {
    listen 9031 ssl;

    ssl_certificate /etc/letsencrypt/live/DOMAIN_DNS/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/DOMAIN_DNS/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:9030;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;
    }
}
Lars
  • 920
  • 1
  • 14
  • 34