Closed abitrolly closed 5 years ago
I have to ask this question, because USER
creates additional problems with volume mapping - #3990.
Yes it still makes sense.
Podman runs as root as well as non-root, and by default even when run in non-root, you might not want your processes to run as root
of the container.
If those processes that run under root
inside container can not affect host system, then I do not see why I need to run them under different user.
There is only one reason mentioned in other issue - because podman
maps container_uid
of root
to host_uid
of user running the container, then a process that can escape the container can read user private data including SSH keys.
Yes I would prefer to always run as non-root, but things like binding to ports<1024 and the abilty for apache to switch to a non-root user still require root.
@rhatdan has answered the questions, closing.
@rhatdan in the article https://www.redhat.com/sysadmin/rootless-podman-makes-sense there is a mistake - the container that is being run is SchemaSpy, not PostgreSQL, and unlike Postgres, the process inside produces html
directory with report that needs to be passed to host machine. I could not run its container with podman
, because the container uses USER=java
.
I tried to remove the USER in https://github.com/schemaspy/schemaspy/pull/590 one time already and now again hitting the same problem. The learning curve is steep.
What the article lacks is the summary, which is podman unpriviliged containers is not enough to secure your SSH keys. First, processes in unpriviliged containers are run under you. It is easy to check.
$ podman run -it --rm fedora bash --debug
[root@8e0ff10181af /]#
$ ps faxo "uname,pid,args" | grep "bash --debug"
anatoli 56683 | | \_ grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn bash --debug
anatoli 55466 | \_ podman run -it --rm fedora bash --debug
anatoli 55494 \_ bash --debug
Which means if bash --debug
breaks from container, or breaks filesystem access layer, or if I map my HOME into it, it will be able to steal my keys.
The proper way to securely run unpriviliged container is to run it under some unknown user. postgres
container does just this.
➜ ~ ps faxo "uname,pid,args" | grep "postgres"
anatoli 28472 | | \_ podman run postgres
anatoli 58406 | \_ grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn postgres
100998 28496 | \_ postgres
100998 28554 | \_ postgres: checkpointer
100998 28555 | \_ postgres: background writer
100998 28556 | \_ postgres: walwriter
100998 28557 | \_ postgres: autovacuum launcher
100998 28558 | \_ postgres: stats collector
100998 28559 | \_ postgres: logical replication launcher
And it works perfectly, if you don't need to map volume for writing as in the case with SchemaSpy.
Now I need to reread the article to go deeper into the hole as I don't remember what unshare
does.
SELinux would prevent a container from reading your .ssh keys if it was to escape. Also if you run the container with any user other then root, that process would not be able to read your .ssh keys based on UID protections. UID 1000065 is not going to be able to read content owned by uid 1000.
But yes if you run your container with your UID==root inside of a user namespace and do not use SELinux and the container process escapes it could read any content in your homedir.
Podman unshare basically sets up the default user namespace that podman uses when running containers. It allows you do do stuff like podman mount if you wanted to examine a container image.
Every athing that podman does in a rootless environment is done in a User Namespace.
https://opensource.com/article/19/2/how-does-rootless-podman-work
I don't really get the whole picture of root, user, user namespace, SELinux and podman unshare
in my head. Too much information. Maybe it is better to start with a practical example. Let's assume SELinux is not there. How should I modify my script that mounts current directory writable inside container to make it work with containers that use USER java
like image from SchemaSpy does?
##!/usr/bin/env bash
# name of current dir
NAME=$(basename "$PWD")
podman run -v "$(pwd)":"/root/$NAME":Z -w "/root/$NAME" -it $*
basically the /root/$NAME directory would need to be accessible by the java
user within the container.
Are you attempting to run this script as root or as non root?
@rhatdan as non-root.
Well most likely a podman user will not be allowed to see /root/$NAME.
If the rootless user can see /root/$NAME then it probably should be owned by his UID or the UID of java running within the user namespace.
Let's change your example to /var/tmp/$NAME, to make it simpler for me to understand. Where $NAME is the user running the container. If his UID == 1000, then this directory should be owner by 1000:1000. Now say that the "java" user inside of the container is uid 1001. Then the UID of content this user needs to be able to read/write would probably be... JAVAUID - 1 + 100,000 (First UID of range of UIDS allocated in /etc/subuid). That is the JAVA UID of the process inside of the container.
@giuseppe We need to make this easier for users...
@rhatdan and there is still no answer to the question how should I modify my script. I don't care which user runs inside container as long as the volume can be written.
Well if the volume is owned by the user or has write permissions of the users group, then it should be writeable. chown -R $NAME:$NAME /root/$NAME
@rhatdan what does mean "volume is owned by user". $NAME
in my script is the short directory name that I want to mount in my home. I run podman
as myself, no root. Dockerfile
for container that I run includes instruction USER java
. The process in container can not write to this dir mounted using this script.
#!/usr/bin/env bash
# name of current dir
NAME=$(basename "$PWD")
podman run -v "$(pwd):/root/$NAME":Z -w "/root/$NAME" -it "$@"
How to modify it to allow writes without giving up on security?
chown -R $USER:$USER /root/$NAME chown -R abitrolly:arbitrolly /root/$NAME
That will mean that all of the content will be owned by your user and will show up as "ROOT" in the rootless container. Since Your user is ROOT in the namespace.
chown -R abitrolly:abitrolly /root/$NAME
That will mean that all of the content will be owned by your user and will show up as "ROOT" in the rootless container. Since Your user is ROOT in the namespace.
chown
needs to be run outside or inside the container? Because outside it is alreadyabitrolly:abitrolly
, and inside it should fail, because inside the user isjava
. I can not test right now.
What is the UID of java inside of the container?
Also what does
cat /proc/self/uid_map inside of the container look like.
Wow, this stuff is way too complicated. I've the same issue as @abitrolly (running podman as non-root, having a user inside the container that is not "root" and I cannot write to the mounted directory). I've read every comment here and I still don't have an idea how to make this work.
@ChristianCiach podman unshare chown UID:GID -R PATH
I consider running with root in the container better because it's more portable. Running with a hardcoded UID (like 1000) can make it very difficult (even impractical) when using volumes. If the user escalating from the container to the host is really a concern for whoever runs the container, afraid that the user in the container could be able to access the user credentials on the host, then I consider a better approach for the consumer of the image to create another user on the host and running podman with this user, instead of hardcoding the UID in the image and forcing every consumer to use that specific UID.
Here for a more detailed explanation: https://github.com/Requarks/wiki/issues/1612#issuecomment-640804157 (this is also related to docker, not only podman, but I think a part of it applies to podman too).
I see that projects are still adding
USER
directive to Dockerfile in order to secure their containers withdocker
. Does that still make sense withpodman
?