udevbe / greenfield

HTML5 Wayland compositor :seedling:
GNU Affero General Public License v3.0
929 stars 29 forks source link

Proxying/Security #99

Closed rosensvv closed 2 years ago

rosensvv commented 2 years ago

Can the compose-module demo be proxied? Once it's opened using https, the websockets upgrade fails as it's not encrypted (wss). How should one go about proxying the demo? I tried also proxying the compositor-proxy as well, but it doesn't seem to work and doesn't give any meaningful information as to why.

Zubnix commented 2 years ago

You need to put SSL termination in front of the compositor-proxy using a reverse proxy like nginx and configure it to use the same certificate you used to serve the secure web-content of the compositor-module.

rosensvv commented 2 years ago

Same as in identical? I am using traefik which generates certificates for my subdomains and the compositor-proxy and -module are on seperate subdomains, will that be a problem? Also, when I add my reverse proxy (it's just labels added in docker-compose), the setup no longer works, even if I connect directly, not using the proxy, the windows don't appear. Logs show connections, it says websocket - open in browser console, yet the application window itself doesnt show up...

Zubnix commented 2 years ago

Same as in: it has to be a valid certificate for the domain you're making a websocket connection to.

As for your connection problem. Once a client connects, you should see additional output in proxy & the browser should also do some additional http(s) calls to the proxy which you can check in the browser network debugging tab.

rosensvv commented 2 years ago

Aha, so my certificates are valid and I only need to find out what is happening with my docker setup. I seem to be stuck: the same docker-compose file with the difference being

    networks:
      - traefik_servo
    labels:
      - traefik.enable=true
      - traefik.http.routers.prgui.rule=Host(`myvaliddomainhere`)
      - traefik.http.routers.prgui.entrypoints=websecure
      - traefik.http.routers.prgui.tls.certresolver=myresolver
      - traefik.http.services.prgui.loadbalancer.server.port=8081
      - traefik.http.routers.prgui.middlewares=sslheader
      - traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https
      - traefik.docker.network=traefik_servo

just adding this to docker-compose seems to break the setup, I can't access it even if i directly use the IP. Does your docker-compose file rely on the container not being attached to external networks or something of the sort?

Zubnix commented 2 years ago

It doesn't make any assumptions about networking. You can specify a bind ip parameter https://github.com/udevbe/greenfield/blob/master/compositor-proxy/src/config.yaml#L3 not sure if that will help?

rosensvv commented 2 years ago

This is what I get in the browser console when I enable the proxy (while still connecting to the IP the old way):

error { target: WebSocket, isTrusted: true, srcElement: WebSocket, currentTarget: WebSocket, eventPhase: 2, bubbles: false, cancelable: false, returnValue: true, defaultPrevented: false, composed: false, … }
[index.js:561](webpack://greenfield-compositor/node_modules/webpack-dev-server/client/modules/logger/index.js)
    logger index.js:561
    getLogger index.js:731
    error index.js:180
    onerror WebSocketClient.js:19
    (Async: EventHandlerNonNull)
    WebSocketClient WebSocketClient.js:18
    initSocket socket.js:24
    10 index.js:275
rosensvv commented 2 years ago

Issue is present on all my installations - it works until I attach it to my proxy docker network/add container labels for the proxy. Haven't tried binding to a specific IP - 0.0.0.0 should accept connections on any interface... Other than that, no errors on compositor-proxy, only the browser console output I posted above

Zubnix commented 2 years ago

Hmm, I switched the compositor-proxy to use https://github.com/uNetworking/uWebSockets.js which is a wrapper for https://github.com/uNetworking/uWebSockets. I wonder if it's an issue in that library, especially if your setup used to work before 🤔

rosensvv commented 2 years ago

I am not sure, I haven't tried to proxy my setup before so I have never seen this work. Issue is probably related to docker, although I don't think docker is misbehaving...

rosensvv commented 2 years ago

I managed to proxy it by exposing the port on the host machine and then pointing my proxy to that port - an ugly workaround, but works. This confirms my suspicion that the problem must be introduced when the container is attached to my docker proxy network (I highly doubt it's from the labels). Unfortunately it is still not usable - I see alacritty opening yet if I try to type anything it flashes and restarts, it gives me this error in the browser:

Blocked loading mixed active content “http://*mydomainhere*/mkstemp-mmap”
[runtime.ts:29](webpack://greenfield-compositor/src/api/runtime.ts)
Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.
Zubnix commented 2 years ago

I suspect it's trying to do an http call from an https domain? Thinking about it, it is probably looking at the websocket connection of the proxy, if that is insecure, it will also do an insecure http call. 🤔

rosensvv commented 2 years ago

I specified wss://mydoimain in the URL of the compositor-module connect button. My proxy is configured to do requests from mydomain to port 8081, yet something is wrong, does compositor proxy provide wss on another port?

Zubnix commented 2 years ago

Both http & websocket use the same server & port. I'm going to double check the code if it's correctly switching to 'https' if the websocket is using 'wss'. There might be a bug there.

Zubnix commented 2 years ago

Found the issue & pushed a fix. Can you confirm it works for you?

rosensvv commented 2 years ago

I still get in compositor-proxy:

WARN                gleglgbm gstgl_gbm_utils.c:489:gst_gl_gbm_find_and_open_drm_node: Cannot open device node "/dev/dri/card1": Permission denied (13)
ERROR              gldisplay gstgldisplay_gbm.c:394:gst_gl_display_gbm_new: could not find or open DRM device

And

Firefox can’t establish a connection to the server at wss://mydomainhere:8080/ws.
error { target: WebSocket, isTrusted: true, srcElement: WebSocket, currentTarget: WebSocket, eventPhase: 2, bubbles: false, cancelable: false, returnValue: true, defaultPrevented: false, composed: false, … }

in the browser console. Yet it actually works now and I can use it because I can finally secure it! Thank you, you're the best!