Docker Security 101: Hardening guide

Emmanuel Eliason-Armstrong
7 min readAug 27, 2020

--

In 2013, Docker introduced what would become the industry standard for containers. Containers are a standardized unit of software that allows developers to isolate their app from its environment, solving the “it works on my machine” headache. For millions of developers today, Docker is the de facto standard to build and share containerized apps — from desktop, to the cloud. But many of those embracing containers are unaware that misconfiguration of the container hosts can lead to an attacker having domain administrator privileges and potentially harming the entire IT network infrastructure.

Hardening your container hosts’ configurations is essential and it involves applying certain configuration steps above and beyond the default settings.

The Center for Internet Security benchmarks provides prescriptive guidance for establishing a secure configuration posture for Docker Engine — Community version 18.09 and Docker Enterprise 2.1.This guide was tested against Docker Engine — Community 18.09 on RHEL 7 and Debian 8. It was also tested against Docker Enterprise 2.1, which includes Docker Engine — Enterprise 18.09, Universal Control Plane (UCP) 3.1.0 and Docker Trusted Registry (DTR) 2.6.0, all on RHEL 7 and Debian 8.
To obtain the latest version of this guide, please visit http://benchmarks.cisecurity.org.

Table 1.1 below provides a high-level list of the CIS Docker v1.2 benchmarks.
For more detail on how to implement those security recommendations, download the CIS Docker v1.2 benchmark file from the above website.

Table 1.1: High Level Center for Internet Security Docker Benchmark v1.2.0

  1. Host Configuration

1.1 General Configuration
1.1.1 Ensure the container host has been Hardened
1.1.2 Ensure that the version of Docker is up to date

1.2 Linux Hosts Specific Configuration
1.2.1 Ensure a separate partition for containers has been created
1.2.2 Ensure only trusted users are allowed to control Docker daemon
1.2.3 Ensure auditing is configured for the Docker
1.2.4 Ensure auditing is configured for Docker files and directories /var/lib/docker
1.2.5 Ensure auditing is configured for Docker files and directories /etc/docker
1.2.6 Ensure auditing is configured for Docker files and directories docker.service
1.2.7 Ensure auditing is configured for Docker files and directories docker.socket
1.2.8 Ensure auditing is configured for Docker files and directories /etc/default/docker
1.2.9 Ensure auditing is configured for Docker files and directories /etc/sysconfig/docker
1.2.10 Ensure auditing is configured for Docker files and directories /etc/docker/daemon.json
1.2.11 Ensure auditing is configured for Docker files and directories /usr/bin/containerd
1.2.12 Ensure auditing is configured for Docker files and directories /usr/sbin/runc

2. Docker daemon configuration

2.1 Ensure network traffic is restricted between containers on the default bridge
2.2 Ensure the logging level is set to ‘info’
2.3 Ensure Docker is allowed to make changes to iptables
2.4 Ensure insecure registries are not used
2.5 Ensure aufs storage driver is not used
2.6 Ensure TLS authentication for Docker daemon is configured
2.7 Ensure the default ulimit is configured appropriately
2.8 Enable user namespace support
2.9 Ensure the default cgroup usage has been confirmed
2.10 Ensure base device size is not changed until needed
2.11 Ensure that authorization for Docker client commands is enabled
2.12 Ensure centralized and remote logging is configured
2.13 Ensure live restore is enabled
2.14 Ensure Userland Proxy is Disabled
2.15 Ensure that a daemon-wide custom seccomp profile is applied if
appropriate
2.16 Ensure that experimental features are not implemented in production
2.17 Ensure containers are restricted from acquiring new privileges

3. Docker daemon configuration files

3.1 Ensure that the docker.service file ownership is set to root:root
3.2 Ensure that docker.service file permissions are appropriately set
3.3 Ensure that docker.socket file ownership is set to root:root
3.4 Ensure that docker.socket file permissions are set to 644 or more restrictive
3.5 Ensure that the /etc/docker directory ownership is set to root:root
3.6 Ensure that /etc/docker directory permissions are set to 755 or more restrictively
3.7 Ensure that registry certificate file ownership is set to root:root
3.8 Ensure that registry certificate file permissions are set to 444 or more restrictively
3.9 Ensure that TLS CA certificate file ownership is set to root:root
3.10 Ensure that TLS CA certificate file permissions are set to 444 or more restrictively
3.11 Ensure that Docker server certificate file ownership is set to root:root
3.12 Ensure that the Docker server certificate file permissions are set to 444 or more restrictively
3.13 Ensure that the Docker server certificate key file ownership is set to root:root
3.14 Ensure that the Docker server certificate key file permissions are set to 400
3.15 Ensure that the Docker socket file ownership is set to root:docker
3.16 Ensure that the Docker socket file permissions are set to 660 or more restrictively
3.17 Ensure that the daemon.json file ownership is set to root:root
3.18 Ensure that daemon.json file permissions are set to 644 or more restrictive
3.19 Ensure that the /etc/default/docker file ownership is set to root:root
3.20 Ensure that the /etc/sysconfig/docker file ownership is set to root:root
3.21 Ensure that the /etc/sysconfig/docker file permissions are set to 644 or more restrictively
3.22 Ensure that the /etc/default/docker file permissions are set to 644 or more restrictively

4. Container Images and Build File Configuration.

4.1 Ensure that a user for the container has been created
4.2 Ensure that containers use only trusted base images
4.3 Ensure that unnecessary packages are not installed in the container
4.4 Ensure images are scanned and rebuilt to include security
4.5 Ensure Content trust for Docker is Enabled
4.6 Ensure that HEALTHCHECK instructions have been added to container images
4.7 Ensure update instructions are not used alone in the Dockerfile
4.8 Ensure setuid and setgid permissions are removed
4.9 Ensure that COPY is used instead of ADD in Dockerfiles
4.10 Ensure secrets are not stored in Dockerfiles
4.11 Ensure only verified packages are installed

5. Container Runtime Configuration.

5.1 Ensure that, if applicable, an AppArmor Profile is enabled
5.2 Ensure that, if applicable, SELinux security options are set
5.3 Ensure that Linux kernel capabilities are restricted within containers
5.4 Ensure that privileged containers are not used
5.5 Ensure sensitive host system directories are not mounted on containers
5.6 Ensure sshd is not run within containers
5.7 Ensure privileged ports are not mapped within containers
5.8 Ensure that only needed ports are open on the container
5.9 Ensure that the host’s network namespace is not shared
5.10 Ensure that the memory usage for containers is limited
5.11 Ensure that CPU priority is set appropriately on containers
5.12 Ensure that the container’s root filesystem is mounted as read only
5.13 Ensure that incoming container traffic is bound to a specific host interface
5.14 Ensure that the ‘on-failure’ container restart policy is set to ‘5’
5.15 Ensure that the host’s process namespace is not shared
5.16 Ensure that the host’s IPC namespace is not shared
5.17 Ensure that host devices are not directly exposed to containers
5.18 Ensure that the default ulimit is overwritten at runtime if needed
5.19 Ensure mount propagation mode is not set to shared
5.20 Ensure that the host’s UTS namespace is not shared
5.21 Ensure the default seccomp profile is not Disabled
5.22 Ensure that docker exec commands are not used with the privileged option
5.23 Ensure that docker exec commands are not used with the user=root option
5.24 Ensure that cgroup usage is confirmed
5.25 Ensure that the container is restricted from acquiring additional privileges
5.26 Ensure that container health is checked at runtime
5.27 Ensure that Docker commands always make use of the latest version of their image
5.28 Ensure that the PIDs cgroup limit is used
5.29 Ensure that Docker’s default bridge “docker0” is not used
5.30 Ensure that the host’s user namespaces are not shared
5.31 Ensure that the Docker socket is not mounted inside any containers

6. Docker Security Operations.

6.1 Ensure that image sprawl is avoided
6.2 Ensure that container sprawl is avoided

7. Docker Swarm Configuration.

7.1 Ensure swarm mode is not Enabled, if not needed
7.2 Ensure that the minimum number of manager nodes have been created in a swarm
7.3 Ensure that swarm services are bound to a specific host interface
7.4 Ensure that all Docker swarm overlay networks are encrypted
7.5 Ensure that Docker’s secret management commands are used for managing secrets in a swarm cluster
7.6 Ensure that swarm manager is run in auto-lock
7.7 Ensure that the swarm manager auto-lock key is rotated periodically
7.8 Ensure that node certificates are rotated as appropriate
7.9 Ensure that CA certificates are rotated as appropriate
7.10 Ensure that management plane traffic is separated from data plane traffic

8. Docker Enterprise Configuration

8.1 Universal Control Plane Configuration
8.1.1 Configure the LDAP authentication
8.1.2 Use external certificates
8.1.3 Enforce the use of client certificate bundles for unprivileged users
8.1.4 Configure applicable cluster role-based access control policies
8.1.5 Enable signed image enforcement
8.1.6 Set the Per-User Session Limit to a value of ‘3’ or lower
8.1.7 Set the “Lifetime Minutes” and “Renewal Threshold Minutes” values to ‘15’ or lower and ‘0’ respectively
8.2 Docker Trusted Registry Configuration
8.2.1 Enable image vulnerability

When hardening your container host, review each security component, and determine its appropriateness to your existing deployment. With any hardening strategy, you need to be incremental in your approach, applying and testing each new security control in a development or test environment before deploying it into a production environment.

--

--

Emmanuel Eliason-Armstrong
Emmanuel Eliason-Armstrong

Written by Emmanuel Eliason-Armstrong

Cloud DevOps Engineer | AWS Certified Solutions Architect | AWS Certified Developer

Responses (1)