Closed andrewgdunn closed 3 years ago
tried
--userns=keep-id
but then the container user (910 in the container) can't write to the volume
what error do you have? If the volume is owned by your rootless main user, then it should be able to access it.
When you say "consistent mapping", do you mean the identify mapping?
This is definitely the use-case for --userns=keep-id
. Privileged does not and will never do this by default - the default container root to user launching container mapping is a lot safer as container apps run as root (and the the user launching the container) by default. You can certainly duplicate what --userns=keep-id
does through --uidmap
and --gidmap
, but I think you're only duplicating what the flag does as under the hood that is basically what it does. --userns=host
doesn't do anything on rootless Podman because we absolutely require a user namespace to set up rootless containers (really need to document this better, maybe emit a warning on it happening).
For debugging your EPERM, I might suggest reading https://www.redhat.com/sysadmin/debug-rootless-podman-mounted-volumes which I put together for cases like this - this is a common problem. Generally speaking, though, it root in the container was mapped to your user and successfully touched a file, and you change to --userns=keep-id
to change to an identity mapping, the user in question should also be able to successfully write to that volume.
Thanks for the response @giuseppe:
what error do you have? If the volume is owned by your rootless main user, then it should be able to access it.
uid
606
uid
0
) can write to the mapped folder (expected, as 0
is being mapped to 606
.uid
is 910
by default in the container I mentioned above)
uid
0
is in play (e.g. linuxserver containers and something like gitlab) how can I get their disk writes in volumes to not be shifted by subuid
.Thanks for the response @mheon, I did read through that and felt like I was entirely confused about --userns=keep-id
(as it seems like exactly what I'm looking for). I didn't debug very long with it. As I'd mentioned just above to @giuseppe, the user that is running the process in this container is not the root user, so it doesn't seem to have proper permissions to write to the mapped volume.
o+rwx
) don't seem to resolve this.
chown
that the container is trying to do (by looking at the logs).I'd seen this (use of --userns=keep-id
) prevent me from launching gitlab-{cc,ee} as well as the container I'd mentioned in the write up. These containers are all built with non-root users interacting on disk.
@mheon follow up on:
Generally speaking, though, it root in the container was mapped to your user and successfully touched a file, and you change to --userns=keep-id to change to an identity mapping, the user in question should also be able to successfully write to that volume.
I'd tried to toy with this, I was unable to get it to work and I didn't share my logs. I'm away from the machine for a moment but wanted to respond with a question (as I might have had the wrong idea for testing).
Ideally, in the case of freshrss above, I can either just know that the uid
and gid
are 910
or I an specify with an envar (the way the container is built). In the case of gitlab it's a couple users that I'd have to go discover. I'd wanted to use --uidmap
to map specific users back to my host user, such as:
--uidmap=0:606:1 --uidmap=910:606:1
where I want both the container users with id
of 0
and 910
to be able to write as the 606
user on the host.
I defer to @giuseppe on whether it's possible to have multiple GIDs in the container map to one GID on the host
Here is the example I was working with.
[root@vault ~]# useradd -g 606 -u 606 -d /zfs/app/freshrss/ -s /bin/bash freshrss
[root@vault ~]# usermod --add-subuids 60600000-60665535 --add-subgids 60600000-60665535 freshrss
[root@vault ~]# loginctl enable-linger freshrss
[root@vault ~]# su - freshrss
Last login: Mon Jun 14 20:18:46 EDT 2021 on pts/0
[freshrss@vault ~]$ dnf info podman
Installed Packages
Name : podman
Epoch : 3
Version : 3.2.0
Release : 5.fc34
Architecture : x86_64
Size : 46 M
Source : podman-3.2.0-5.fc34.src.rpm
Repository : @System
From repo : updates
Summary : Manage Pods, Containers and Container Images
URL : https://podman.io/
License : ASL 2.0
Description : podman (Pod Manager) is a fully featured container engine that is a simple
: daemonless tool. podman provides a Docker-CLI comparable command line that
: eases the transition from other container engines and allows the management of
: pods, containers and images. Simply put: alias docker=podman.
: Most podman commands can be run as a regular user, without requiring
: additional privileges.
:
: podman uses Buildah(1) internally to create container images.
: Both tools share image (not container) storage, hence each can use or
: manipulate images (but not containers) created by the other.
:
: Manage Pods, Containers and Container Images
: podman Simple management tool for pods, containers and images
[freshrss@vault ~]$ mkdir data
[freshrss@vault ~]$ ls -la
total 5
drwxr-xr-x. 3 freshrss freshrss 4 Jun 14 20:19 .
drwxr-xr-x. 8 root root 104 Jun 12 15:23 ..
-rw-------. 1 freshrss freshrss 16689 Jun 14 20:18 .bash_history
drwxr-xr-x. 2 freshrss freshrss 2 Jun 14 20:19 data
[freshrss@vault ~]$ id
uid=606(freshrss) gid=606(freshrss) groups=606(freshrss) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
freshrss
data
freshrss
has uid
and gid
of 606
.I'd like to use the --userns=keep-id
and have this container be able to write to the data
volume, but... it seems to have permissions errors:
[freshrss@vault ~]$ podman run --userns=keep-id --name=freshrss --publish 127.0.0.1:8008:80 --volume ~/data/:/config:Z docker.io/linuxserver/freshrss:latest
Trying to pull docker.io/linuxserver/freshrss:latest...
Getting image source signatures
Copying blob e9d333e5322a done
Copying blob cbf2c38fca87 done
Copying blob 664897dd7f3c done
Copying blob bcd6fb444d70 done
Copying blob 9a950d26b1f9 done
Copying blob ba742d4eac8f done
Copying blob 70ef020bbadd done
Copying blob 14dd34cd286f done
Copying blob a538fa58b2b7 done
Copying blob e482928adb1b done
Copying config 8f057a25eb done
Writing manifest to image destination
Storing signatures
[s6-init] making user provided files available at /var/run/s6/etc...exited 0.
[s6-init] ensuring user provided files have correct perms...s6-chown: fatal: unable to chown /var/run/s6/etc/cont-init.d/20-config: Operation not permitted
s6-chown: fatal: unable to chown /var/run/s6/etc/cont-init.d/01-envfile: Operation not permitted
s6-chown: fatal: unable to chown /var/run/s6/etc/cont-init.d/40-install: Operation not permitted
s6-chown: fatal: unable to chown /var/run/s6/etc/cont-init.d/99-custom-files: Operation not permitted
s6-chown: fatal: unable to chown /var/run/s6/etc/cont-init.d/10-adduser: Operation not permitted
s6-chown: fatal: unable to chown /var/run/s6/etc/cont-init.d/30-keygen: Operation not permitted
s6-chmod: fatal: unable to change mode of /var/run/s6/etc/cont-init.d/99-custom-files: Operation not permitted
s6-chmod: fatal: unable to change mode of /var/run/s6/etc/cont-init.d/20-config: Operation not permitted
s6-chmod: fatal: unable to change mode of /var/run/s6/etc/cont-init.d/01-envfile: Operation not permitted
s6-chmod: fatal: unable to change mode of /var/run/s6/etc/cont-init.d/40-install: Operation not permitted
s6-chmod: fatal: unable to change mode of /var/run/s6/etc/cont-init.d/10-adduser: Operation not permitted
s6-chmod: fatal: unable to change mode of /var/run/s6/etc/cont-init.d/30-keygen: Operation not permitted
s6-chown: fatal: unable to chown /var/run/s6/etc/services.d/nginx/run: Operation not permitted
s6-chown: fatal: unable to chown /var/run/s6/etc/services.d/cron/run: Operation not permitted
s6-chown: fatal: unable to chown /var/run/s6/etc/services.d/php-fpm/run: Operation not permitted
s6-chmod: fatal: unable to change mode of /var/run/s6/etc/services.d/nginx/run: Operation not permitted
s6-chmod: fatal: unable to change mode of /var/run/s6/etc/services.d/cron/run: Operation not permitted
s6-chmod: fatal: unable to change mode of /var/run/s6/etc/services.d/php-fpm/run: Operation not permitted
exited 0.
[fix-attrs.d] applying ownership & permissions fixes...
[fix-attrs.d] done.
[cont-init.d] executing container initialization scripts...
[cont-init.d] 01-envfile: executing...
foreground: warning: unable to spawn /var/run/s6/etc/cont-init.d/01-envfile: Permission denied
[cont-init.d] 01-envfile: exited 127.
[cont-init.d] 10-adduser: executing...
foreground: warning: unable to spawn /var/run/s6/etc/cont-init.d/10-adduser: Permission denied
[cont-init.d] 10-adduser: exited 127.
[cont-init.d] 20-config: executing...
foreground: warning: unable to spawn /var/run/s6/etc/cont-init.d/20-config: Permission denied
[cont-init.d] 20-config: exited 127.
[cont-init.d] 30-keygen: executing...
foreground: warning: unable to spawn /var/run/s6/etc/cont-init.d/30-keygen: Permission denied
[cont-init.d] 30-keygen: exited 127.
[cont-init.d] 40-install: executing...
foreground: warning: unable to spawn /var/run/s6/etc/cont-init.d/40-install: Permission denied
[cont-init.d] 40-install: exited 127.
[cont-init.d] 99-custom-files: executing...
foreground: warning: unable to spawn /var/run/s6/etc/cont-init.d/99-custom-files: Permission denied
[cont-init.d] 99-custom-files: exited 127.
[cont-init.d] done.
[services.d] starting services
s6-supervise (child): fatal: unable to exec run: Permission denied
s6-supervise (child): fatal: unable to exec run: Permission denied
s6-supervise cron: warning: unable to spawn ./run - waiting 10 seconds
s6-supervise nginx: warning: unable to spawn ./run - waiting 10 seconds
s6-supervise (child): fatal: unable to exec run: Permission denied
s6-supervise php-fpm: warning: unable to spawn ./run - waiting 10 seconds
[services.d] done.
[cont-finish.d] executing container finish scripts...
[cont-finish.d] done.
[s6-finish] waiting for services.
[s6-finish] sending all processes the TERM signal.
[s6-finish] sending all processes the KILL signal and exiting.
^C
[freshrss@vault ~]$ ls -la data/
total 2
drwxr-xr-x. 2 freshrss freshrss 2 Jun 14 20:19 .
drwxr-xr-x. 5 freshrss freshrss 6 Jun 14 20:21 ..
data
directoryNow without --userns=keep-id
:
[freshrss@vault ~]$ podman rm -f freshrss
[freshrss@vault ~]$ podman run --name=freshrss --publish 127.0.0.1:8008:80 --volume ~/data/:/config:Z docker.io/linuxserver/freshrss:latest
[s6-init] making user provided files available at /var/run/s6/etc...exited 0.
[s6-init] ensuring user provided files have correct perms...exited 0.
[fix-attrs.d] applying ownership & permissions fixes...
[fix-attrs.d] done.
[cont-init.d] executing container initialization scripts...
[cont-init.d] 01-envfile: executing...
[cont-init.d] 01-envfile: exited 0.
[cont-init.d] 10-adduser: executing...
usermod: no changes
-------------------------------------
_ ()
| | ___ _ __
| | / __| | | / \
| | \__ \ | | | () |
|_| |___/ |_| \__/
Brought to you by linuxserver.io
-------------------------------------
To support LSIO projects visit:
https://www.linuxserver.io/donate/
-------------------------------------
GID/UID
-------------------------------------
User uid: 911
User gid: 911
-------------------------------------
[cont-init.d] 10-adduser: exited 0.
[cont-init.d] 20-config: executing...
[cont-init.d] 20-config: exited 0.
[cont-init.d] 30-keygen: executing...
generating self-signed keys in /config/keys, you can replace these with your own keys if required
Generating a RSA private key
...+++++
...........................................................+++++
writing new private key to '/config/keys/cert.key'
-----
[cont-init.d] 30-keygen: exited 0.
[cont-init.d] 40-install: executing...
[cont-init.d] 40-install: exited 0.
[cont-init.d] 99-custom-files: executing...
[custom-init] no custom files found exiting...
[cont-init.d] 99-custom-files: exited 0.
[cont-init.d] done.
[services.d] starting services
[services.d] done.
[cont-finish.d] executing container finish scripts...
[cont-finish.d] done.
[s6-finish] waiting for services.
^C
[s6-finish] sending all processes the TERM signal.
[s6-finish] sending all processes the KILL signal and exiting.
[freshrss@vault ~]$ ls -la data/
total 6
drwxr-xr-x. 8 60600910 60600910 8 Jun 14 20:26 .
drwxr-xr-x. 5 freshrss freshrss 6 Jun 14 20:21 ..
drwxr-xr-x. 2 60600910 60600910 3 Jun 14 20:26 crontabs
drwxr-xr-x. 2 60600910 60600910 4 Jun 14 20:26 keys
drwxr-xr-x. 4 60600910 60600910 4 Jun 14 20:26 log
drwxrwxr-x. 3 60600910 60600910 4 Jun 14 20:26 nginx
drwxr-xr-x. 2 60600910 60600910 4 Jun 14 20:26 php
drwxrwxr-x. 3 60600910 60600910 4 Jun 14 20:26 www
I defer to @giuseppe on whether it's possible to have multiple GIDs in the container map to one GID on the host
that is not possible. One ID in the user namespace can only map to one ID in the outer environment.
* this is the case I'm trying to understand, when a user that isn't `uid` `0` is in play (e.g. linuxserver containers and something like gitlab) how can I get their disk writes in volumes to not be shifted by `subuid`.
you'd need to allocate IDs 1->N on the host to the rootless user. I really suggest you to not do it, as you allow the unprivileged user to use system IDs.
Why is such a requirement to have the same IDs mapped to the same values on the host?
Why is such a requirement to have the same IDs mapped to the same values on the host?
Speaking of myself (not as the topic owner): PostgreSQL for example creates an internal UID 999
(postgres) to store the database's data. When trying to backup this data from "outside", the access to this directory fails. So you need to be root or allow the outer user sudo
rights. Sure, there is podman unshare
, but the file being created again belongs to another user. This can be chowned from outside, but it's pretty ugly to handle by scripting or external processes.
I'm using --userns=keep-id
in most cases, but this changes all the volumes/mounts... not what everyone wants.
Why is such a requirement to have the same IDs mapped to the same values on the host?
It depends on the container composition. The example I expressed with freshrss and containers built by this community was because there are likely many people using these tools and running into this use case. There are other cases of more complex containers, like gitlab, which has uid
of 991
, 995
, 996
, 997
and a gid
of 998
that shows up. This makes interaction with data on disk more difficult (e.g. requires root, sudo, or unshare).
[root@citadel data]# ls -la
total 173
drwxr-xr-x. 20 gitlab gitlab 25 Jun 4 12:42 .
drwx------. 7 gitlab gitlab 8 Mar 4 17:41 ..
drwxr-x---. 3 80000991 gitlab 4 Jun 4 12:44 alertmanager
drwx------. 4 80000997 gitlab 10 Jun 5 05:46 backups
-rw-------. 1 gitlab gitlab 38 Jul 31 2020 bootstrapped
drwxr-xr-x. 2 80000997 80000997 2 Jul 31 2020 .bundle
drwx------. 3 80000997 gitlab 8 Jun 4 12:44 gitaly
-rw-r--r--. 1 80000997 80000997 367 Jul 31 2020 .gitconfig
drwx------. 3 80000997 80000997 3 Jul 31 2020 git-data
drwxr-xr-x. 3 80000997 gitlab 3 Jul 31 2020 gitlab-ci
drwxr-xr-x. 2 80000997 gitlab 4 Jun 4 12:43 gitlab-exporter
drwxr-xr-x. 9 80000997 gitlab 12 Jun 4 12:42 gitlab-rails
drwx------. 2 80000997 gitlab 3 Jun 4 12:42 gitlab-shell
drwxr-x---. 3 80000997 80000998 5 Jun 4 12:43 gitlab-workhorse
drwx------. 4 80000991 gitlab 7 Jun 4 12:44 grafana
drwx------. 3 gitlab gitlab 5 Jun 15 08:53 logrotate
drwxr-x---. 9 gitlab 80000998 11 Jun 4 12:43 nginx
drwx------. 2 80000995 gitlab 3 Jun 4 12:44 postgres-exporter
drwxr-xr-x. 4 80000995 gitlab 9 Jun 4 12:42 postgresql
-rw-r--r--. 1 gitlab gitlab 5 Feb 1 17:22 postgresql-version.old
drwxr-x---. 4 80000991 gitlab 5 Jun 4 12:44 prometheus
-rw-r--r--. 1 gitlab gitlab 483 Jun 4 12:44 public_attributes.json
drwxr-x---. 2 80000996 80000997 13 Jun 15 09:48 redis
drwx------. 2 80000997 80000997 4 Jul 31 2020 .ssh
-rw-r--r--. 1 gitlab gitlab 40 Jun 4 12:42 trusted-certs-directory-hash
I'm curious about how to do the mapping when the case is a single non root-user. Like with the linuxserver.io where there is expected to only be one. In this case I'd specifically want to map 910
to my host uid, but all others I'd want to shift in the subuid
space. The thing I struggle with is that it appears that the way --uidmap
works is sequential. So... Would I have to do three calls to --uidmap
like:
--uidmap=0:60600000:909 --uidmap=910:606:1 --uidmap=911:60600911:64626
For a case where there are multiple non-root users... I have no idea what to do. Is it possible to run podman as a non-root user on the host but run it "rootfull" as that non-root user so that it's interactions on disk are all mapped to the host user's uid?
@tobwen when you use --userns=keep-id
does this ensure that the volume for postgres is written as the host uid?
when you use
--userns=keep-id
does this ensure that the volume for postgres is written as the host uid?
Yes. But ALL the users inside the container (e.g. 333 666 999 65535) get smashed to host uid.
Yes. But ALL the users inside the container (e.g. 333 666 999 65535) get smashed to host uid.
This is exactly what I actually want with the example of freshrss above, could you speculate as to why I'm seeing those permissions issues?
Oh, I was using --user tobwen --userns=keep-id
here. You're right, I'm also ending up on IDs like 166536
on the host, when creating another user.
keep-id: creates a user namespace where the current rootless user’s UID:GID are mapped to the same values in the container. This option is ignored for containers created by the root user.
From the podman run
documentation it would appear that using --userns=keep-id
will only affect the uid:gid of the user that starts the command inside of the container once running. How would this result in several other uid/gid getting mapped to a different uid? Similarly, the --user
flag only affects the uid:gid of the user that runs the default command/entrypoint for the container image as specified by the appropriate directive in the Containerfile.
@jmpolom this is what I expected but didn't have a chance to fully verify. My assumption was that --user
was implicit when running rootless.
The question I'd have is, how do I "snipe" some UIDs and map them to host IDs? similar to what I'd mentioned above, for a single UID mapping:
--uidmap=0:60600000:909 --uidmap=910:606:1 --uidmap=911:60600911:64626
For multiple?
--uidmap=0:60600000:909 --uidmap=910:606:1 --uidmap=911:607:1 --uidmap=912:60600911:64625
Then I can use group membership of host based users to alleviate management of files on disk.
I think there's a more difficult thing to consider. When you would be able to assign multiple "users inside the container" to one user "outside the container" - how to get reassign it correctly on the next run?
Let's say: 991
, 995
, 996
, 997
(inside) get mapped to 1001
outside
How do you want to recover the internal UIDs, when it's all 1001
outside? You can't "split" it back to the original "internal" UIDs.
Did you consider ACLs on those directories? ACLs often don't get overwritten by containers, since the permissions are missing. But beware of creating new files or chowning permissions. Those have to match the "internal" UID of course.
I think you are asking for stuff that user namespace can not do.
if you want to use real UIDs mapped to real UID within the container, then you need to handle this with --uidmap, and --gidmap, which will not be pretty. You would also need all of the entries added to /etc/subuid and /etc/subgid.
BTW You can manipulate all of the files in the volume, by simply executing a script with
podman unshare chown
and then chown the files to what you want.
mapping system IDs (< 1000) in a rootless container is a bad practice as you are allowing your unprivileged user to access system IDs.
If you want 1->1 mapping on the host, could it be done with a a root container without user namespaces?
podman unshare chown
and then chown the files to what you want.
Wouldn't a chmod 777
(or such) be better because a chown
might make it unreadable from the container. Or chown :host-user
and chmod g+rwX
?
depends what you are aiming at.
If you want to make the files world writeable/readable then that is fine.
if you want to chown to your own user, then you need a different command, and that probably will make files not accessible from the container.
I am closing the issue as I am not sure what we can do from Podman, but feel free to keep commenting
Was going to post to the mailing list, but this may be more discoverable... and it may result in a feature/enhancement documentation change.
The shortest form of my question/confusion is:
The follow up to this would be, how does one handle many non-root users (e.g. gitlab omnibus container has many non-root users writing to disk)?
For example:
/etc/subuid
and/etc/subgid
container_id: 0
is mapped tohist_id: 606
expected behavior is that all other users inside the container will be mapped into the
uid
andgid
space of60600000
with a maximum of65536
users/groups allowedLet's test this out:
Now, the freshrss name is because there a good example of a simple container that utilizes the non-root user within itself, there is documentation on their standards of uid and gid here.
We know that if we run this container there is a default
uid
andgid
of910
:I'd love to know how to "clobber" these filesystem operations back to the initiating host user. What I'd like to see is that these things created on disk are
uid
andgid
of606
. Looking over the documentation I've been unable to figure this out, however I've tried a couple things:--privileged=true
hoping that it would somehow decimate all the users within the container back to606
on the host.--uidmap
several times, specifically trying to map both0
in the container and910
in the container to606
on the host.--userns=host
, however I think this is actually the default behavior?tried
--userns=keep-id
but then the container user (910 in the container) can't write to the volumeUltimately I'd really like to know, if its possible given podman's design, to achieve the goal of:
uid
andgid
on filesystemThis phenomena gets more complex with "bigger" containers, for example the gitlab omnibus has many users writing to the filesystem so you get a smattering of mapped
uid
andgid
.