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

option to prevent --userns=keep-id from setting the value of --workdir option as the HOME #13185

Closed
pymonger opened this issue Feb 9, 2022 · 20 comments · Fixed by #13616
Closed
Labels
kind/feature Categorizes issue or PR as related to a new feature. locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments.

Comments

@pymonger
Copy link

pymonger commented Feb 9, 2022

Is this a BUG REPORT or FEATURE REQUEST? (leave only one on its own line)

/kind feature

Description

The -w/--workdir options seems to have a dual purpose. The option is described as "Working directory inside the container" and that works fine. However in the case that we are specifying the --userns=keep-id where the UID of the user running podman doesn't exist in the container, a user is created in /etc/passwd and the user home is set to the value of -w/--workdir. Without specifying the -w/--workdir, the behavior seems to be to reuse the image's WORKDIR value as the new user's home in /etc/passwd. There is a use case where we want the working directory (-w/--workdir) of the container to be in any arbitrary directory (e.g. /tmp/my/work/directory) but have the user's home directory preserved from the original value in the image. I'm not sure if I missed something in the documentation or if this is a feature request.

Steps to reproduce the issue:

  1. Create a Dockerfile to build a container with a non-root user:
$ cat << EOF > Dockerfile
FROM rockylinux:8
RUN useradd -d /home/rootless_user -m -s /bin/bash -U rootless_user
USER rootless_user
WORKDIR /home/rootless_user
EOF
  1. Build image:
$ buildah build -t rockylinux:8-rootless -f Dockerfile .
STEP 1/4: FROM rockylinux:8
STEP 2/4: RUN useradd -d /home/rootless_user -m -s /bin/bash -U rootless_user
STEP 3/4: USER rootless_user
STEP 4/4: WORKDIR /home/rootless_user
COMMIT rockylinux:8-rootless
Getting image source signatures
Copying blob 65dbea0a4b39 skipped: already exists  
Copying blob 40b23051d6aa done  
Copying config 4531b42559 done  
Writing manifest to image destination
Storing signatures
--> 4531b425592
Successfully tagged localhost/rockylinux:8-rootless
4531b425592186918088a47a226d36105553f2c675021060c9f33ce3f122b7f0
  1. Verify UID:GID of host user:
$ id
uid=1001(ops) gid=1001(ops) groups=1001(ops)
  1. Without -w/--workdir option:
$ podman run --userns=keep-id -u $UID:$(id -g) localhost/rockylinux:8-rootless bash -c 'id; echo "HOME: $HOME"; echo "PWD: $PWD"; cat /etc/passwd'
uid=1001(ops) gid=1001(ops) groups=1001(ops)
HOME: /home/rootless_user
PWD: /home/rootless_user
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
tss:x:59:59:Account used for TPM access:/dev/null:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
systemd-coredump:x:999:997:systemd Core Dumper:/:/sbin/nologin
systemd-resolve:x:193:193:systemd Resolver:/:/sbin/nologin
rootless_user:x:1000:1000::/home/rootless_user:/bin/bash
ops:*:1001:1001::/home/rootless_user:/bin/sh

Note that the running user in the container has a $HOME of /home/rootless_user.

  1. With the -w/--workdir option:
$ podman run --userns=keep-id -u $UID:$(id -g) -w /tmp localhost/rockylinux:8-rootless bash -c 'id; echo "HOME: $HOME"; echo "PWD: $PWD"; cat /etc/passwd'
uid=1001(ops) gid=1001(ops) groups=1001(ops)
HOME: /tmp
PWD: /tmp
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
tss:x:59:59:Account used for TPM access:/dev/null:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
systemd-coredump:x:999:997:systemd Core Dumper:/:/sbin/nologin
systemd-resolve:x:193:193:systemd Resolver:/:/sbin/nologin
rootless_user:x:1000:1000::/home/rootless_user:/bin/bash
ops:*:1001:1001::/tmp:/bin/sh

Describe the results you received:

In step number #5 above, we see that the /etc/passwd entry for the new user has a home directory set to the value of the -w/--workingdir option I passed in and is verified by echoing the HOME env variable. In step #4 where no -w/--workingdir option was passed, the /etc/passwd entry for the new user has a home directory set to /home/rootless_user which was the value of WORKDIR in the Dockerfile and is verified by echoing the HOME env variable.

Describe the results you expected:

I'm assuming these results are all expected and so I'm guessing that what I'm looking for is a new feature (e.g. for lack of a better name --preserve-original-workdir) such that using that option like this:

podman run --userns=keep-id -u $UID:$(id -g) -w /tmp --preserve-original-workdir localhost/rockylinux:8-rootless bash -c 'id; echo "HOME: $HOME"; echo "PWD: $PWD"; cat /etc/passwd'

would result in the following:

uid=1001(ops) gid=1001(ops) groups=1001(ops)
HOME: /home/rootless_user
PWD: /tmp
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
tss:x:59:59:Account used for TPM access:/dev/null:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
systemd-coredump:x:999:997:systemd Core Dumper:/:/sbin/nologin
systemd-resolve:x:193:193:systemd Resolver:/:/sbin/nologin
rootless_user:x:1000:1000::/home/rootless_user:/bin/bash
ops:*:1001:1001::/home/rootless_user:/bin/sh

Note that HOME is /home/rootless_user and the entry in /etc/passwd verifies that. Also, the PWD of the process is correctly in the value I passed to -w/--workdir.

Additional information you deem important (e.g. issue happens only occasionally):

Output of podman version:

Version:      3.4.2
API Version:  3.4.2
Go Version:   go1.16.12
Built:        Sat Feb  5 00:02:55 2022
OS/Arch:      linux/amd64

Output of podman info --debug:

host:
  arch: amd64
  buildahVersion: 1.23.1
  cgroupControllers: []
  cgroupManager: cgroupfs
  cgroupVersion: v1
  conmon:
    package: conmon-2.0.32-1.module+el8.5.0+20494+0311868c.x86_64
    path: /usr/bin/conmon
    version: 'conmon version 2.0.32, commit: 152262b46a0d328c2746a648892a6b9a67922199'
  cpus: 2
  distribution:
    distribution: '"ol"'
    variant: server
    version: "8.5"
  eventLogger: file
  hostname: localhost.localdomain
  idMappings:
    gidmap:
    - container_id: 0
      host_id: 1001
      size: 1
    - container_id: 1
      host_id: 165536
      size: 65536
    uidmap:
    - container_id: 0
      host_id: 1001
      size: 1
    - container_id: 1
      host_id: 165536
      size: 65536
  kernel: 5.4.17-2136.302.7.2.2.el8uek.x86_64
  linkmode: dynamic
  logDriver: k8s-file
  memFree: 176267264
  memTotal: 1776623616
  ociRuntime:
    name: runc
    package: runc-1.0.3-1.module+el8.5.0+20494+0311868c.x86_64
    path: /usr/bin/runc
    version: |-
      runc version 1.0.3
      spec: 1.0.2-dev
      go: go1.16.12
      libseccomp: 2.5.1
  os: linux
  remoteSocket:
    path: /tmp/podman-run-1001/podman/podman.sock
  security:
    apparmorEnabled: false
    capabilities: CAP_NET_RAW,CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: true
    seccompEnabled: true
    seccompProfilePath: /usr/share/containers/seccomp.json
    selinuxEnabled: false
  serviceIsRemote: false
  slirp4netns:
    executable: /usr/bin/slirp4netns
    package: slirp4netns-1.1.8-1.module+el8.5.0+20416+d687fed7.x86_64
    version: |-
      slirp4netns version 1.1.8
      commit: d361001f495417b880f20329121e3aa431a8f90f
      libslirp: 4.4.0
      SLIRP_CONFIG_VERSION_MAX: 3
      libseccomp: 2.5.1
  swapFree: 4276244480
  swapTotal: 4294963200
  uptime: 9h 5m 59.85s (Approximately 0.38 days)
plugins:
  log:
  - k8s-file
  - none
  - journald
  network:
  - bridge
  - macvlan
  volume:
  - local
registries:
  search:
  - container-registry.oracle.com
  - docker.io
store:
  configFile: /home/ops/.config/containers/storage.conf
  containerStore:
    number: 77
    paused: 0
    running: 0
    stopped: 77
  graphDriverName: overlay
  graphOptions:
    overlay.mount_program:
      Executable: /usr/bin/fuse-overlayfs
      Package: fuse-overlayfs-1.8-1.module+el8.5.0+20494+0311868c.x86_64
      Version: |-
        fusermount3 version: 3.2.1
        fuse-overlayfs: version 1.8
        FUSE library version 3.2.1
        using FUSE kernel interface version 7.26
  graphRoot: /home/ops/.local/share/containers/storage
  graphStatus:
    Backing Filesystem: xfs
    Native Overlay Diff: "false"
    Supports d_type: "true"
    Using metacopy: "false"
  imageStore:
    number: 63
  runRoot: /tmp/podman-run-1001/containers
  volumePath: /home/ops/.local/share/containers/storage/volumes
version:
  APIVersion: 3.4.2
  Built: 1644019375
  BuiltTime: Sat Feb  5 00:02:55 2022
  GitCommit: ""
  GoVersion: go1.16.12
  OsArch: linux/amd64
  Version: 3.4.2

Package info (e.g. output of rpm -q podman or apt list podman):

podman-3.4.2-9.0.1.module+el8.5.0+20494+0311868c.x86_64

Have you tested with the latest version of Podman and have you checked the Podman Troubleshooting Guide? (https://github.com/containers/podman/blob/main/troubleshooting.md)

Yes

Additional environment details (AWS, VirtualBox, physical, etc.):

All commands were run from a Vagrant box on MacOS:

$ cd ~/tmp
$ mkdir podman_testing
$ vagrant init hysds/base
$ vagrant up
$ vagrant ssh
@openshift-ci openshift-ci bot added the kind/feature Categorizes issue or PR as related to a new feature. label Feb 9, 2022
@mheon
Copy link
Member

mheon commented Feb 9, 2022

This seems like it could be a bug? The home directory of the created user should be set to the same directory at the user on the host, from my understanding - workdir should be separate from homedir.

@rhatdan @giuseppe Am I wrong here? I don't see anything regarding this in the keep-id documentation, so I don't see any indication this was deliberate.

@giuseppe
Copy link
Member

giuseppe commented Feb 9, 2022

I see you are using both --userns=keep-id and use an explicit --user for running the container. I am not sure why we are even allowing this combination as it is very confusing. It creates a user namespace where your UID is mapped to the same UID in the container, but then runs the process with the UID specified for --user.

I am not sure we should allow this combination. What is your expectation when you specify both --userns=keep-id and --user?

@Luap99
Copy link
Member

Luap99 commented Feb 9, 2022

@giuseppe I think this is required for images that have some special entrypoint which expects to be run as root to chown directories etc... and then switches to the user so it is very useful to run --userns=keep-id --user 0 in my experience.

@rhatdan
Copy link
Member

rhatdan commented Feb 9, 2022

Yes I see this as a legitimate use case. I do find it strange that --userns=keep-id would change the behavior.

@pymonger
Copy link
Author

pymonger commented Feb 9, 2022

I see you are using both --userns=keep-id and use an explicit --user for running the container. I am not sure why we are even allowing this combination as it is very confusing. It creates a user namespace where your UID is mapped to the same UID in the container, but then runs the process with the UID specified for --user.

I am not sure we should allow this combination. What is your expectation when you specify both --userns=keep-id and --user?

@giuseppe: If I didn't specify the --user, then the UID/GID of the user in the container isn't that of the user that ran podman on the host. Here's how that looks like:

[ops@localhost ~]$ id
uid=1001(ops) gid=1001(ops) groups=1001(ops)
[ops@localhost ~]$ podman run --userns=keep-id -w /tmp localhost/rockylinux:8-rootless bash -c 'id; echo "HOME: $HOME"; echo "PWD: $PWD"; cat /etc/passwd'
uid=1000(rootless_user) gid=1000(rootless_user) groups=1000(rootless_user)
HOME: /tmp
PWD: /tmp
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
tss:x:59:59:Account used for TPM access:/dev/null:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
systemd-coredump:x:999:997:systemd Core Dumper:/:/sbin/nologin
systemd-resolve:x:193:193:systemd Resolver:/:/sbin/nologin
rootless_user:x:1000:1000::/home/rootless_user:/bin/bash
ops:*:1001:1001::/tmp:/bin/sh

Note that the --userns=keep-id did add an entry in /etc/passwd:

ops:*:1001:1001::/tmp:/bin/sh

but the running user's ID still 1000:1000. Also note that the HOME env variable is /tmp instead of /home/rootless_user. Adding --user $UID:$(id -g) fixes that.

@giuseppe
Copy link
Member

giuseppe commented Feb 16, 2022

the behavior AFAICS, doesn't depend on --userns=keep-id as I can easily reproduce it without adding a user namespace.

$ podman run -w /home  -u 1000 alpine sh -c 'grep 1000 /etc/passwd'
1000:*:1000:1000:container user:/home:/bin/sh
$ podman run -w /  -u 1000 alpine sh -c 'grep 1000 /etc/passwd'
1000:*:1000:1000:container user:/:/bin/sh

What you are looking for, IIUC, is a way to customize the entry for /etc/passwd. I guess a bind mount from an external file would be too mechanical?

IMO, if we want to allow customizing the entry, it should be in a more generic way, something like --passwd-entry=...

@rhatdan
Copy link
Member

rhatdan commented Feb 16, 2022

Yes that would be the best way, then allow users to enter free form text.

@pymonger
Copy link
Author

@giuseppe: you are correct. My use-case would then look like this using your suggestion:

$ podman run -w /tmp  -u 1000 --passwd-entry="1000:*:1000:1000:container user:/home:/bin/sh" alpine sh -c 'pwd; grep 1000 /etc/passwd'
/tmp
1000:*:1000:1000:container user:/home:/bin/sh

But there is potential that the user will screw up the value they pass to --password-entry where they pass in a different UID than the one specified by the -u option. Maybe there would be some underlying validation that the --password-entry free-form value:

  1. conforms to the /etc/passwd format
  2. UID in the free-form text matches the UID passed in the -u option if -u was specified

@pymonger
Copy link
Author

hi @giuseppe, @rhatdan: any further thoughts on this feature?

@giuseppe
Copy link
Member

I am fine with something like was suggested above --passwd-entry="1000:*:1000:1000:container user:/home:/bin/sh" or even more generic as --append-to-file="/etc/passwd:1000:*:1000:1000:container user:/home:/bin/sh".

Now it must be implemented :) Are you interested in opening a PR? Otherwise I can take a look

@giuseppe
Copy link
Member

If we decide for --passwd-entry I think we would also need to add --groups-entry

@giuseppe
Copy link
Member

I've played a bit with it and got with: https://github.com/giuseppe/libpod/tree/passwd-entry

You can write something like:

$ bin/podman run --user 1231 --rm -ti --passwd-entry '$UID:*:$UID:0:FOO:/:/bin/sh' fedora tail -1 /etc/passwd
1231:*:1231:0:FOO:/:/bin/sh

What do you think about it? Would it work for you?

@pymonger
Copy link
Author

Hi @giuseppe, that would definitely work.

@rhatdan
Copy link
Member

rhatdan commented Mar 23, 2022

SGTM --passwd-entry and --group-entry.

@giuseppe
Copy link
Member

giuseppe commented Mar 23, 2022

I am not sure we need group-entry at this point. There is not much we can customize here: return fmt.Sprintf("%s:x:%s:%s\n", g.Name, g.Gid, username)

@giuseppe
Copy link
Member

opened a PR: #13616

@pymonger
Copy link
Author

@giuseppe: is there something holding back the merging of the PR?

giuseppe added a commit to giuseppe/libpod that referenced this issue Apr 14, 2022
It allows to customize the entry that is written to the `/etc/passwd`
file when --passwd is used.

Closes: containers#13185

Signed-off-by: Giuseppe Scrivano <[email protected]>
@pymonger
Copy link
Author

Thank you @giuseppe! Can't wait to start using this feature. Any idea which version/release this feature will come out in?

@giuseppe
Copy link
Member

I think the first version where the new feature will be included is 4.1

@rhatdan
Copy link
Member

rhatdan commented Apr 15, 2022

RC1 of podman 4.1 is supposed to be released next week.

@github-actions github-actions bot added the locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments. label Sep 20, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
kind/feature Categorizes issue or PR as related to a new feature. locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants