su - rhel
The User Namespace is easily the newest namespce in the Linux Kernel. It was introduced to allow non-root users to run containers without a heavy root daemon. Typically, a non-priviledged user cannot spawn new namespaces. However, if a new User Namespace is created, then that same user can now spawn any type of namespace. Since this feature was introduced in the Kernel, you have seen newer container images come out that do not rely on daemons because they are no longer necessary.
The User Namespaces allow our sandboxed environment to have its own set of user and group IDs that will map to very high, unique, user and group IDs back on the host system. They also allow the root user in the sandbox to be mapped to another user on the host.
Because we are now invoking the User Namespace, we no longer need to work as root. Let’s switch to a non-priviledged user.
su - rhel
Now let’s unshare some namespaces!
unshare -Ur /bin/bash whoami
Wait… We are root again? I thought we just left root!
Well… yes and no. Inside of our sandbox, we are the root user, but we have instructed unshare to map the root user to our actual UID outside the sandbox. That is what the
r option does. The
U option creates the new User Namespace.
To inspect how UIDs are being mapped, we can query the Kernel state.
0 1001 1
This tells us that root (UID 0) is mapped to rhel (UID 1001) and a span of 1 UID is available for mapping. It is possible to allocate additional UIDs to the sandbox, but that is outside the scope of this workshop.
Let’s look at the UID mapping in the host’s native namespace. Switch to a terminal that is not in your sandbox.
0 0 4294967295
This says that root (UID 0) is mapped to root (UID 0) and a span of 4294967295 UIDs are available. That number may seem odd until you realize it is the maximum value for a 32-bit unsigned integer.
So… let’s test the limts of our root powers. If we were root, we could do some pretty destructive things… Like delete Bash! Go back to the terminal that is in your sandbox.
rm -f /bin/bash
rm: cannot remove '/bin/bash': Permission denied
However, since we are not root outside of the sandbox, we cannot remove files owned by the real root outside of the sandbox.
Let’s do another test.
date > /tmp/test ls -la /tmp/test
-rw-r--r--. 1 root root 29 Feb 6 03:58 /tmp/test
Makes sense. We are root so the files we create are owned by root. But lets leave our sandbox and check that same file in the host’s native namespace. Run the following commands on a terminal that is not in your sandbox.
ls -la /tmp/test
-rw-r--r--. 1 rhel rhel 29 Feb 6 03:58 /tmp/test
So root in the sandbox made the file. Root in the sandbox is mapped to rhel outside the sandbox. So, outside the sandbox rhel owns the file! This means that, as an admin, I can allow users to run containers on my systems without the fear of them becoming root on the host! Security win!