Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Files Written to Mounted Linux Home Directory Owned by Root User #594

Closed
osterman opened this issue Jun 19, 2020 · 14 comments · Fixed by #769 or #771
Closed

Files Written to Mounted Linux Home Directory Owned by Root User #594

osterman opened this issue Jun 19, 2020 · 14 comments · Fixed by #769 or #771

Comments

@osterman
Copy link
Member

osterman commented Jun 19, 2020

what

  • The user's shell inside Geodesic runs as root
  • The script that launches Geodesic bind-mounts the host user's $HOME to /localhost to provide access to configuration files and allow for editing of host files
  • Depending on the way Docker is set up, it is possible that files created under /localhost from within Geodesic will be set to the same owner UID and GID (that is, owned by root) on the host as they have within Geodesic.
  • This appears to affect only users running the Docker daemon as root under Linux. It does not affect Docker for Mac or Docker for Windows, nor does it affect Docker for Linux when run in "rootless" mode.

Resolution

The recommended solution for Linux users is to run Docker in "rootless" mode. In this mode, the Docker daemon runs as the host user (rather than as root) and files created by the root user in Geodesic are owned by the host user on the host. Not only does this configuration solve this issue, but it provides much better system security overall.

Geodesic, as of v0.151.0, provides an alternative solution: BindFS mapping of file owner and group IDs. To enable this solution, either set (and export) the shell environment variable GEODESIC_HOST_BINDFS_ENABLED=true or launch Geodesic with the command line option --geodesic-host-bindfs-enabled. When this option is enabled, Geodesic will output

# Enabling BindFS mapping of file system owner and group ID.

among its startup messages. Note that if you enable BindFS mapping while running in "rootless" mode, it will actually cause files on the host to be created with a different owner and group, not root and not the host user. If you see this behavior, do not use BindFS mapping.

@osterman osterman changed the title Files Written to Mounted Home Directory Owned by Root User Files Written to Mounted Linux Home Directory Owned by Root User Jun 19, 2020
@Nuru Nuru pinned this issue Aug 30, 2020
@Nuru
Copy link
Contributor

Nuru commented Jun 19, 2021

@osterman @sboardwell
I think we can use BindFS to solve this problem without risking the "works in my environment" problems that could come up if some users were running inside Geodesic as root and some were not.

It would require further customization of the launch script, so that on Linux we mount $HOME to /localhost.bindfs instead of /localhost and then inside Geodesic use BindFS to map /localhost.bindfs to /localhost with UID/GID mapping using --create-for-user and --create-for-group, but I think once we get that right, everything else falls into place, and it should not be as hard as supporting Windows was.

@drmikecrowe
Copy link

@Nuru @osterman

I'd like to propose this solution (please advise if this is universal enough):

  1. We support Linux user 1000 (which appears to be the default uid for distributions).
  2. If running linux, the wrapper script does DOCKER_ARGS+=(--user="$(id -u):$(id -g)")
  3. The Dockerfile.alpine and Dockerfile.debian will include useradd/groupadd/sudo support for user 1000 performing root operations.
  4. Major: We have to change the ownership inside the containers of /conf, /home and fix permissions of /var/tmp to allow usage by user 1000

Dockerfile additions:

RUN \
  groupadd -g 1000 geouser && \
  useradd -d /conf -G sudo -g geouser -u 1000 geouser && \
  sed -i 's/sudo[[:space:]]ALL=(ALL:ALL) ALL/sudo ALL=(ALL) NOPASSWD: ALL/' /etc/sudoers && \
  chown -R 1000:1000 /conf /home && \
  chmod 777 /var/tmp

@Nuru
Copy link
Contributor

Nuru commented Jan 31, 2022

@drmikecrowe wrote:

I'd like to propose this solution (please advise if this is universal enough):

1. We support Linux user 1000 (which appears to be the default uid for distributions).

...

@drmikecrowe If you would be willing, I would prefer you try the BindFS solution I proposed and let us know how that goes.

Steps:

  1. Create a custom Geodesic image that includes the bindfs package.

  2. In the wrapper, if running Linux:

  • pass environment variables GEODESIC_HOST_UID="$(id -u)" and GEODESIC_HOST_GID="$(id -g)"
  • mount $HOME to /localhost.bindfs instead of /localhost
  1. Then, at the start of _workdir.sh:
  • Check if env vars are set and file system is mounted on /localhost.bindfs and if so, set up bindfs to mirror it to /localhost with the desired owner and group:
if [[ -n $GEODESIC_HOST_UID ]] && [[ -n $GEODESIC_HOST_GID ]] && df -a | grep -q /localhost.bindfs; then
  bindfs --create-for-user="$GEODESIC_HOST_UID" --create-for-group="$GEODESIC_HOST_GID" /localhost.bindfs /localhost
  • Fix file_on_host if needed. I can take care of that if you just get me the output of df -a on a system where the BindFS fix is active and working as we would like it to work.

My hope is that this will solve all the file ownership problems and not get hung up on whatever the host UID and GID are, while also not requiring any further changes to Geodesic.

@drmikecrowe
Copy link

drmikecrowe commented Feb 2, 2022

@Nuru see this PR

I think this is what we want, but would appreciate any feedback

Nuru added a commit that referenced this issue Feb 3, 2022
@Nuru
Copy link
Contributor

Nuru commented Feb 4, 2022

@drmikecrowe OK, I have not been able to reproduce and fix the problem, so I need more information from you.

This is not an issue with Docker v20 on Ubuntu (tested on 20.04 LTS) when running in rootless mode. As with macOS, this configuration correctly translates file ownership between the root UID and GID inside the container to the user's UID and GID on the host.

When running Docker as root, and launching Geodesic using sudo geodesic, the geodesic wrapper does not get the user's UID and GID or home directory, so BindFS does not help and we do not get the right home directory mapped to /localhost anyway.

How are you launching Geodesic? Are you able to find the non-root user's UID, GID, and $HOME?

@drmikecrowe
Copy link

drmikecrowe commented Feb 4, 2022

I add my user to the docker group, and never use sudo to run docker.

I'm wondering if we should simply point users to rootless mode...

@Nuru
Copy link
Contributor

Nuru commented Feb 5, 2022

@drmikecrowe We definitely should be pointing users to rootless mode. Unfortunately, our current install procedure does not work in rootless mode, because the non-root user cannot install the geodesic wrapper in /usr/local/bin and the root user cannot run docker run because the socket is not in the default location. I think what we will do is:

  • Give up on auto-detection and auto-configuration of BindFS, just make it available as an option
  • If we cannot install the geodesic wrapper in /usr/local/bin, instead of giving up, write it to /tmp/geodesic and output a message to install it manually via sudo install -C /tmp/geodesic /usr/local/bin/geodesic

@drmikecrowe
Copy link

@Nuru -- what about:

  1. check if user has write access to /usr/local/bin and ensure we are running in user mode
  2. write to /tmp/geodesic
  3. execute sudo mv /tmp/geodesic /usr/local/bin/___ (which will prompt the user for their password if they aren't in sudoer's group)

Thoughts?

@Nuru
Copy link
Contributor

Nuru commented Feb 6, 2022

@drmikecrowe I do not like the security implications of running other people's scripts as root, and to me it's even worse when a script asks for your password in the middle of running, as you really have no idea what it's doing: maybe it's going to Tweet your password to the world. So I don't want to execute sudo in the script and I'm glad my solution gets rid of our current workaround which is to have affected users run the whole install script under sudo.

An alternative would be to install the script in $HOME/bin/ (creating it if it does not exist), giving the user the option of adding $HOME/bin to their PATH or installing the script in /usr/local/bin. I have mixed feelings about that. I like that for some people (who already have $HOME/bin on their path), they will have nothing left to do, and make install (and therefore make all) will properly update their wrapper without further intervention. What I don't like is that it feels intrusive and presumptuous to be creating a directory in the user's home directory.

@drmikecrowe
Copy link

@Nuru -- I'd recomment $HOME/.local/bin (see XDG Base Directory Specification).

@Nuru
Copy link
Contributor

Nuru commented Feb 15, 2022

@drmikecrowe Please try release candidate v0.152.0-rc2 and report issues in #771

@drmikecrowe
Copy link

drmikecrowe commented Feb 15, 2022

Please try release candidate v0.152.0-rc2 and report issues in #771

@Nuru Please confirm:

ARG VERSION=0.151.0-rc2

not 152?

@Nuru
Copy link
Contributor

Nuru commented Feb 15, 2022

Please try release candidate v0.152.0-rc2 and report issues in #771

@Nuru Please confirm:

ARG VERSION=0.151.0-rc2

not 152?

@drmikecrowe Feel free to try both, but if you are going to try only one, please try

ARG VERSION=0.152.0-rc2

@Gowiem
Copy link
Member

Gowiem commented Feb 21, 2024

Since this is a pretty common issue across different container runtimes, underlying VMs, mountTypes -- one note for any fellow colima users out there: Be sure to change from your vm setting to vz and mountType setting to virtiofs. See the below for full details:

  1. https://sweetops.slack.com/archives/G014YEKDH4K/p1708394409046649
  2. https://stackoverflow.com/a/77596193
  3. chown/chmod on mounted directory: Permission denied lima-vm/lima#231

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment