UIbuilder behind NGINX reverse proxy

Hi,

I'm having an Issue accessing uibuilder.
I recently added a basic auth from the node-red setting.js

 httpNodeAuth: {user:"user",pass:"..."},
 httpStaticAuth: {user:"user",pass:"..."},

While this works well with Dashboard, when I access uibuilder it gives me 401 Unauthorized untill I clear all the cookies. Then it provides me with a login popup and works untill the next time the session expires.

I'm using nginx as a reverse proxi with LetsEncrypt ssl.

Here's my nginx settings:

 location / {
        proxy_pass http://localhost:1880/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

Perhaps I shioldn't use this authentication for uibuilder, and I need to find a better solution.

My uibuilder version is 1.2.5

And I don't know if it's relevant, but I'm building a PWA app with uibuilder.

Thanks

Hi, sorry for the delayed reply. Work night out kind of removed anything intelligent happening yesterday :slight_smile:

I think my initial advice would be that if you are using NGINX - and I fully approve of that, it is a good approach - it would be better for you to use it to also provide authentication and session management.


Given the testing and development that goes into NGINX, that is almost always going to be a solution that is more likely to be secure with fewer edge cases.

The second thing to say is that v2 of uibuilder is going to dis-aggregate authentication from httpNodeAuth because that is really designed for core nodes and I realised that it would be confusing to link it to uibuilder to say nothing of creating a lock-in between my contributed node and core capabilities which isn't wise.

So v2 has its own middleware capability which can be used for authentication. However, you will still be better off using NGINX, not only for better security but also because I think that the solution will be simpler and you are more likely to remember how it works in 6 months time.

One other thing to note. Obviously uibuilder, like Node-RED and Dashboard, makes heavy use of websockets (Socket.IO in uibuilder's case). You should note that, although I am implementing a middleware function for the sockets connection - this can only ever work on the initial connection. That is because, typically, websockets make an http(s) connection initially which is then upgraded to the ws(s) connection. The ws(s) connection cannot have a middleware as none of the libraries support that. Also, I don't believe that ws(s) connections allow control of headers like http does and so even JWT tokens aren't feasible.

What this means is, that if you are checking/enforcing session expiry, it only happens on the socket connection when the connection is first made. So there is no way to expire the session when only using sockets. Of course, the whole point of uibuilder (and Dashboard) is that you don't need to reload the page.

I am still working through some thoughts about how to handle this and I think that it will probably involve including the JWT token in the message though clearly this adds significant overhead to the message size so I'm not sure how scalable this will be. I also need to add an Origin header check to enforce same origin messages (probably with an optional switch and/or list of acceptable origins. Doubt this will land until v2.1 though).

Here is a useful tutorial on using NGINX, JWT and websockets for authentication and session management.

Final useful article on securing websockets is here. Also a StackOverflow QA here.

Hi Julian,

I was waiting for your reply :slight_smile:
And I'm also waiting for uibuilder v2

I actually really like the approach with nginx authentication.

I did try to go the basic_auth way but I ran into the same issue, that when the session expires nginx returns 401 Unauthorized untill I clear the cookies. This mostly happens on Chrome both on PC and Android.

I realy liked the artice with vouch-proxy, but unfortunately couldn't get it to work.

I have a redirect loop with error

{"level":"error","msg":"no jwt found in request"}

I belive this happens because I don't have my on domain, but using duckdns.org

I've opened 2 subdomains mydomain.duckdns.org and login-mydomain.duckdns.org

but I'm not sure jwt created for login-mydomain.duckdns.org works with mydomain.duckdns.org

Thanks

In case anyone is following I've opened an issue on Github - more details there.

1 Like

I ended up using a different module that essentially does the same thing as vouch-proxy, but it was easier for me to set up.

1 Like