Skip to main content

Controlling access to rootless Podman for users

It's easy to have mistaken assumptions about security controls when it comes to rootless Podman containers.
Image
6 doors for access control

Image by Arek Socha from Pixabay

Recently the Podman team received a Bugzilla report claiming that there was no way to stop rootless Podman from running containers. The reporter set up a user account with no entries in /etc/subuid and /etc/subgid and reported that rootless Podman could still run the hello-world container.

Mistaken assumption

Removing the user information from /etc/subuid does not prevent users from using Podman. Let's look deeper into what is going on when someone uses rootless Podman to run a container.

First, realize that container images like hello-world are just tarballs along with some JSON content sitting at a web server called a container image registry. Any application that can talk to a web server can pull them down using standard web protocols and tools like curl.

When Podman pulls down an image, it first creates and enters a user namespace. This user namespace usually maps the user's UID to root (UID=0) within the user namespace. It then looks into /etc/subuid for the user and uses the UIDs listed there to populate the rest of UIDs available within the user namespace. It does the same for groups via /etc/subgid. If there are no entries in /etc/subuid and /etc/subgid, then the user namespace consists of just the user's UID mapped as root. Once the user namespace is set up, Podman extracts the tar content of the image. If the image has files owned by users other then UID=0, then Podman extracts and attempts to chown the content to the defined user and group. If the user and group are not defined within the user namespace, then the chown fails, and Podman fails.

In the Bugzilla example, the reporter attempted to execute hello-world.

$ podman run hello-world
Resolved "hello-world" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull docker.io/library/hello-world:latest...
Getting image source signatures
Copying blob b8dfde127a29 done  
Copying config d1165f2212 done  
Writing manifest to image destination
Storing signatures

Hello from Docker!
…

It worked even though the user had no entries in /etc/subuid and /etc/subgid.

Let's enter the user namespace and see what is going on.

Podman unshare cat /proc/self/uid_map
         0       3267         

Notice, my account is set up without access in /etc/subuid. Podman is mapping my UID 3267 to UID 0 for a range of one UIDs. Now let's look at the contents of the container image hello-world. Enter the user namespace, mount the hello-world image, and list the contents.

$ podman unshare
# mnt=$(podman image mount hello-world)
# ls -l $mnt
total 16
-rwxrwxr-x. 1 root root 13336 Mar  5 18:25 hello

Notice the only content is the hello command. This is a statically linked GO binary, owned by root within the user namespace, and UID=3267 in my home directory.

This is why the command worked, even without the extra UIDs and GIDs.

Let's attempt to run a container image with more than one UID.

$ podman run fedora echo hi
Resolved "fedora" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull registry.fedoraproject.org/fedora:latest...
Getting image source signatures
Copying blob 7679c09af385 done  
Copying config 3567369c67 done  
Writing manifest to image destination
Storing signatures
Error: Error committing the finished image: error adding layer with blob "sha256:7679c09af3851a1622782c74864351c296a0d1886813862fd7116383aeba9f07": Error processing tar file(exit status 1): potentially insufficient UIDs or GIDs available in user namespace (requested 0:12 for /var/spool/mail): Check /etc/subuid and /etc/subgid: lchown /var/spool/mail: invalid argument

Notice Podman can pull down the tarballs (it refers to them as blobs). When it attempts to extract them, it fails when it tries to chown the /var/spool/mail directory to a GID (12) not defined within the user namespace, and the container fails.

Bottom line

Running unprivileged containers is safe and can't really affect the system any more than just having a login on the system. The Podman user performs tasks that normal users can do: Pull content from web servers, and untar them. Finally, users can even execute the content. The only failures occur when the user attempts to switch to UIDs that the user is not allowed via commands like chown or su.

In the above example, Podman did not do anything that required extra privileges. All of the processes executed via Podman by the user were under the same constraints as any user process. Actually, they are more constrained since they are wrapped with SELinux, SECCOMP, and other security mechanisms.

Using rootless Podman to execute a container image is no less secure than allowing users to download executable files from a web server and run them in their home directory.

If you still want to prevent certain users on a system from executing Podman, you need to change the permissions on Podman itself.

# chmod 750 /usr/bin/podman
# groupadd podman
# chown root:podman /usr/bin/podman

Add users that you wish to allow access to Podman to the podman group. Just realize that when Podman gets updated, you will need to do the chmod and chown commands again, and rpm -qV podman will report issues with the install.

Extra credit

For advanced users, specifically people in High-Performance Computing (HPC), we added a special flag, ignore_chown_errors, to the container's storage.

man storage.conf
…
       ignore_chown_errors = "false"
         ignore_chown_errors can be set to allow a non privileged user running with a  single UID within a user namespace to run containers. The user can pull and use any image, even those with multiple uids.  Note multiple UIDs will be squashed down to the default uid in the container.  These images will have no separation between the users in the container. (default: false)

By setting this flag in /etc/containers/storage.conf of $HOME/.config/containers/storage.conf to true, Podman can successfully run the Fedora container.

$ grep ignore_chown_err /etc/containers/storage.conf
# ignore_chown_errors can be set to allow a non privileged user running with
ignore_chown_errors = "true"
$ podman unshare cat /proc/self/uid_map
         0        3267          1


$ podman run fedora echo hi
Resolved "fedora" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull registry.fedoraproject.org/fedora:latest...
Getting image source signatures
Copying blob 7679c09af385 done  
Copying config 3567369c67 done  
Writing manifest to image destination
Storing signatures
hi

This time when Podman attempted to chown the /var/spool/mail directory and received an error, it ignored it and continued. HPC does not want users to have more than one UID, so this allows their users to run standard OCI images but not have to loosen their security settings at all. Note that this works fine as long as the only UID that you run inside of the container is the root of the container. If, for any reason, the process attempts to change UID to a UID not defined within the container, it will fail. Also, in most cases, all files in the image will be owned by the user. That user of the container has full read/write permissions on all content.

[ Getting started with containers? Check out this free course. Deploying containerized applications: A technical overview. ]

Wrap up

Podman administrators must be aware of what access levels are being granted. Ensure you understand the intent and function of /etc/subuid and /etc/subgid, and how they will impact container security.

Finally, use the ignore_chown_errors option with care. It was designed for HPC scenarios.

Topics:   Containers   Linux  
Author’s photo

Dan Walsh

Daniel Walsh has worked in the computer security field for over 30 years. Dan is a Consulting Engineer at Red Hat. He joined Red Hat in August 2001. Dan leads the Red Hat Container Engineering team since August 2013, but has been working on container technology for several years. More about me

Try Red Hat Enterprise Linux

Download it at no charge from the Red Hat Developer program.