There are many sites which preach that we should not run docker containers as root users.
By default, Docker gives root permission to the processes within your containers, which means they have full administrative access to your container and host environments.
I do not understand that how a container can access host environment & cause security vulnerabilities if I do not do volume/port mapping.
Can someone give an example of such security risk?
CodePudding user response:
By default, docker tries to do very strong isolation between containers and host. If you need to have a root user (you can't avoid it) docker offers a security mechanism which maps the root user from the container to a random virtual high UUID on a host which is nothing if someone manages to escape.
Leaving root inside the container can leave the "attacker" option to install additional packages they wish, they see other containers/resources to which container has access (for instance they can try to NMAP around the container), .. well .. they are after all root inside container.
As of example of security risk. There was one "big one" called dirty cow.
Hope I pushed you in the right direction for further research.
CodePudding user response:
docker
and other containerization technology build on the namespaces feature of the Linux kernel to confine and isolated processes, limiting their view on available resources such as the filesystem, access to other processes or to the network.
By default docker
uses a really strong isolation of processes limiting their access to a minimum. This leads many people to believe that running any untrusted process/docker
image within a container is perfectly safe - it is not!
Because albeit the strong isolation of such processes they still run directly on the kernel of the host system. And when they run as root within the container (and not using a user namespace) they are actually root on the host, too. The only thing then preventing a malicious container from completely overtaking the host system is that it has no direct/straight-forward access to critical resources. If, though, it somehow gets ahold on an handle to a resource outside of its namespaces it may be used to break out of the isolation.
It is easy for an incautious user to unintentionally provide such a handle to outside resources to a container. For example:
# DON'T DO THIS
# the user intends to share the mapping of user names to ids with the container
docker run -v /etc/passwd:/etc/passwd untrusted/image
With the process within the container running as root the container would not only be able to read all users in /etc/passwd
but also to edit that file, since it has also root access on the host. In this case - should you really need something like this - best practice would be to bind-mount /etc/passwd
read-only.
Another example: some applications require extended access to system capabilities which requires to loosen some of the strict isolation docker
applies by default, e.g.:
# DON'T DO THIS
docker run --privileged --cap-add=CAP_ALL untrusted/image
This would remove most of the limitations and most notably would allow the container to load new kernel modules, i.e., inject and execute arbitrary code into the kernel, which is obviously bad.
But besides giving access to external resources by mistake there also exists the possibility of bugs in the Linux kernel that could be exploited to escape the isolation of the container - which are much easier to use when the process already has root privileges inside the container.
Therefor best practice with docker
is to limit the access of containers as much as possible:
- drop/do not add any capabilities/privileges that are not required
- bind-mount only files/directories that are really required
- use a non-root user when possible
Although starting containers as root is the default in docker
most applications do not actually require being started as root. So why give root privileges when they are not really required?