How to secure Docker Containers: Tips and cheats

how to protect docker containers

While Docker containers are assumed to be secure, not following the best practice can put you in the way of harm. To keep you protected, we have prepared a cheat sheet on how to secure Docker containers in your organization.

Following are the best practices that you should be following to keep your containers secure.

1. Allow only trusted users to control the Daemon

You should allow only trusted users to control the Docker Daemon. Though Docker creates the docker group, however, any sudo user can also use Docker. So you need to check memberships of sudo and docker both the groups:

Use the following commands over the Docker host to get the members of the docker group,

getent group docker
getent group sudo

Use gpasswd -d user_name group_name command to remove users from the groups.

2. Use non-privileged users inside the container

You should not run any processes in a Docker container as root or even assuming that they are root. Instead, it’s a good idea to create a user in your Dockerfile with an available UID and GID. You can then run your process as this user.

Using non-privileged users will be the best way to prevent privilege escalation attacks.

3. Remove capabilities not explicitly required

Are you aware that you can drop Linux capabilities in Docker? 

You can use the docker run –cap-drop option to lock down the root in a container to have limited access within the container. However, almost no one ever tightens the security on a container or anywhere else.

By doing this, you will reduce the risks significantly.

What are Linux Capabilities?

Linux capabilities are unique attributes in the Linux kernel that grant processes and binary executables specific privileges reserved for root user (UID 0)

Linux Capabilities examples are things like the ability to send raw IP packets or bind to ports below 1024. So when you run containers, you can drop a whole lot of capabilities before running your containers. Further, it will not cause the majority of containerized applications any issues.

Dropping capabilities is a low-hanging fruit that can significantly improve container security.

Following is the default list of capabilities available to privileged processes in a Docker container:

chown, dac_override, fowner, fsetid, kill, setgid, setuid, setpcap, net_bind_service, net_raw, sys_chroot, mknod, audit_write, setfcap

Further, in the open containers/runtime-spec, they only retain audit_write, kill, and net_bind_service, and users can use ocitools to add additional capabilities.

So a better approach here will be to remove all capabilities and add capabilities that you need.

4. Use Linux security modules to harden a container

You can use external security systems like AppArmor, SELinux, etc., to protect Docker containers.

What is AppArmor?

AppArmor is a Linux kernel security module that allows an administrator to restrict a program’s capabilities with per-program profiles. For example, a profile can allow capabilities like network access, raw socket access, and the permission to read, write, or execute files on matching paths.

For more details on using it to harden a Docker container, please refer to this link from Docker.

What is SELinux?

SELinux (Security-Enhanced Linux) is an access control system built into the Linux kernel. SELinux is used to enforce the resource policies defining what level of access services, users, and programs can have on a system.            

For more details on how you can use SELinux for Docker container hardening, please refer to this link.

5. Configure Docker Engine only to run signed images

You can configure the Docker Content Trust signature verification feature directly in the dockerd configuration file. To enable this feature, you can configure trustpinning in daemon.json, whereby only repositories signed with a user-specified root key can be pulled and run.

Please refer to this link from Docker for more details.

6. Configure User Namespaces

If some Docker containers require the processes to be run as the root user within the container, you can actually remap the root user to a less privileged user on the Docker host. The mapped user will have no privileges on the host machine and will be assigned a range of UIDs from 0 to 65536.

Please be noted that this feature is not enabled by default.

Please refer to this link from Docker for more details

7. Keep Host and Docker updated, clean and lean

To prevent known container escapes vulnerabilities, which typically end in escalating to root/administrator privileges, patching Docker Engine and Docker Machine is crucial.

In addition, containers (unlike virtual machines) share the kernel with the host. Therefore kernel exploits executed inside the container will directly hit the host kernel. For example, kernel privilege escalation exploit (for example Dirty COW) executed inside a well-insulated container will result in root access in a host.

8. Do not Expose Docker Socket

Do not expose /var/run/docker.sock in any case. Docker.sock is the Unix socket that Docker listens to and the primary entry point for the Docker API. You should hide it from everything, including from anything inside the container.

If anyone have write access to this, it’s equivalent to having root access to the host.

9. Scan for any known vulnerabilities

Using vulnerable Docker images can put you at significant risk of a command injection attack. Regularly audit the containers to identify any known vulnerabilities. We recommend the following tools to scan images:

  • Clair (Free tool)
  • Trivy (Free tool)
  • Snyk (Commercial, open-source and free option available)
  • anchore (Commercial, open-source and free option available)
  • Aqua Security’s MicroScanner (commercial, free option available for rate-limited number of scans)
  • JFrog XRay (Commercial)
  • Qualys (Commercial)

You can use the following tools to detect misconfigurations in Docker:

  • inspec.io
  • Dev-sec.io

10. Configure Docker logging level to info

Docker daemon is configured with logging level “info” by default. Please set it to “info” in case it’s not but using the following command:

docker-compose –log-level info up

A base log level of ‘info’ and above will capture all logs except the debug logs. Therefore, you should not run the docker daemon at the ‘debug’ log level until and unless required. 

Some additional resources which we highly recommend are the OWASP cheat series and the Docker website. 

Do let us know what you think about this cheat sheet on how to secure Docker Containers. You can also mail us any suggestions or feedback.