Skip to main content

Understanding rootless Podman's user namespace modes

Customize how you run containers in Podman by changing the user namespace while in rootless mode.

By default, rootless Podman containers map the user's user ID (UID) into the container as root of the user namespace. The podman top command displays this.

To illustrate it, I will launch a ubi9 container and sleep it for 100 seconds, then use the podman top command to show the USER within the container and the host user. In the following examples, I will be using my UID, 3267.

$ id -u
3267

$ podman run -d --rm ubi9 sleep 100
8988c2979ab3548753d7b2947a0261c9eaa31a7c651b0ba5a8411822c9617df3

$ podman top -l user huser
USER    HUSER
root    3267

As you can see, the UID of the process on my system is running as my UID 3267, but inside the container, it is running as root.

[ Download now: Podman basics cheat sheet ]

User namespace modes

I can change this default mapping using the –userns option, which is described in the podman run man page. This list shows the different modes you can pass to the –userns option.

  • Key: "" (Unset)    
    • Host user: $UID
    • Container user: 0 (Default User account mapped to root user in container.) (Default)
  • Key: keep-id
    • Host user: $UID
    • Container user: $UID (Map user account to the same UID within the container.)
  • Key: auto    
    • Host user: $UID  
    • Container user: nil (Host User UID is not mapped into the container. Unique UID is selected from the unused UIDs for the root user inside of the container.)
  • Key: nomap        
    • Host user:  $UID
    • Container user: nil (Host User UID is not mapped into the container. First UID in /etc/subuid range is mapped as the root user inside the container.)

[ Related reading: Why can't I use sudo with rootless Podman? ]

keep-id mode

The second option, keep-id, tells Podman to map the user as itself into the container:

$ podman run -d --userns=keep-id --rm ubi9 sleep 100
08cf48b71a137974ca07a690a39f5e308849eb7ae12c2a16849f638939e4d22d

$ podman top -l user huser
USER        HUSER
dwalsh      dwalsh

In this example, Podman runs the container by default as dwalsh and maps my UID inside of the container as the same outside of the container.

As a side effect of the keep-id mode, Podman adds an entry for the user into the containers /etc/passwd file. I can demonstrate this by running two containers. The first, with keep-id, shows the entry for my user in the /etc/passwd, and the second, with the default mode "", shows no entry for my user in the /etc/passwd file.

$ podman run –rm --userns=keep-id ubi9 grep $UID /etc/passwd
dwalsh:*:3267:3267:Daniel Walsh:/:/bin/sh

$ podman run –rm --userns="" ubi9 grep $UID /etc/passwd

[ Learn everything you need to know about Kubernetes. ]

auto mode

The third option, auto, tells Podman to select a range of UIDs to run a container automatically but does NOT add my UID to the container. But when I run the command, it fails:

$ podman run -d --rm --userns=auto ubi9 sleep 100
Error: creating container storage: could not find enough available IDs

This is because Podman, in auto mode, is looking for 1024 or more UIDs that are not currently used within the user's user namespace. Because containers were already run on this system, and Podman defaults to using 65,000 UIDs, all of the UIDs are used. I can destroy all of my containers that use the entire UID mappings to show this mode:

$ podman rm --all
6b2b28f1799b05bfc17be51359a4bf40ffc82d39ba66a1e3d3ca5d28e9f0db0f
bba7308dac369b1bbccad3cd51c752930e6b3c7d11b7e85bbc9256a7c21e35e1
cfc348cf362124dd46add2d72e572e8a94962ba0e09395a8445b61b095c069db

$ podman run -d --rm --userns=auto ubi9 sleep 100
23fcb83680ce09734ee6a6c87eeae855bdd6e542da55b228880283b9999bede9
kube (volume) $ podman top -l user huser
USER    	HUSER
root    	100000

Notice that the root user within the user namespace is mapped to UID 10000 on my host. If I examine my mappings inside the /etc/subuid file, you will see my subuids start with UID 10000.

$ grep dwalsh /etc/subuid
dwalsh:100000:65536

By default, –userns=auto only uses 1024 UIDs within the user namespace. Podman is smart enough to examine the image, figure out the minimum UIDs needed to run the image, and automatically increase the number of UIDs, if necessary. I can demonstrate this by showing the range of UIDs mapped within two consecutive containers created with auto mode:

$ podman run --userns=auto ubi9 cat /proc/self/uid_map
     	0      	1   	1024
$ podman run --userns=auto ubi9 cat /proc/self/uid_map
     	0   	1025   	1024

Because auto mode does not map the user's UID into the container, it protects all files in the user's home directory from being accessed from within the container (SELinux also does this). Auto mode also runs each container with separate UID maps, guaranteeing that no UIDs are shared. Auto mode works much better in rootful mode since there are so many more UIDs to share than in rootless mode.

[ Want to test your sysadmin skills? Take a skills assessment today. ]

nomap mode

The final supported userns mode is nomap. Podman running containers with –userns=nomap, like auto mode, does not map the user's UID into the container. To illustrate this, I will remove all containers from my system and run in nomap mode:

$ podman rm --all
853513eb97542e5cda735d0c6ef46af8fcd7e5a47246313b8f8a0e9d12c320dd
f54149b25002f4c82c1a58363e929abd9210b21afb6c6c69c2400ec36ef1b91f

$ podman run -d --userns=nomap --rm ubi9 sleep 100
cc09a876879dc4604ca2656da303ff06e54088fd62794a4277d7b170586ca461

$ podman top -l user huser
USER        HUSER
root        100000

Note root inside of the container is mapped to the first UID in my subuid range. Because this container does not map my UID into the user namespace, it does not have access to files owned by my UID except by world access, giving me additional security.

Explore the differences between the modes

To illustrate the difference between these modes, this example shows what a volume mapped into a container looks like. Create a directory and a file in your home directory and mount them into a container. Ownership changes depending on the mode:

$ mkdir test

$ touch test/foobar

$ podman rm --all
0a3246bd2b11186830d82b9073510c8e1df46348ba3c743f02aa244d9fbc9c10

$ podman run -v ./test:/test:Z --rm –userns=”” ubi9 ls -l /test
total 0 -rw-r--r--. 1 root root 0 Dec 29 12:20 foobar

$ podman run --userns=keep-id -v ./test:/test:Z --rm ubi9 ls -l /test
total 0 -rw-r--r--. 1 dwalsh dwalsh 0 Dec 29 12:20 foobar

$ podman run --userns=auto -v ./test:/test:Z --rm ubi9 ls -l /test
total 0 -rw-r--r--. 1 nobody nobody 0 Dec 29 12:20 foobar

$ podman run --userns=nomap -v ./test:/test:Z --rm ubi9 ls -l /test
total 0 -rw-r--r--. 1 nobody nobody 0 Dec 29 12:20 foobar

$ ls -l test
-rw-r--r--. 1 dwalsh dwalsh 0 Dec 29 07:20 foobar

When running in normal mode, the file within the user namespace looks like it is owned by root since my UID is mapped to root within the user namespace. With mode keep-id, the file shows that my UID owns it since my UID inside and outside of the user namespace are the same. With mode auto and nomap, the file looks like it is owned by the user nobody since my UID, 3267, is not mapped inside the user namespace.

If I try to modify the file in these modes, I will get permission denied:

$ podman run --userns="" -v ./test:/test:Z --rm ubi9 touch /test/foobar

$ podman run --userns=keep-id -v ./test:/test:Z --rm ubi9 touch /test/foobar

$ podman run --userns=auto -v ./test:/test:Z --rm ubi9 touch /test/foobar
touch: cannot touch '/test/foobar': Permission denied

$ podman run --userns=nomap -v ./test:/test:Z --rm ubi9 touch /test/foobar
touch: cannot touch '/test/foobar': Permission denied

This illustrates the additional security provided through the auto and nomap modes. But it also demonstrates the difficulties of running in this mode. You can use the U volume option if you want to write to these files in the container when running in nomap or auto mode:

$ podman run --userns=nomap -v ./test:/test:Z,U --rm ubi9 touch /test/foobar

$ ls -l test/
total 0
-rw-r--r--. 1 100000 100000 0 Dec 29 08:38 foobar

The U volume option tells Podman to chown (change owner) the files on disk to match the default user inside of the container, in this case, UID=100000 (root of the container). While this works, these files can become difficult to manage.

[ Learn how to manage your Linux environment for success. ]

Change the default user namespace mode

You can change your system's default user namespace mode by creating or modifying the containers.conf directory to look something like this:

$ cat ~/.config/containers/containers.conf
[containers]
userns = "keep-id"

Now when you run containers, they will automatically be in keep-id mode:

$ podman run -d --rm ubi9 sleep 100
88c34293773b435977e9fc47b5951f55dcf39f7a2dee2f6460168357548e7d63

$ podman top -l user huser
USER    	HUSER
dwalsh  	dwalsh

Wrap up

Understanding the user namespace while in rootless mode allows you to customize the way you run containers to be easier to use and help make them more secure. Podman allows great flexibility.

For more reading on user namespace and all things Podman, check out my book, Podman in Action, or get a complimentary download of the book from Red Hat.

Topics:   Podman   Containers  
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.