Skip to content

Commit

Permalink
Clarify Docker Security considerations -- with added emphasis on secu…
Browse files Browse the repository at this point in the history
…ring the underlying host and controlling access to the docker daemon
  • Loading branch information
markriggins committed Oct 27, 2015
1 parent ebf8ca9 commit 27abf63
Showing 1 changed file with 81 additions and 71 deletions.
152 changes: 81 additions & 71 deletions docs/articles/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,89 @@ weight = 2

There are three major areas to consider when reviewing Docker security:

- the intrinsic security of the kernel and its support for
namespaces and cgroups;
- the attack surface of the Docker daemon itself;
- loopholes in the container configuration profile, either by default,
or when customized by users.
- the "hardening" security features of the kernel and how they
interact with containers.
- **Host Security** -- the attack surface of the underlying host and the
Docker daemon itself;
- **Container Security** -- and how it interacts with namespaces, cgroups,
and "hardening" features of the kernel
- **Configuring Containers for Least Privilege**

## Host Security
The overall purpose and design of Docker Security is to protect against
**external attack vectors**, with a focus on keeping containers isolated and
operating with least privilege. First, it is essential that you control access
to the host and keep it securely configured. Secondly, the Docker daemon
currently requires `root` privileges, and you should therefore be aware of
some important details:

###Docker Daemon Security Details

**Only trusted users should be allowed to control your Docker daemon**.
Running containers (and applications) with Docker implies running the
Docker daemon.

This is a direct consequence of some powerful Docker
features. Specifically, Docker allows you to share a directory between
the Docker host and a guest container; and it allows you to do so
without limiting the access rights of the container. This means that you
can start a container where the `/host` directory will be the `/` directory
on your host; and the container will be able to alter your host filesystem
without any restriction. This is similar to how virtualization systems
allow filesystem resource sharing. Nothing prevents you from sharing your
root filesystem (or even your root block device) with a virtual machine.

This has a strong security implication: for example, if you instrument Docker
from a web server to provision containers through an API, you should be
even more careful than usual with parameter checking, to make sure that
a malicious user cannot pass crafted parameters causing Docker to create
arbitrary containers.

For this reason, the REST API endpoint (used by the Docker CLI to
communicate with the Docker daemon) changed in Docker 0.5.2, and now
uses a UNIX socket instead of a TCP socket bound on 127.0.0.1 (the
latter being prone to cross-site-scripting attacks if you happen to run
Docker directly on your local machine, outside of a VM). You can then
use traditional UNIX permission checks to limit access to the control
socket.

You can also expose the REST API over HTTP if you explicitly decide to do so.
However, if you do that, being aware of the above mentioned security
implication, you should ensure that it will be reachable only from a
trusted network or VPN; or protected with e.g., `stunnel` and client SSL
certificates. You can also secure them with [HTTPS and
certificates](../articles/https/).

## Kernel namespaces
The daemon is also potentially vulnerable to other inputs, such as image
loading from either disk with 'docker load', or from the network with
'docker pull'. This has been a focus of improvement in the community,
especially for 'pull' security. While these overlap, it should be noted
that 'docker load' is a mechanism for backup and restore and is not
currently considered a secure mechanism for loading images. As of
Docker 1.3.2, images are now extracted in a chrooted subprocess on
Linux/Unix platforms, being the first-step in a wider effort toward
privilege separation.

Eventually, it is expected that the Docker daemon will run restricted
privileges, delegating operations well-audited sub-processes,
each with its own (very limited) scope of Linux capabilities,
virtual network setup, filesystem management, etc. That is, most likely,
pieces of the Docker engine itself will run inside of containers.

Finally, if you run Docker on a server, it is recommended to run
exclusively Docker in the server, and move all other services within
containers controlled by Docker. Of course, it is fine to keep your
favorite admin tools (probably at least an SSH server), as well as
existing monitoring/supervision processes (e.g., NRPE, collectd, etc).


## Container Security

Docker containers are very similar to LXC containers, and they have
similar security features. When you start a container with
`docker run`, behind the scenes Docker creates a set of namespaces and control
groups for the container.

### Kernel namespaces

**Namespaces provide the first and most straightforward form of
isolation**: processes running within a container cannot see, and even
less affect, processes running in another container, or in the host
Expand Down Expand Up @@ -60,7 +128,7 @@ http://en.wikipedia.org/wiki/OpenVZ) in such a way that they could be
merged within the mainstream kernel. And OpenVZ was initially released
in 2005, so both the design and the implementation are pretty mature.

## Control groups
### Control groups

Control Groups are another key component of Linux Containers. They
implement resource accounting and limiting. They provide many
Expand All @@ -79,67 +147,8 @@ when some applications start to misbehave.
Control Groups have been around for a while as well: the code was
started in 2006, and initially merged in kernel 2.6.24.

## Docker daemon attack surface

Running containers (and applications) with Docker implies running the
Docker daemon. This daemon currently requires `root` privileges, and you
should therefore be aware of some important details.

First of all, **only trusted users should be allowed to control your
Docker daemon**. This is a direct consequence of some powerful Docker
features. Specifically, Docker allows you to share a directory between
the Docker host and a guest container; and it allows you to do so
without limiting the access rights of the container. This means that you
can start a container where the `/host` directory will be the `/` directory
on your host; and the container will be able to alter your host filesystem
without any restriction. This is similar to how virtualization systems
allow filesystem resource sharing. Nothing prevents you from sharing your
root filesystem (or even your root block device) with a virtual machine.

This has a strong security implication: for example, if you instrument Docker
from a web server to provision containers through an API, you should be
even more careful than usual with parameter checking, to make sure that
a malicious user cannot pass crafted parameters causing Docker to create
arbitrary containers.

For this reason, the REST API endpoint (used by the Docker CLI to
communicate with the Docker daemon) changed in Docker 0.5.2, and now
uses a UNIX socket instead of a TCP socket bound on 127.0.0.1 (the
latter being prone to cross-site-scripting attacks if you happen to run
Docker directly on your local machine, outside of a VM). You can then
use traditional UNIX permission checks to limit access to the control
socket.

You can also expose the REST API over HTTP if you explicitly decide to do so.
However, if you do that, being aware of the above mentioned security
implication, you should ensure that it will be reachable only from a
trusted network or VPN; or protected with e.g., `stunnel` and client SSL
certificates. You can also secure them with [HTTPS and
certificates](../articles/https/).

The daemon is also potentially vulnerable to other inputs, such as image
loading from either disk with 'docker load', or from the network with
'docker pull'. This has been a focus of improvement in the community,
especially for 'pull' security. While these overlap, it should be noted
that 'docker load' is a mechanism for backup and restore and is not
currently considered a secure mechanism for loading images. As of
Docker 1.3.2, images are now extracted in a chrooted subprocess on
Linux/Unix platforms, being the first-step in a wider effort toward
privilege separation.

Eventually, it is expected that the Docker daemon will run restricted
privileges, delegating operations well-audited sub-processes,
each with its own (very limited) scope of Linux capabilities,
virtual network setup, filesystem management, etc. That is, most likely,
pieces of the Docker engine itself will run inside of containers.

Finally, if you run Docker on a server, it is recommended to run
exclusively Docker in the server, and move all other services within
containers controlled by Docker. Of course, it is fine to keep your
favorite admin tools (probably at least an SSH server), as well as
existing monitoring/supervision processes (e.g., NRPE, collectd, etc).

## Linux kernel capabilities
### Linux kernel capabilities

By default, Docker starts containers with a restricted set of
capabilities. What does that mean?
Expand Down Expand Up @@ -177,7 +186,8 @@ infrastructure around the container:
is specifically engineered to behave like a router or firewall, of
course).

This means that in most cases, containers will not need "real" root
## Configuring Containers for Least Privilege
In most cases, containers will not need "real" root
privileges *at all*. And therefore, containers can run with a reduced
capability set; meaning that "root" within a container has much less
privileges than the real "root". For instance, it is possible to:
Expand Down Expand Up @@ -213,7 +223,7 @@ 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.

## Other kernel security features
### Other kernel security features

Capabilities are just one of the many security features provided by
modern Linux kernels. It is also possible to leverage existing,
Expand Down

0 comments on commit 27abf63

Please sign in to comment.