I’m passing a wayland socket into my containers in order run GUI applications from within containers.
Recently I ran a less trustworthy application within an unprivileged container and realised that who-/whatever has access to the wayland socket, has full access, e.g. can read the screen’s content at any time.
That most likely can’t be easily solved on the level of the socket itself (every GUI application using wayland will need write and read access to that socket as the protocol naturally is bidirectional), but It got me thinking how to restrict applications/containers.
Is there a more higher-level approach on e.g. applications only allowing to “read” (as in screenshot, record, etc.) the areas they’re drawing themselves?
Is there maybe a way to map and restrict UID/GID ranges (every unprivileged container has its own range in my case)? As far as I know the socket’s owner (wayland server here) is aware of which UID/GID is currently opening the / operating on the UNIX socket.
Thanks, but your “solution” totally disregards the actual problem/question and suggests there’s no solution involving incus/LXC/wayland - which I highly doubt.
No, that’s not the only way. If not wayland itself specifying such policies it’s on another level, as there are such policies.
I come to believe that it depends on the compositor. I’m using sway. Which is using wlroots as intermediate framework for communication with the wayland server.
And I come to conclude that’s the layer (wlrootfs when using sway) where policies are implemented and potentially enforced.
Sway is the compositor running in your host. You can create a container then install wayvnc in it then start wayvnc using sway wayland socket. I guess after you use another device connect to wayvnc, you can see the hole sway compositor content.
You can try nested a sway compositor in sway compositor, then let wayvnc using the nested sway wayland socket. It will show less.
A more isolated way, install wayland compositor in container, use host wayland socket as backend, start the untrusted app in container wayland compositor.
When you run a GUI application in a container and have the output appear on your desktop, you are using some way to make the container GUI app appear (per your host’s desktop environment) as if it is running on the host . Therefore, you would need to get your desktop environment to offer a way to separate apps running in a container from the rest of your desktop (i.e. through the X11 or Wayland socket).
But why go into all these steps if you can separate the GUI app from the rest of your desktop, by running it directly on your host? Because if you run the GUI app from within a container, you get a nice separation for the filesystem; your GUI app in the container does not access the host’s files, etc.
GUI snap packages work somewhat like the above, but they accept that the running snap app has access to the rest of the desktop. Apart from the ability to take a screenshot, the other issue is key logging.
For X11 you would try to figure out to launch a separate X server and point the container GUI app to appear in that second X server window.
You’re describing my use case (GUI apps in containers), questioning it right after (why do so if I can run them with restrictions on the host) and right then answer that (due to further (e.g. filesystem-)isolation).
But what’s the solution to the problem? Apparently using my desktop-environment / compositor for restricting - but how? Using sway/wlroots btw.
I don’t think there is a solution to the problem. X11 and wayland developers don’t need to isolate app through namespace. So there is no integratelion between lxc and x11 and wayland.
Wayland has done its best to isolate apps. Wayland developers don’t even want to implement remote access protocols, but there comes wayvnc.
So even if somehow you create a wayland compositor respects namespace, apps still can find a way to see hole desktop contain as long as they can access the socket.
The community is also reading these threads and it helps them to get a summary of the issue. Secondly, it also helps search engines and AI scrapers to provide better results. All for the community.
With regards to X11, you would need to start a new X server so that you separate the GUI app from the desktop. In practice you would use Xephyr (by itself it’s an X server), xpra (uses Xvfb), etc. There are several implementations of containers+GUI that use these.
The equivalent of a new X server in Wayland is using a separate wayland compositor.
The filesystem isolation is a given and it’s done right with the containers.
The proper GUI isolation requires more work. There’s no granular access control to the desktop. If you are to run untrusted GUI apps in a container, you definitely do not want any access to your host’s desktop. That means no copy-paste between the container GUI app and the rest of the desktop, etc.
and realised that who-/whatever has access to the wayland socket, has full access, e.g. can read the screen’s content at any time.
Did you check it was indeed the case? Are we talking about a normal (i.e. unprivileged) Incus container?
Wayland sandboxes everything by default. The only meaningful way to get access to get “full access” to the compositor is for the compositor to accept to provide full access. If your compositor is very lax with its security, either change to one that isn’t, change its configuration if that was the issue, or barred all these do:
The equivalent of a new X server in Wayland is using a separate wayland compositor.
Did you check it was indeed the case? Are we talking about a normal (i.e. unprivileged) Incus container?
As stated they’re unprivileged containers and of course I checked it, running e.g. grim allows me to screenshot all viewports/screens from an unprivileged container, having its own isolated UID/GID range.
Wayland sandboxes everything by default. The only meaningful way to get access to get “full access” to the compositor is for the compositor to accept to provide full access. If your compositor is very lax with its security, either change to one that isn’t, change its configuration if that was the issue, or barred all these do:
Using sway which uses wlroots. So if it’s the compositor having to ensure such restrictions it’s sway allowing everything by default?
running e.g. grim allows me to screenshot all viewports/screens from an unprivileged container, having its own isolated UID/GID range.
Grim uses the wayland screen capture protocol. In a nutshell here, it asks Sway for a full screen capture, whether or not this is allowed is up to Sway. That’s what I meant with compositors being lax (or configured lax) on security.
E.g. gnome typically forbids this generally and only allows a few programs to do screen captures (most notably Pipewire, which typically prompts user to approve screen sharing).
So if it’s the compositor having to ensure such restrictions it’s sway allowing everything by default?
Indeed. Wayland is only a protocol, much like HTTP is, the actual server is your compositor. Incidentally,
on the same wayland socket.
there is no such thing.
The socket you see has been setup by Sway (to speak the Wayland protocol over it, true). If you run a second instance (on a new TTY or nested), it will create a new, separated, socket that you can then share with your containers. This guarantees maximum isolation but means you can’t interact with it as if it was any other window.
If you want container-isolated programs to display stuff on your existing Sway compositor, you did the right thing but you need to find the way to tell Sway not to trust that program. I don’t know how this is done but, Sway being Sway, I’m pretty positive this is just a flag/option somewhere.
BTW, I double checked about privileged vs. unprivileged containers because root can indeed ptrace the socket and potentially dump data from there. A normal user is only able to interact with the compositor on the (Sway) Unix domain socket, it cannot see what is being exchanged otherwise, very much like I cannot see what you exchange with this website, in spite of reading/writing from and to the same socket.
I think I found a sensible solution to address this at least for my very use case.
I now create a new, restricted wayland socket, specifically to be used by the containers, which enables the security context protocols and enforces all restrictions by default.