Docker Secure Deployment Guidelines
Within today’s growing cloud-based IT market, there is a strong demand for virtualisation technologies. Unfortunately most virtualisation solutions are not flexible enough to meet developer requirements and the overhead implied by the use of full virtualisation solutions becomes a burden on the scalability of the infrastructure.
Docker reduces that overhead by allowing developers and system administrators to seamlessly deploy containers for applications and services required for business operations. However, because Docker leverages the same kernel as the host system to reduce the need for resources, containers can be exposed to significant security risks if not adequately configured.
The following itemised list suggests hardening actions that can be undertaken to improve the security posture of the containers within their respective environment. It should be noted that proposed solutions only apply to deployment of Linux Docker containers on Linux-based hosts, using the most recent release of Docker at the time of this writing (1.4.0, commit 4595d4f
, dating 11/12/14).
Part of the content below is based on publications from Jérôme Petazzoni [1] and Daniel J Walsh [2]. This document aims at adding on to their recommendations and how they can specifically be implemented within Docker.
Note: Most of suggested command line options can be stored and used in a similar manner inside a Dockerfile for automated image building.
Item | Deployment |
---|---|
Docker Images | Docker 1.3 now supports cryptographic signatures [3] to ascertain the origin and integrity of official repository images. This feature is however still a work in progress as Docker will issue a warning but not prevent the image from actually running. Furthermore, it does not apply to non-official images.
|
Network Namespaces [4] | By default, the Docker REST API used to control containers exposed via the system Docker daemon is only accessible locally via a Unix domain socket.
|
Logging & Auditing | Collect and archive security logs relating to Docker for auditing and monitoring purposes.
|
SELinux or AppArmor | Linux kernel security modules such as Security-Enhanced Linux (SELinux) and AppArmor can be configured, via access control security policies, to implement mandatory access controls (MAC) confining processes to a limited set of system resources or privileges.
|
Daemon Privileges | Do not use the |
cgroups [10] | In order to prevent Denial of Service (DoS) attacks via system resource exhaustion, a number of resource restrictions can be applied using specific command line arguments.
|
SUID/GUID binaries | SUID and GUID binaries can prove dangerous when vulnerable to attacks leading to arbitrary code execution (e.g. buffer overflows), as they will be running under the context of the process’s file owner or group.
|
Devices control group (/dev/*) | If required, mount devices using the built-in |
Services and Applications | To reduce the potential for lateral movement if a Docker container was to be compromised, consider isolating sensitive services (e.g. run SSH service on bastion host or in a VM).
|
Mount Points | This is handled automatically by Docker when using the native container library (i.e. libcontainer).
|
Linux Kernel | Ensure kernel is up-to-date using update utility provided by the system (e.g. apt-get, yum, etc). Out-dated kernels are more likely to be vulnerable to publicly disclosed vulnerabilities.
|
User Namespaces | Docker does not support user namespaces but is a feature currently under development [13]. UID mapping is currently supported by the LXC driver but not in the native libcontainer library.
docker run -lxc-conf="lxc.id_map = u 0 100000 65536" -lxc-conf="lxc.id_map = g 0 100000 65536" ...
The specified arguments in the above command will instruct Docker to map UIDs and GIDs 100000 through 65536 on the host to UIDs and GIDs 0 through 65536 to a specific user account, defined at system level on the host in a configuration similar to: [14] /etc/subgid:<username>:100000:65536 /etc/subuid:<username>:100000:65536
|
libseccomp (and seccomp-bpf extension) | The libseccomp library allows restricting the use of Linux kernel’s syscall procedures based on a white-list approach. Syscall procedures not vital to system operation should ideally be disabled to prevent abuse or misuse within a compromised container.
|
capabilities(7) |
Drop linux capabilities to a minimum whenever possible.
Docker default capabilities include: |
Multi-tenancy Environments | Due to the shared nature of Docker containers’ kernel, separation of duty in multi-tenancy environments cannot be achieved securely. It is recommended that containers be run on hosts that have no other purposes and are not used for sensitive operations. Consider moving all services into containers controlled by Docker.
|
Full Virtualisation | Use a full virtualisation solution to contain Docker, such as KVM. This will prevent escalation from the container to the host if a kernel vulnerability is exploited inside the Docker image.
|
Security Audits | Perform regular security audits of your host system and containers to identify mis-configuration or vulnerabilities that could expose your system to compromise. |
[1] Docker, Linux Containers (LXC), and security (August, 2014). Jérôme Petazzoni. [presentation slides] Referenceshttp://www.slideshare.net/jpetazzo/docker-linux-containers-lxc-and-security
[2] Docker and SELinux (July, 2014). Daniel Walsh [video] https://www.youtube.com/watch?v=zWGFqMuEHdw
[3] Docker 1.3: Signed Images, Process Injection, Security Options, Mac shared directories (October, 2014). Scott Johnston http://blog.docker.com/2014/10/docker-1-3-signed-images-process-injection-security-options-mac-shared-directories/
[4] Exploring LXC Networking (November, 2013). Milos Gajdos. http://containerops.org/2013/11/19/lxc-networking/
PaaS under the hood, episode 1: kernel namespaces (November, 2012). Jérôme Petazzoni. http://blog.dotcloud.com/under-the-hood-linux-kernels-on-dotcloud-part
Exploring networking in Linux containers (January, 2014). Milos Gajdos. [presentation slides] https://speakerdeck.com/gyre007/exploring-networking-in-linux-containers
[5] How to grant rights to users to use Docker in Fedora (October 2014). Daniel Walsh http://opensource.com/business/14/10/docker-user-rights-fedora
[6] Running Docker with https. [Docker documentation] https://docs.docker.com/articles/https/
[7] security suggestions when running malicious code, Google Groups (August, 2013). Jérôme Petazzoni https://groups.google.com/forum/#!msg/docker-user/uuiQ3Nk3uSY/SuFpdO6BPmYJ
[8] Monitoring Images and Containers. [Red Hat documentation] https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Resource_Management_and_Linux_Containers_Guide/sec-Monitoring_Images.html
[9] Docker 1.3: Signed Images, Process Injection, Security Options, Mac shared directories (October, 2014). Scott Johnston http://blog.docker.com/2014/10/docker-1-3-signed-images-process-injection-security-options-mac-shared-directories/
[10] Resource management in Docker (September, 2014). Marek Goldmann. https://goldmann.pl/blog/2014/09/11/resource-management-in-docker/
Gathering LXC and Docker Containers Metrics (October, 2013). Jérôme Petazzoni. http://blog.docker.com/2013/10/gathering-lxc-docker-containers-metrics/
[11] Removing SUID and SGID flags off binaries (August, 2008). Eric Thern. http://www.thern.org/projects/linux-lecture/intro-to-linux/node10.html
[12] Announcing Docker 1.2.0 (August, 2014). Victor Vieux. http://blog.docker.com/2014/08/announcing-docker-1-2-0/
[13] Having non-root privileges on the host and root inside the container #2918 (November, 2013). [GitHub issue] moby/moby#2918
Support for user namespaces #4572 (March 2014). [GitHub issue] moby/moby#4572
Proposal: Support for user namespaces #7906 (September, 2014). [GitHub issue] moby/moby#7906
Issue 8447: syscall, os/exec: Support for User Namespaces (July, 2014) [Google Code issue] https://code.google.com/p/go/issues/detail?id=8447
[14] Introduction to unprivileged containers (January, 2014). Stéphane Graber https://www.stgraber.org/2014/01/17/lxc-1-0-unprivileged-containers/
[15] Docker 0.9: Introducing Execution Drivers and libcontainer (March, 2014). Solomon Hykes http://blog.docker.com/2014/03/docker-0-9-introducing-execution-drivers-and-libcontainer/
[16] A simple helper script to help people build seccomp profiles for Docker/LXC (November 2013). Martijn van Oosterhout. https://github.com/docker/docker/blob/487a417d9fd074d0e78876072c7d1ebfd398ea7a/contrib/mkseccomp.pl
https://github.com/docker/docker/blob/487a417d9fd074d0e78876072c7d1ebfd398ea7a/contrib/mkseccomp.sample
[17] Announcing Docker 1.2.0 (August, 2014). Victor Vieux. http://blog.docker.com/2014/08/announcing-docker-1-2-0/
[18] Docker Container Breakout Proof-of-Concept Exploit (June, 2014). James Turnbull http://blog.docker.com/2014/06/docker-container-breakout-proof-of-concept-exploit/
[19] docker2docker GitHub repository. Jérôme Petazzoni. https://github.com/jpetazzo/docker2docker
License
Docker Secure Deployment Guidelines by Gotham Digital Science is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.