Docker containers before 1.2 could either be given complete capabilities under privileged mode, or they can all follow a whitelist of allowed capabilities while dropping all others. If the flag --privileged
is used, it will grant all capabilities to the container. This was not recommended for production use because it's really unsafe; it allowed Docker all privileges as a process under the direct host.
With Docker 1.2, two flags have been introduced with docker run
:
--cap-add
--cap-drop
These two flags provide fine-grain control to a container, for example, as follows:
docker run --cap-add=NET_ADMIN busybox sh -c "ip link eth0 down"
docker run --cap-drop=CHOWN ...
mknod
:docker run --cap-add=ALL --cap-drop=MKNOD ...
Docker starts containers with a restricted set of capabilities by default. Capabilities convert a binary mode of root and non-root to a more fine-grained access control. As an example, a web server which serves HTTP request needs to be bound to port 80 for HTTP and 443 for HTTPs. These servers need not be run in the root mode. These servers can be granted net_bind_service
capability.
Containers and servers are a little different in this context. Servers need to run a few processes in the root mode. For example, ssh, cron, and network configurations to handle dhcp, and so on. Containers, on the other hand, do not need this access.
The following tasks need not happen in the container:
We can safely deduce containers might not need root priviledges.
Examples that can be denied are as follows:
Docker allows only the following capabilities:
Capabilities: []string{ "CHOWN", "DAC_OVERRIDE", "FSETID", "FOWNER", "MKNOD", "NET_RAW", "SETGID", "SETUID", "SETFCAP", "SETPCAP", "NET_BIND_SERVICE", "SYS_CHROOT", "KILL", "AUDIT_WRITE", },
A reference to the preceding code is at https://github.com/docker/docker/blob/master/daemon/execdriver/native/template/default_template_linux.go.
A full list of available capabilities can be found in the Linux man-pages (http://man7.org/linux/man-pages/man7/capabilities.7.html).
One primary risk with running Docker containers is that the default set of capabilities and mounts given to a container may provide incomplete isolation, either independently or when used in combination with kernel vulnerabilities.
Docker supports the addition and removal of capabilities, allowing the use of a non-default profile. This may make Docker more secure through capability removal or less secure through the addition of capabilities. The best practice for users would be to remove all capabilities except those explicitly required for their processes.