question

ezra avatar image
ezra asked

Remote LAN console over HTTPS

Hello!


Just setup my entire offgrid system. Now for security and compatibility reasons i'd like to have my remote console (LAN) served over HTTPS.


I've tried to gain root access and SSH in, tried to find some apache/nginx config but, not found any.

When setting up a reverse proxy via nginx (other machine to the ccgx) the css and images do not load and render the remote console useless (on the reverse proxy url that is)


Please advise.


Background:

Trying to intergrate the remote console with an iframe in Home assistant (needs to be HTTPS)

CCGX Color Control
4 comments
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

matt1309 avatar image matt1309 commented ·
Hey Ezra, did you ever manage to resolve this. I'm looking for a similar config, albeit for different reasons.

I think I've managed to get stuck on the same stage as you. Setup reverse proxy but get stuck at the loading page which shows console errors of ws (plain text) connections via HTTPS connection. Not sure it's possible to upgrade the ws request to WSS with nginx alone might need to edit the webserver in venus for that to connect to the ws via https, but I'm not clued up enough to say that with confidence, just guessing.

Thanks,

Matt

0 Likes 0 ·
matt1309 avatar image matt1309 matt1309 commented ·

Got slightly further. I firstly I didnt use domain.com/app as thought it being non root would cause issues so i went with app.domain.com. Which resolved most errors apart from the ws vs wss error (the "mixed content error" in chrome screenshot below).


I then went a different route. Rather than trying to make all of Hiawatha use ssl. I instead thought i could just go through the js scripts calling the websockets and change them to wss requests and then use nginx reverse proxy to take wss back to ws internal ip.


Unfortunately my javascript knowledge is zero. So I've given up at this point. I'll likely resort to saving the data to influxdb and a grafana gui, it's a shame the venus os webui is quite nice.

Posting just incase this is useful for anyone else with javascript knowledge.

0 Likes 0 ·
ngknick avatar image ngknick matt1309 commented ·
Did you ever find a way to integrate with home assistant?
0 Likes 0 ·
matt1309 avatar image matt1309 ngknick commented ·

Hi @NGKnick


I wasn't using for home assistant. I was just using for reference proxy. (by guessing you need that for reverse proxy to add into homeassistant from outside LAN?)

I've stopped using this method and so not sure if newer versions of venus os solve this anyway but here was my solution:

Nginx reverse proxy - Victron Community (victronenergy.com)

I imagine the issue there is it'll work on LAN as it uses websockets to connect to xvnc (at least it used to). So your browser will make the connection on LAN.

Assuming nothing has changed since i looked at this then you'll need to setup reverse proxy to add ssl to venus os page. then edit the index.php for the javascript change i made in the link above. Then it should work inside and outside of LAN. (The editting might not be needed anymore, would have to test it to see if it worked)


(Tbh most folk just use MQTT to integrate into homeassistant)

0 Likes 0 ·
3 Answers
eliott avatar image
eliott answered ·

Hi!


what I would do is to replicate the /service/ssh-tunnel functionality and create a reverse tunnel to your local computer. this way you could also have ssh access from home


3 comments
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

ezra avatar image ezra commented ·

Could you explain a bit more? You mean create a reverse ssh tunnel to mount the port http on the local machine?

I'm trying to try if it works if i mount an sshfs on my nignx server and then serve up that directory over https on my nginx box. Not working out so far.

0 Likes 0 ·
ezra avatar image ezra ezra commented ·
sudo ssh -4 -L 888:192.168.x.x:80 root@192.168.x.x

This doesn't work, gives:

Failed to connect. Make sure to enable Remote Console for LAN, and reboot the device.

On the web page, it does load. Sure it has something to do with the html site requesting stuff on localhost, which now, is not valid since its forwarded.

0 Likes 0 ·
ezra avatar image ezra ezra commented ·

Same thing goes for SSHFS, serving it on my localhost to nginx also gives the above error.

sshfs -o allow_other victron:/var/www/venus/ /var/www/html/
0 Likes 0 ·
markus avatar image
markus answered ·

Just an idea: maybe its possible to configure the Hiawatha web server (used in VenusOS) for SSL connections: https://www.hiawatha-webserver.org/howto/bindings

Regards,

Markus

4 comments
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

markus avatar image markus ♦♦ commented ·

I move this thread to Mod space. I think it's better fitted there.

0 Likes 0 ·
ezra avatar image ezra commented ·

Thanks Markus, been trying that.

https://community.victronenergy.com/questions/19229/hiawatha-webserver-not-starting-when-https-enabled.html

0 Likes 0 ·
Show more comments
ezra avatar image
ezra answered ·

Ok I managed to setup a proxy for the websockets on 7890 and 9001 and its working, just only on HTTP, but I got further then ever (3 days and counting).

HTTPS gives a mixed content error, though i was quite sure i was proxying it from Venus ws to nginx WSS:


I'll post my nginx config below:


http {
   include       mime.types;
   default_type  application/octet-stream;

   sendfile on;
   tcp_nopush on;
   tcp_nodelay on;
   keepalive_timeout 65;
   types_hash_max_size 2048;

   access_log /var/log/nginx/access.log;
   error_log /var/log/nginx/error.log;

   gzip on;
   gzip_disable "msie6";

   map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
   }

   upstream websockets {
    server VENUS-IP:9001;
    server VENUS-IP:7890;
   
    check interval=3000 rise=2 fall=5 timeout=1000;
   }

   ##############################
   ########## HTTP ##############
   ##############################

   server {
    listen 80;
    server_name nginx.localdomain.nl;

    location /app {

      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_pass          http://VENUS-IP;
      proxy_read_timeout  90;

      proxy_redirect      http://VENUS-IP http://nginx.localdomain.nl;
    }            

   }

   ##############################
   ########## HTTPS #############
   ##############################

   server {
    listen 443 ssl http2;
    server_name nginx.localdomain.nl;

    ssl_certificate /usr/local/etc/nginx/certs/cert.crt;
    ssl_certificate_key /usr/local/etc/nginx/certs/cert.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    ssl_protocols TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    ssl_prefer_server_ciphers on;

    add_header Strict-Transport-Security max-age=15768000;

    resolver 192.168.7.1;

    ##############################
    ########## VENUS #############
    ##############################

    location /app {

      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_pass          http://VENUS-IP;
      proxy_read_timeout  90;

      proxy_redirect      http://VENUS-IP https://nginx.localdomain.nl;
    }            


    include /etc/nginx/include/reverse/*.conf;
   }

   ##############################
   ####### WEBSCOCKETS ##########
   ##############################

    server {
        server_name nginx.localdomain.nl;
        listen 9001; # ssl;

        #ssl_certificate /usr/local/etc/nginx/certs/cert.crt;
        #ssl_certificate_key /usr/local/etc/nginx/certs/cert.key;

        location / {
            # redirect all HTTP traffic
            proxy_pass http://websockets;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            # WebSocket support
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";             
        }
    }

    server {
        server_name nginx.localdomain.nl;
        listen 7890; #ssl;

        #ssl_certificate /usr/local/etc/nginx/certs/cert.crt;
        #ssl_certificate_key /usr/local/etc/nginx/certs/cert.key;

        location / {
            # redirect all HTTP traffic
            proxy_pass http://websockets;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            # WebSocket support
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";             
        }
    }
}

I've tried the 7890 and 9001 proxys with ssl by uncommenting the ssl certs and ssl behind port. For plain http proxy they work.

Anyone any idea?



1559169860907.png (224.0 KiB)
1559167952639.png (114.4 KiB)
5 comments
2 |3000

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

ezra avatar image ezra commented ·

@mvader (Victron Energy Staff) since you've chimed in on the other related topic, perhaps you could shine a light on this matter.

I've found that when I edit venus/app/index.html

to this:

if (mode === "production") {
var host = getParameterByName("host") || window.location.hostname || "localhost"
var socket = new WebSocket("wss://" + host + ":7890")
window.onerror = function(msg, url, lineNo, columnNo, err) {
var data = {
time: new Date(),
error: msg
}

It partly solves the issue only for port 7890. How would i go about to do this for 9001 in bundle.js


0 Likes 0 ·
mvader (Victron Energy) avatar image mvader (Victron Energy) ♦♦ ezra commented ·

Hi @ezra, I don’t know. Sorry.


0 Likes 0 ·
matt1309 avatar image matt1309 ezra commented ·

Hi @ezra


Sorry for digging up and old post but felt it was only fair to share my solution given your answers above helped me along the way:


In /var/www/venus/index.php I've editted the part where rfb object is created to edit the encrypt line to be true if connected to site via https and false otherwise (so that if im on lan it will just use ws instead of wss) The line now shows:

'encrypt': window.location.protocol === 'https:' ? WebUtil.getQueryVar('encrypt', true) : WebUtil.getQueryVar('encrypt', false),


Then in my reverse proxy (nginx in my case). I've reverse proxied from solar.domain.com to my internal ip of the venus os. And then also the websockets connection ie solar.domain.com:81/websockify (which will be done over wss if you connect via https://solar.domain.com). and forwards this from wss to ws (port 81 subdirectory /websockify I didn't bother editing).


I did it this way so you can still access via LAN without needing https.


Given the websocket is not authenticated I've added a password to the venus os page as a half arsed measure for now. I'll be looking to add some sort of authentication to websocket connection itself going forward. I have main page behind my sso but not edited the js for authentication connection on wss yet.

0 Likes 0 ·
akstef avatar image akstef matt1309 commented ·
Hi

I read all the post because I try to do the same. Using the remote console from lan through https for home assistant.

I am a real beginner and I even can configure the reverse proxy properly with nginx so I have an idea:

We can access the remote control from the vrm portal which is accessible in https. Is it not possible to get a vrm portal link displaying directly the remote console?

0 Likes 0 ·
matt1309 avatar image matt1309 akstef commented ·

Hi @Akstef ,

For home assistant you may be better off using MQTT or modbus they are both integrated into the GX devices, and would be far easier/cleaner.


If you just want ssl/dont really need reverse proxy then I believe venus os/gx devices now run nginx as their webserver. So you could probably just install the SSL certificates directly in the gx devices nginx config.


However if you want to use external reverse proxy like I've noted above then assuming you have ssl setup you just need to past the below proxy_pass into the location / block within the config.

However as venus os uses websocks you also need to forward those from ws to wss.

The nginx config I have the below in location /

proxy_pass http://192.168.xx.yy #IP address of gx device.

Add block below for websocks forwarding.

location /websockify {    proxy_pass http:// http://192.168.xx.yy:81/websockify;            proxy_http_version 1.1;            proxy_set_header Host $host;            proxy_set_header Upgrade $http_upgrade;            proxy_set_header Connection $connection_upgrade;            proxy_read_timeout 86400s; }


To get venus os to connect via wss rather than ws I edited the js in index.php so that it uses wss if user connected to remote console via https and ws if http.

However as I mentioned mqtt/modbus will be far easier for home assistant integration.


1 Like 1 ·