User Namespaces - Dockerlabs
User Namespaces - Dockerlabs
Difficulty: Intermediate
By default, the Docker daemon runs as root. This allows the daemon to
create and work with the kernel structures required to start containers.
However, it also presents potential security risks. This lab will walk you
through implementing a more secure configuration utilizing user
namespaces.
Prerequisites
You will need all of the following to complete this lab:
You must perform this step while logged in as the ubuntu user.
The first line shows the Docker daemon (dockerd). The second line shows
the ps command you just ran. The first column of the first line shows that
the Docker daemon is running as root.
Note: If you are using a Docker Engine earlier than 1.12 you will
need to substitute dockerd with docker.
The last line of the output above shows that the container is running as root
- uid=0(root) and gid=0(root).
This step has shown you that the Docker daemon runs as root by default.
You have also seen that new containers also start as root.
ubuntu@node:~$ id
1. Use the docker run command with the --user flag to force a new
container to start with the uid and gid of your current user.
uid=1000 gid=1000
The output shows that the container is running under uid 1000 and gid
1000. This proves that the container ran under the security context of a user
and group that you specified.
There are many times when containers need to run under the root security
context, while at the same time not having root access to the entire Docker
Host. This is where user namespaces help!
If you are using a Docker 1.11 or earlier you will need to supplement
dockerd with docker daemon in the previous command.
This will start the Docker Daemon in the background using the default user
namespace mapping where the dockermap user and group are created and
mapped to non-privileged uid and gid ranges in the /etc/subuid and /etc/
subgid files.
The /etc/subuid and /etc/subgid files have a single-line entry for each
user/group. Each line is formatted with three fields as follows -
1. Use the docker info command to verify that user namespace support
is properly enabled.
Containers: 3
Running: 1
Paused: 0
Stopped: 2
Images: 2
<snip>
Docker Root Dir: /var/lib/docker/231072.231072
<snip>
The numbers at the end of the Docker Root Dir line indicate that the
daemon is running inside of a user namespace. The numbers will match
the subordinate user ID of the dockermap user as defined in the /etc/
subuid file.
The Docker daemon’s local store is empty! This is despite the fact that
the alpine image was pulled locally in a previous step. This is because
this instance of the Docker daemon is running inside of a brand new
namespace and has no visibility of anything outside of that namespace.
1. Start a new container in interactive mode and mount the Docker Host’s
/bin directory as a volume.
The previous command should have attached you to the terminal of the
newly created container. The following commands should be ran from inside
of the container created in the previous step.
/ # id
The output above shows that the container is running under the root user’s
security context. Remember that this is only root within the scope of the
namespace that the container is running in.
1. Try and delete a file that exists in the volume that you mounted from
the Docker Host’s filesystem into the container as a volume.
/ # rm host/bin/sh
The operation fails with a permission denied error. This is because the file
you are trying to delete exists in the local filesystem of the Docker Host and
the container does not have root access outside of the namespace that it
exists in.
If you perform the same operation - start the same container and attempt
the same rm command - without user namespace support enabled, the
operation will succeed.
Step 2: Clean-up
The following commands will clean up the user namespace you’ve been
working in and restart the Docker daemon without user namespace support
enabled.
Note: If you are using a version of the Docker Engine prior to 1.12
you will have to substitute dockerd with docker in the previous
killall command.
Summary
In this lab you learned how to start the Docker daemon with user namespace
support enabled. This started the daemon in a new namespace and mapped
the root user inside of the namespace to a non-privileged user outside of the
user namespace. This meant that the root user within the user namespace
had full access to processes and containers within that namespace, but did
not have elevated permissions outside of the namespace.
You proved that the Docker daemon was running within a user namespace
using the docker info command. You saw that the root user inside of a the
user namespace was unable to delete files that existed outside of the
namespace.
Additional Resources
You can refer to the following resources for more information and help: -
Docker: http://www.docker.com