mviereck / x11docker

Run GUI applications and desktops in docker and podman containers. Focus on security.
MIT License
5.62k stars 378 forks source link

Running as non-root user shows error due to missing process id (NixOS) #83

Closed timor closed 5 years ago

timor commented 5 years ago

Version: 5.3.1 OS: NixOS

When running as non-root user, the command that tries to get the process id (ps ax | grep ...) returns nothing, because ps does not list the process, as it as run as root which it cannot see.

Symptopm: container.pid is empty

As a result, an error window pops up, but the container starts fine otherwise.

mviereck commented 5 years ago

Thanks for your bug report, and for already pointing on the issue part of the code!

ps ax on debian shows root processes, too. Is this different on NixOS?

I made a change in master branch that looks for parent pid of container pid 1 (ps -o ppid $Pid1pid instead of ps ax). Please try out if that works for you.

timor commented 5 years ago

Thanks for the quick response.

I have not tried the commit itself yet, but the ps -o ppid version seems to work as expected on the command line.

timor commented 5 years ago

The important thing seems to be /proc mounted with option hidepid=2, which hides all processes in /proc which are not owned by the current user. Judging from your code, the pid watcher will thus also probably fail.

For NixOS, a viable solution should be to add the user to the proc group, which exempts him from pid hiding. I suppose, ps aux will also work like expected then.

Will test that next week.

mviereck commented 5 years ago

The important thing seems to be /proc mounted with option hidepid=2, which hides all processes in /proc which are not owned by the current user.

This sounds like a reasonable security setting by NixOS.

For NixOS, a viable solution should be to add the user to the proc group, which exempts him from pid hiding.

I prefer not to change default system settings to allow x11docker.

A possible solution is to drop watching container pid at all and to watch pid 1 of container instead. This is not too hard, I could easily change that.

This may still fail for special cases when the container user is different from host user, e.g. with option --systemd that runs pid 1 as root in container. But it would cover most regular use cases.

mviereck commented 5 years ago

I've changed the code to watch container pid 1 instead of container pid itself. This should work now on NixOS with restricted /proc access.

For cases with different user of container pid 1, e.g. with options --systemd or --user=root, it should work if you run x11docker as root; container user and X server will still be unprivileged. Otherwise your suggestion with group proc will probably work. Changing mount option hidepid=2 to hidepid=1 probably works, too.

Regular use cases of unprivileged x11docker should work now without additional setup.

Edit: Does mount | grep /proc on NixOS show the mount options with hidepid=2, or is output of mount somehow restricted, too? I could include a check and a warning message for critical cases.

timor commented 5 years ago

With regards to this issue, I wonder if the following behavior is related to that, or independent:

When I run an application in a seamless container using Xpra, after closing the application, the Xpra server is still running (tray icon), and the x11docker command does not return. Does this have anything to do with this?

Edit: Right-clicking the tray icon and choosing "shutdown" causes the command to return.

timor commented 5 years ago

Does mount | grep /proc on NixOS show the mount options with hidepid=2, or is output of mount somehow restricted, too? I could include a check and a warning message for critical cases.

$ mount |grep /proc
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime,gid=21,hidepid=2)
mviereck commented 5 years ago

When I run an application in a seamless container using Xpra, after closing the application, the Xpra server is still running (tray icon), and the x11docker command does not return. Does this have anything to do with this?

x11docker should terminate itself (and xpra server) if the application terminates. The whole point on watching container pid or its pid 1 is about this. x11docker terminates X if the application finishes and vica versa.

A few applications do not really terminate if their window is closed but continue to run in background. Can you reproduce this with other applications? If yes, than it is an x11docker bug. If not, the container application does not terminate itself as it should. My own test runs works fine here, everything (including xpra) terminates as it should.

Please give me a --debug or --verbose output of a non-terminating setup.

mviereck commented 5 years ago

Latest commit checks for hidepid=2 and shows a meaningful error in cases with container pid 1 not owned by host user. The error will show some possible solutions, too.

timor commented 5 years ago

I tried the latest commit, but the code path that checks for hidepid=2 does not seem to get activated.

This is the command, which still does not terminate xpra when closing the application. x11docker --sharedir /afs --sharedir /home --no-init -c -a -Q --cachebasedir "$XDG_CACHE_HOME" --verbose x11docker/xfce /[redacted]/bin/matlab

Next, I will try whether adding my user to the proc group changes anything.

mviereck commented 5 years ago

the code path that checks for hidepid=2 does not seem to get activated.

It only has a visible effect if x11docker needs to watch root processes, e.g. with --user=root. Your command example would not trigger it.

Fails terminating of xpra with other applications than matlab, too? You could try e.g.

x11docker --xpra --no-init x11docker/xfce xfce4-terminal
timor commented 5 years ago

the code path that checks for hidepid=2 does not seem to get activated.

It only has a visible effect if x11docker needs to watch root processes, e.g. with --user=root. Your command example would not trigger it.

As far as I can tell, the process in question always runs under root, because the docker daemon is creating the container, not my user, no? The original issue here I encountered without using any --user option.

mviereck commented 5 years ago

As far as I can tell, the process in question always runs under root, because the docker daemon is creating the container, not my user, no?

Previously x11docker watched the pid of the docker container, created by dockerd and owned by root. Due to your original issue I changed that: x11docker watches pid 1 of container now.

For most x11docker options pid 1 in container is owned by the host user and can be watched without being restricted by hidepid=2. (Pid 1 in container is mapped to a regular pid on host that can easily be watched.)

timor commented 5 years ago

I tested with xfce4-term, and with matlab, and both times shutdown worked correctly.

mviereck commented 5 years ago

I tested with xfce4-term, and with matlab, and both times shutdown worked correctly.

Good, thanks for testing! It seems the issues are solved. Feel free to open a new issue if something else comes up.

mviereck commented 5 years ago

I did some test runs of x11docker in a NixOS VM and found that NixOS has issues with shebang #! /bin/bash. I have changed it to #! /usr/bin/env bash in all generated helper scripts. Now x11docker runs on NixOS without adjustment.