Is this a BUG REPORT or FEATURE REQUEST? (leave only one on its own line)
/kind bug
Description
Volumes are always owned by root instead of inheriting owner and group from the host.
Steps to reproduce the issue:
podman run --rm -v "$HOME:$HOME" alpine ls -l "$HOME/.."total 4
drwx------ 35 root root 4096 Apr 11 07:55 fnkr
podman run --rm -v "$HOME:$HOME" --user "$(id -u):$(id -g)" alpine ls -l "$(dirname $HOME)"total 4
drwx------ 35 root root 4096 Apr 11 07:55 fnkr
Describe the results you received:
The mount is owned by root.
Describe the results you expected:
The mount should be owned by the current user in both cases. (At least this is what Docker does.)
โ docker run --rm -v "$HOME:$HOME" alpine ls -l "$HOME/.."
total 4
drwx------ 35 1001 1001 4096 Apr 11 08:01 fnkr
โ docker run --rm -v "$HOME:$HOME" --user "$(id -u):$(id -g)" alpine ls -l "$(dirname $HOME)"
total 4
drwx------ 35 1001 1001 4096 Apr 11 08:01 fnkr
Additional information you deem important (e.g. issue happens only occasionally):
100% reproducible. Probably related to https://github.com/containers/libpod/pull/2643 and https://github.com/containers/libpod/issues/2634.
Output of podman version:
โ podman version
Version: 1.2.0
RemoteAPI Version: 1
Go Version: go1.11.5
OS/Arch: linux/amd64
Output of podman info --debug:
debug:
compiler: gc
git commit: ""
go version: go1.11.5
podman version: 1.2.0
host:
BuildahVersion: 1.7.2
Conmon:
package: podman-1.2.0-2.git3bd528e.fc29.x86_64
path: /usr/libexec/podman/conmon
version: 'conmon version 1.12.0-dev, commit: d88bb0e63cb70f9787a8e410716924f380af361f'
Distribution:
distribution: fedora
version: "29"
MemFree: 10356088832
MemTotal: 25145073664
OCIRuntime:
package: runc-1.0.0-68.dev.git6635b4f.fc29.x86_64
path: /usr/bin/runc
version: |-
runc version 1.0.0-rc6+dev
commit: ef9132178ccc3d2775d4fb51f1e431f30cac1398-dirty
spec: 1.0.1-dev
SwapFree: 0
SwapTotal: 0
arch: amd64
cpus: 8
hostname: ping
kernel: 5.0.6-200.fc29.x86_64
os: linux
rootless: true
uptime: 1h 54m 36.7s (Approximately 0.04 days)
insecure registries:
registries: []
registries:
registries:
- docker.io
- registry.fedoraproject.org
- quay.io
- registry.access.redhat.com
- registry.centos.org
store:
ConfigFile: /home/fnkr/.config/containers/storage.conf
ContainerStore:
number: 1
GraphDriverName: overlay
GraphOptions:
- overlay.mount_program=/usr/bin/fuse-overlayfs
GraphRoot: /home/fnkr/.local/share/containers/storage
GraphStatus:
Backing Filesystem: extfs
Native Overlay Diff: "false"
Supports d_type: "true"
Using metacopy: "false"
ImageStore:
number: 26
RunRoot: /run/user/1001
VolumePath: /home/fnkr/.local/share/containers/storage/volumes
Additional environment details (AWS, VirtualBox, physical, etc.):
I'm using Fedora Workstation 29.
Podman by default in rootless mode makes the UID of the user running the command ROOT inside of the container. That means that when you look at the UID of the running process it will be 0, even though the process is really running as your UID. Also any files with your UID as owner or group will be seen as UID==0 while in the container. Any file actually owned by a UID==0 will be seen as -1.
So this is not a bug.
What are you hoping to do in the container?
Hi @rhatdan, thanks for your response. Is there any way to use --user together with volumes? In my use case the name, group, UID, GID and home dir of the user are relevant and I need to access certain files from host and container processes. This is a simplified example of what I'm doing (works with Docker):
--user=$UID --volume="$HOME/build/passwd:/etc/passwd:ro" --volume="$HOME/build:$HOME/build" --workdir="$HOME/build"
If you eliminate the --user=$UID it should work for you, but you will think you are running as root inside of the container. Another option is to use the User Namespace differently.
I am going to guess that your UID == 1000, Current
And you have a line like this in the /etc/subuid file.
fnkr:100000:65536
If you ran podman with the following commands
$ podman run --uidmap 0:100000:1000 --uidmap 1000:1000:1 --uidmap 1001:101000:64536 ...
Then you will get the environment you envision.
You will have to play with the UID Ranges above to get this correct.
@giuseppe I wonder if we should make this an option for podman,
podman --uidmap user, which would do the above automatically.
โ podman run --uidmap 0:100000:1000 --uidmap 1000:1000:1 --uidmap 1001:101000:64536 alpne ls
Error: error creating libpod runtime: there might not be enough IDs available in the namespace (requested 100000:100000 for /home/fnkr/.local/share/containers/storage/overlay/l): chown /home/fnkr/.local/share/containers/storage/overlay/l: invalid argument
I changed the command slightly to get it working, but now files from the volume are owned by nobody:
โ podman run --rm -v="$PWD:$PWD" -w="$PWD" --uidmap=0:10000:$((UID)) --uidmap=$UID:$UID:1 --uidmap=$((UID+1)):$((UID+10001)):$((55536-UID)) alpine ls -l -n
total 0
-rw-r--r-- 1 65534 65534 0 Apr 12 17:47 test
โ ls -l -n
total 0
-rw-r--r--. 1 1001 1001 0 Apr 12 17:47 test
I like it, I would love to make this easier for non expert users.
Seems like users are running non rootl containers, where they expect their UID==UID in the container and others expect their UID == 0 inside the container. The desktop team has built toolbox which is a wrapper around podman but does the UID==UID mapping.
podman run --match-uid maybe?
I would want something to indicate this is usernamespace --userns-map-uid
we could do that, it should be pretty easy. We need to provide a preconfigured mapping for the namespace. We also need --user to be configured though
We could default to the logged-in user's UID
@giuseppe Why would we need --user? I still am fine with them being root when the container starts and then remapping to their user.
@mheon I don't think we should change the default. If we had a flag that changed the default then you could toggle the flag via an environment variable.
We need user for the effective setresuid in the oci runtime, that needs to happen after the second mapping is in place.
Hi,
I couldn't figure out how to fix this yet. If I use --uidmap the UID/GID of volumes is always 65534.
โ podman run --rm -v="$PWD:$PWD" -w="$PWD" --uidmap=0:10000:$((UID)) --uidmap=$UID:$UID:1 --uidmap=$((UID+1)):$((UID+10001)):$((55536-UID)) alpine ls -l -n
total 0
-rw-r--r-- 1 65534 65534 0 Apr 12 17:47 test
โ ls -l -n
total 0
-rw-r--r--. 1 1001 1001 0 Apr 12 17:47 test
Is uid 1001 mapped into your container? If not it will show up as 65534
Yes, it is ($UID is 1001). This is how the command is expanded:
โ podman run --rm -v="$PWD:$PWD" -w "$PWD" --uidmap=0:10000:1001 --uidmap=1001:1001:1 --uidmap=1002:11002:54535 alpine ls -l -n
Here is another example that doesn't work either:
โ podman run --rm -v="$PWD:$PWD" -w "$PWD" --uidmap=0:10000:10 --uidmap=1000:1000:1000 alpine ls -l -n
@fnk
@giuseppe I am seeing this also. Any ideas?
podman run --rm -v="$PWD:$PWD" --privileged -w "$PWD" --uidmap=0:10000:3267 --uidmap=3267:3267:1 alpine ls -l -n
Is showing me the files in my homedir as:
-rw-rw-r-- 1 65534 65534 13426 Apr 17 12:30 run.bats
-rw-rw-r-- 1 65534 65534 1212 Apr 15 20:15 secrets.bats
-rw-rw-r-- 1 65534 65534 2597 Apr 15 20:15 selinux.bats
drwxrwxr-x 2 65534 65534 4096 Sep 17 2018 serve
$ ls -l -n umount.bats
-rw-rw-r--. 1 3267 3267 1780 Apr 15 16:15 umount.bats
$ podman run --rm -v="$PWD:$PWD" --privileged -w "$PWD" --uidmap=0:10000:3267 --uidmap=3267:3267:1 --uidmap=3268:13268:100 alpine ls -l -n umount.bats
-rw-rw-r-- 1 65534 65534 1780 Apr 15 20:15 umount.bats
$ podman run --rm -v="$PWD:$PWD" --privileged -w "$PWD" --uidmap=0:10000:3267 --uidmap=3267:3267:1 --uidmap=3268:13268:100 alpine cat /proc/self/uid_map
0 10000 3267
3267 3267 1
3268 13268 100
root from the first namespace (which is your user) is not mapped inside the new namespace, you need to do --uidmap=3267:0:1
So the issue here is that my command is executing in the second namespace.
we need to use something like fedora-toolbox: https://github.com/debarshiray/toolbox/blob/master/toolbox#L732-L734
Very confusing for the user.
@rhatdan agreed. We need to do this automatically:
user_id_real=$(id -u)
max_uid_count=65536
max_minus_uid=$((max_uid_count - user_id_real))
uid_plus_one=$((user_id_real + 1))
podman run --rm -v="$PWD:$PWD" --privileged -w "$PWD" --uidmap "$user_id_real":0:1 --uidmap 0:1:"$user_id_real" --uidmap "$uid_plus_one":"$uid_plus_one":"$max_minus_uid" alpine ls -l -n
To allow for users above 65536 you will need something like:
user_id_real=$(id -u)
max_uid_count=65536
max_minus_uid=$((max_uid_count - user_id_real))
uid_plus_one=$((user_id_real + 1))
if $user_id_real < 65536 ; then
podman run --rm -v="$PWD:$PWD" --privileged -w "$PWD" --uidmap "$user_id_real":0:1 --uidmap 0:1:"$user_id_real" --uidmap "$uid_plus_one":"$uid_plus_one":"$max_minus_uid" alpine ls -l -n
else
podman run --rm -v="$PWD:$PWD" --privileged -w "$PWD" --uidmap "$user_id_real":0:1 --uidmap 0:1:65536 alpine ls -l -n
fi
Since I keep getting yelled at for recommending --privileged, I'm trying to work out how I can mount a volume unprivileged such that the root user in the container writes files to that volume as the user who started the container. (In other words, when the container stops, the files that were written are owned by the user who started the container).
Here's what I've tried:
podman run --rm -it -v "/tmp:/tmp" alpine touch /tmp/test.txt
Here's what I get:
touch: text.txt: Permission denied
But, magically, it works if I add --privileged:
podman run --rm -it --privileged -v "/tmp:/tmp" alpine touch /tmp/test.txt
Am I violating security best practices by adding --privileged? Or is it safe because this is podman? I'm confused. If it is safe, it would be nice if the documentation would say so.
Are you running Podman rootless, or with root?
The problem is likely SELinux, given that the user in question should have
permissions to write in /tmp otherwise. Privileged relaxes the container's
SELinux constraints, so it makes sense that it resolves the issue.
If you're running Podman rootless, using privileged increases the
container's ability to interact with the system (more of the host is
mounted into the container, SELinux and Seccomp restrictions are relaxed,
etc), but it still has no privileges the user that launched the container
did not.
If you only need to make files and don't want the other effects of
privileged, security-opt label=disable might work better. You can also use
:z on the volume mounts to label them for container use, but I'd only
recommend that for folders you made explicitly to share with the container
(relabelling /tmp for example would probably break your system)
On Sat, Apr 27, 2019, 05:12 Dan Allen notifications@github.com wrote:
Since I keep getting yelled at for recommending --privileged, I'm trying
to work out how I can mount a volume unprivileged such that the root user
in the container writes files to that volume as the user who started the
container. (In other words, when the container stops, the files that were
written are owned by the user who started the container).Here's what I've tried:
podman run --rm -it -v "/tmp:/tmp" alpine touch /tmp/test.txt
Here's what I get:
touch: text.txt: Permission denied
But, magically, it works if I add --privileged:
podman run --rm -it --privileged -v "/tmp:/tmp" alpine touch /tmp/test.txt
Am I violating security best practices by adding --privileged? Or is it
safe because this is podman? I'm confused. If it is safe, it would be nice
if the documentation would say so.โ
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/containers/libpod/issues/2898#issuecomment-487269663,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AB3AOCA7DD2U4YMDOUKMVZ3PSQKHFANCNFSM4HFEIAOA
.
If you're running Podman rootless, using privileged increases the container's ability to interact with the system (more of the host is mounted into the container, SELinux and Seccomp restrictions are relaxed, etc), but it still has no privileges the user that launched the container did not.
That is exactly what I needed to know. And it's also exactly the behavior I need to make volumes viable. (The use case is to invoke the container as though it is a local command to save the user from having to install a toolchain).
Is there anywhere in the documentation I can link to that makes this assertion?
You might want to look at the gnome toolbox package, which is designed for pretty much your use case. It wraps podman to act in a behaviour where it gives the users their own container, which they can become root and install what ever software they want, but does not effect the host OS.
I wrote a series of blogs on podman and user namespace out on opensource.com
@rhatdan I appreciate that suggestion, and I will certainly look into it for my own use.
However, when it comes to providing instructions for users who want to run a piece of software without having to install the whole toolchain, that's asking too much of them. They just want to know what command they have to type into the console to be able to run the application. It's a means to an end. And for that, the podman command alone is what they're after. And it's something that requires very little explanation (once we sort out the right arguments for them to use).
I am not arguing against the use of podman. Podman is the tool for a user to install a containerized application. That is why we are building it.
If a user wants to install RPMs on his host and is not allowed to run as root, then toolbox wrapping of podman becomes an interesting way to allow users to to do this use case.
Obviously podman can do this, since toolbox is just wrapping it, but toolbox makes different assumptions on how the user runs the container.
@mojavelinux We've mentioned that rootless uses no additional privileges in a few blog posts, but nothing in the README or manpages.
That sounds like a big omission on our part, so I'll look into getting something written up for the README first, and then maybe the manpages
@mojavelinux I took a first pass at adding a description in #3038 - would appreciate your checking to see if this would have adequately answered your question, or if we need to include more detail.
@mheon I very appreciate you following up to add information about this to the docs. However, the paragraph you added doesn't really enhance my knowledge or understanding in anyway. Specifically, I don't see any mention of --privileged and how it pertains to volume mounts. That's really the issue at hand here. I would expect something like:
Running rootless has the advantage that the container has no more access to the host system than the user who launched it. Yet, by default, it's even more restricted then that. To give the container the same permission the host system as the user who launched it, such as the ability to mount volumes read/write, you'll need to add the
--privilegedflag. Bear in mind that, with rootless podman, this does not grant the container privileged beyond what the user who launched it has. In other words, the behavior diffs from the same flag in Docker, which in contrast does violate that permission boundary.
Honestly, I think it was a poor decision to reuse the same flag as in Docker since clearly it has very different implications. But for consistency, I could see the benefits if it is properly documented.
A lot of the implications are still the same - we're still relaxing Seccomp, SELinux, and restrictions on mounts in /proc and /sys. The biggest difference is the starting point in terms of permissions and capabilities - we can grant you additional privileges with --privileged, but nothing more than what you started with in the first place.
(I should probably put that bit in the readme too)
where are we on this one?
Actually, I think @giuseppe solved our other issues with a --userns option
I'm going to close as we've added documentation and https://github.com/containers/libpod/pull/3196 added a way to retain UIDs
The --userns=keep-id thing did not work for me, while my volume had the right uid, the rest of the system was also owned by it instead of root. While the solution by @stevenwhately works perfectly for me, I will repeat it here in sh syntax for anyone stumbling across this:
user_id_real=$(id -u)
max_uid_count=65536
max_minus_uid=$((max_uid_count - user_id_real))
uid_plus_one=$((user_id_real + 1))
if [ $user_id_real -lt 65536 ]; then
extra_args="--privileged --uidmap $user_id_real:0:1 --uidmap 0:1:$user_id_real --uidmap $uid_plus_one:$uid_plus_one:$max_minus_uid"
else
extra_args="--privileged --uidmap $user_id_real:0:1 --uidmap 0:1:65536"
fi
Most helpful comment
I like it, I would love to make this easier for non expert users.
Seems like users are running non rootl containers, where they expect their UID==UID in the container and others expect their UID == 0 inside the container. The desktop team has built toolbox which is a wrapper around podman but does the UID==UID mapping.