This means that if a process in the container breaks out it will be severely restricted on the container host.Īnother question that comes up is, can the system run out of UIDs when you add a bunch of users? The short answer is, yes. The set of user IDs from 100,000 to 165,535 has no special privilege on the system, not even as the user fatherlinux (1000). This is a great security feature because now the container engine and the containerized process inside the running container are both running as different, unprivileged users. But, when Podman is run as fatherlinux it maps root inside the container to the fatherlinux user (1000), and the sync user (uid 5) to a UID in the range of 100,000 and 165,535.
#Docker run as root dockerfile full#
Notice that when Podman is run as root, the full user ID range is available in the container (4294967295 = 32 bits). You can also see this map from inside of a container: The useradd command will reserve the next range for the next user. By default, shadow-utils (useradd, passwd, etc) this range of user IDs is reserved for only one user. With the following entries, the fatherlinux user can map up to 65,535 user IDs in containers to real user IDs on the system starting at 100,000. Here’s an example of entries on my system.
Entries are created in these files when users are added, via the usermod command, or manually by a systems administrator. But, where does this mapping come from? From two files, /etc/subuid and /etc/subgid. This is useful when a container uses multiple users - examples include running Apache and MySQL together in a single container or pod, or running a sidecar container with an agent that runs as a different user. Traditionally, on a Unix system, each user only had one ID, but now it’s possible to have thousands of UIDs at each users disposal for use inside of containers. Well, the short answer is because with newer kernels and newer shadow-utils packages ( useradd, passwd, etc.) each new user is given a range of user IDs at their disposal. Wait! Why didn’t it map the sync user (uid 5) to fatherlinux (uid 1000)? On the other hand, when we run the exact same container as a regular user (fatherlinux), it maps the sync user (uid 5) in the running container to uid 100004 on the underlying container’s host. This means that if a process broke out of this container, it could run with the privileges of the real sync user. The example above demonstrates that when we run a container as root, we are mapping the sync user (uid 5) in the container to the sync user (uid 5) on the underlying container host. Podman also gives us a really cool sub-command called top which lets us map the user on the container host to the user in the running container. Like before, you can research these further by typing man podman-run command. The command line options are -i (interactive) -d (detach) and -u (user) - combined, these options run the container in the background and specify that the containerized process should run as the user sync.
When the kernel creates a running process inside of a container, the user namespace maps the user ID of the containerized processes to a different user ID outside of the container. That’s exactly what user namespaces facilitate.
Stated another way, these two passwd files imply that we could have two sets of users-one set outside of the container, and one set inside of the container. The users in the /etc/passwd file on the Container Host are used for Podman, while the users in the /etc/passwd file in the Container Image are used in the running container. Third, in the above example, Podman is by definition outside of the container and runs as root or a regular user (fatherlinux), while inside the container bash runs as root or a regular user (sync). These are Unix traditions that will help explain root inside and outside of the container. Second, pay close attention to $ which implies our shell is running as a regular user, and # which implies our shell is running as root.
You can research these further by typing ‘man podman-run’ command. First, the command line options are -i (interactive) -t (terminal) and -u (user) - combined, these options give you an interactive terminal inside of the container, and specify that the containerized process should run as the user sync. Let’s point out a few interesting things about the above example.