Understanding Docker Bench for Security Scores

Docker Bench for Security provides a comprehensive audit of your Docker environment, comparing it against CIS benchmarks to highlight potential security risks. At the end of the scan, a score is generated, reflecting how well your setup adheres to best practices.

Understanding Docker Bench for Security Scores

Docker Bench for Security provides a comprehensive audit of your Docker environment, comparing it against CIS benchmarks to highlight potential security risks. At the end of the scan, a score is generated, reflecting how well your setup adheres to best practices. A low score (e.g., 4) indicates significant room for improvement, while a higher score shows better compliance and security. By addressing identified issues, such as permissions, network configurations, and container isolation, you can strengthen your Docker environment and safeguard your infrastructure. Ready to secure your setup? Let’s dive in!

I’ve run one on my Docker server, and here’s the result:

sudo sh docker-bench-security.sh
# --------------------------------------------------------------------------------------------
# Docker Bench for Security v1.6.0
#
# Docker, Inc. (c) 2015-2024
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Based on the CIS Docker Benchmark 1.6.0.
# --------------------------------------------------------------------------------------------

Initializing 2024-12-06T09:35:30+02:00


Section A - Check results

[INFO] 1 - Host Configuration
[INFO] 1.1 - Linux Hosts Specific Configuration
[DEPRECATION NOTICE]: API is accessible on http://127.0.0.1:2375 without encryption.
         Access to the remote API is equivalent to root access on the host. Refer
         to the 'Docker daemon attack surface' section in the documentation for
         more information: https://docs.docker.com/go/attack-surface/
In future versions this will be a hard failure preventing the daemon from starting! Learn more at: https://docs.docker.com/go/api-security/
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
[WARN] 1.1.1 - Ensure a separate partition for containers has been created (Automated)
[INFO] 1.1.2 - Ensure only trusted users are allowed to control Docker daemon (Automated)
[INFO]       * Users: dolpa
[WARN] 1.1.3 - Ensure auditing is configured for the Docker daemon (Automated)
[WARN] 1.1.4 - Ensure auditing is configured for Docker files and directories -/run/containerd (Automated)
[WARN] 1.1.5 - Ensure auditing is configured for Docker files and directories - /var/lib/docker (Automated)
[WARN] 1.1.6 - Ensure auditing is configured for Docker files and directories - /etc/docker (Automated)
[WARN] 1.1.7 - Ensure auditing is configured for Docker files and directories - docker.service (Automated)
[INFO] 1.1.8 - Ensure auditing is configured for Docker files and directories - containerd.sock (Automated)
[INFO]        * File not found
[WARN] 1.1.9 - Ensure auditing is configured for Docker files and directories - docker.socket (Automated)
[WARN] 1.1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker (Automated)
[WARN] 1.1.11 - Ensure auditing is configured for Dockerfiles and directories - /etc/docker/daemon.json (Automated)
[WARN] 1.1.12 - 1.1.12 Ensure auditing is configured for Dockerfiles and directories - /etc/containerd/config.toml (Automated)
[INFO] 1.1.13 - Ensure auditing is configured for Docker files and directories - /etc/sysconfig/docker (Automated)
[INFO]        * File not found
[WARN] 1.1.14 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd (Automated)
[WARN] 1.1.15 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim (Automated)
[WARN] 1.1.16 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim-runc-v1 (Automated)
[WARN] 1.1.17 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim-runc-v2 (Automated)
[WARN] 1.1.18 - Ensure auditing is configured for Docker files and directories - /usr/bin/runc (Automated)
[INFO] 1.2 - General Configuration
[NOTE] 1.2.1 - Ensure the container host has been Hardened (Manual)
[PASS] 1.2.2 - Ensure that the version of Docker is up to date (Manual)
[INFO]        * Using 27.3.1 which is current
[INFO]        * Check with your operating system vendor for support and security maintenance for Docker

[INFO] 2 - Docker daemon configuration
[NOTE] 2.1 - Run the Docker daemon as a non-root user, if possible (Manual)
docker-bench-security.sh: 37: [[: not found
[WARN] 2.2 - Ensure network traffic is restricted between containers on the default bridge (Scored)
[WARN] 2.3 - Ensure the logging level is set to 'info' (Scored)
docker-bench-security.sh: 96: [[: not found
[PASS] 2.4 - Ensure Docker is allowed to make changes to iptables (Scored)
docker-bench-security.sh: 118: [[: not found
[PASS] 2.5 - Ensure insecure registries are not used (Scored)
[PASS] 2.6 - Ensure aufs storage driver is not used (Scored)
jq: error: syntax error, unexpected IDENT (Unix shell quoting issues?) at <top-level>, line 1:
.[""tlsverify":"]
jq: 1 compile error
jq: error: syntax error, unexpected IDENT (Unix shell quoting issues?) at <top-level>, line 1:
.[""tls":"]
jq: 1 compile error
[WARN] 2.7 - Ensure TLS authentication for Docker daemon is configured (Scored)
[WARN]      * Docker daemon currently listening on TCP without TLS
docker-bench-security.sh: 185: [[: not found
[INFO] 2.8 - Ensure the default ulimit is configured appropriately (Manual)
[INFO]      * Default ulimit doesn't appear to be set
docker-bench-security.sh: 208: [[: not found
[WARN] 2.9 - Enable user namespace support (Scored)
[PASS] 2.10 - Ensure the default cgroup usage has been confirmed (Scored)
[PASS] 2.11 - Ensure base device size is not changed until needed (Scored)
docker-bench-security.sh: 276: [[: not found
[WARN] 2.12 - Ensure that authorization for Docker client commands is enabled (Scored)
[WARN] 2.13 - Ensure centralized and remote logging is configured (Scored)
[WARN] 2.14 - Ensure containers are restricted from acquiring new privileges (Scored)
[WARN] 2.15 - Ensure live restore is enabled (Scored)
[WARN] 2.16 - Ensure Userland Proxy is Disabled (Scored)
[INFO] 2.17 - Ensure that a daemon-wide custom seccomp profile is applied if appropriate (Manual)
[INFO] Ensure that experimental features are not implemented in production (Scored) (Deprecated)

[INFO] 3 - Docker daemon configuration files
[PASS] 3.1 - Ensure that the docker.service file ownership is set to root:root (Automated)
[PASS] 3.2 - Ensure that docker.service file permissions are appropriately set (Automated)
[PASS] 3.3 - Ensure that docker.socket file ownership is set to root:root (Automated)
[PASS] 3.4 - Ensure that docker.socket file permissions are set to 644 or more restrictive (Automated)
[PASS] 3.5 - Ensure that the /etc/docker directory ownership is set to root:root (Automated)
[PASS] 3.6 - Ensure that /etc/docker directory permissions are set to 755 or more restrictively (Automated)
[INFO] 3.7 - Ensure that registry certificate file ownership is set to root:root (Automated)
[INFO]      * Directory not found
[INFO] 3.8 - Ensure that registry certificate file permissions are set to 444 or more restrictively (Automated)
[INFO]      * Directory not found
[INFO] 3.9 - Ensure that TLS CA certificate file ownership is set to root:root (Automated)
[INFO]      * No TLS CA certificate found
[INFO] 3.10 - Ensure that TLS CA certificate file permissions are set to 444 or more restrictively (Automated)
[INFO]       * No TLS CA certificate found
[INFO] 3.11 - Ensure that Docker server certificate file ownership is set to root:root (Automated)
[INFO]       * No TLS Server certificate found
[INFO] 3.12 - Ensure that the Docker server certificate file permissions are set to 444 or more restrictively (Automated)
[INFO]       * No TLS Server certificate found
[INFO] 3.13 - Ensure that the Docker server certificate key file ownership is set to root:root (Automated)
[INFO]       * No TLS Key found
[INFO] 3.14 - Ensure that the Docker server certificate key file permissions are set to 400 (Automated)
[INFO]       * No TLS Key found
[PASS] 3.15 - Ensure that the Docker socket file ownership is set to root:docker (Automated)
[PASS] 3.16 - Ensure that the Docker socket file permissions are set to 660 or more restrictively (Automated)
[PASS] 3.17 - Ensure that the daemon.json file ownership is set to root:root (Automated)
[PASS] 3.18 - Ensure that daemon.json file permissions are set to 644 or more restrictive (Automated)
[PASS] 3.19 - Ensure that the /etc/default/docker file ownership is set to root:root (Automated)
[PASS] 3.20 - Ensure that the /etc/default/docker file permissions are set to 644 or more restrictively (Automated)
[INFO] 3.21 - Ensure that the /etc/sysconfig/docker file permissions are set to 644 or more restrictively (Automated)
[INFO]       * File not found
[INFO] 3.22 - Ensure that the /etc/sysconfig/docker file ownership is set to root:root (Automated)
[INFO]       * File not found
[PASS] 3.23 - Ensure that the Containerd socket file ownership is set to root:root (Automated)
[PASS] 3.24 - Ensure that the Containerd socket file permissions are set to 660 or more restrictively (Automated)

[INFO] 4 - Container Images and Build File
[PASS] 4.1 - Ensure that a user for the container has been created (Automated)
[NOTE] 4.2 - Ensure that containers use only trusted base images (Manual)
[NOTE] 4.3 - Ensure that unnecessary packages are not installed in the container (Manual)
[NOTE] 4.4 - Ensure images are scanned and rebuilt to include security patches (Manual)
[WARN] 4.5 - Ensure Content trust for Docker is Enabled (Automated)
[WARN] 4.6 - Ensure that HEALTHCHECK instructions have been added to container images (Automated)
[WARN]      * No Healthcheck found: [ghost:latest]
[WARN]      * No Healthcheck found: [ghost:5-alpine]
[WARN]      * No Healthcheck found: [mysql:8.0]
[WARN]      * No Healthcheck found: [jenkins/jenkins:2.430-jdk21]
[WARN]      * No Healthcheck found: [hello-world:latest]
[WARN]      * No Healthcheck found: [jenkins:2.60.3-alpine]
[INFO] 4.7 - Ensure update instructions are not used alone in the Dockerfile (Manual)
[INFO]      * Update instruction found: [jenkins/jenkins:2.430-jdk21]
[NOTE] 4.8 - Ensure setuid and setgid permissions are removed (Manual)
[PASS] 4.9 - Ensure that COPY is used instead of ADD in Dockerfiles (Manual)
[NOTE] 4.10 - Ensure secrets are not stored in Dockerfiles (Manual)
[NOTE] 4.11 - Ensure only verified packages are installed (Manual)
[NOTE] 4.12 - Ensure all signed artifacts are validated (Manual)

[INFO] 5 - Container Runtime
[PASS] 5.1 - Ensure swarm mode is not Enabled, if not needed (Automated)
[PASS] 5.2 - Ensure that, if applicable, an AppArmor Profile is enabled (Automated)
[WARN] 5.3 - Ensure that, if applicable, SELinux security options are set (Automated)
[WARN]      * No SecurityOptions Found: jenkins_server_jenkins-server_1
[PASS] 5.4 - Ensure that Linux kernel capabilities are restricted within containers (Automated)
[PASS] 5.5 - Ensure that privileged containers are not used (Automated)
[PASS] 5.6 - Ensure sensitive host system directories are not mounted on containers (Automated)
[PASS] 5.7 - Ensure sshd is not run within containers (Automated)
[PASS] 5.8 - Ensure privileged ports are not mapped within containers (Automated)
[WARN] 5.9 - Ensure that only needed ports are open on the container (Manual)
[WARN]      * Port in use: 5000 in jenkins_server_jenkins-server_1
[WARN]      * Port in use: 8080 in jenkins_server_jenkins-server_1
[PASS] 5.10 - Ensure that the host's network namespace is not shared (Automated)
[WARN] 5.11 - Ensure that the memory usage for containers is limited (Automated)
[WARN]       * Container running without memory restrictions: jenkins_server_jenkins-server_1
[WARN] 5.12 - Ensure that CPU priority is set appropriately on containers (Automated)
[WARN]       * Container running without CPU restrictions: jenkins_server_jenkins-server_1
[WARN] 5.13 - Ensure that the container's root filesystem is mounted as read only (Automated)
[WARN]       * Container running with root FS mounted R/W: jenkins_server_jenkins-server_1
[WARN] 5.14 - Ensure that incoming container traffic is bound to a specific host interface (Automated)
[WARN]       * Port being bound to wildcard IP: 0.0.0.0 in jenkins_server_jenkins-server_1
[WARN]       * Port being bound to wildcard IP: 0.0.0.0 in jenkins_server_jenkins-server_1
[WARN] 5.15 - Ensure that the 'on-failure' container restart policy is set to '5' (Automated)
[WARN]       * MaximumRetryCount is not set to 5: jenkins_server_jenkins-server_1
[PASS] 5.16 - Ensure that the host's process namespace is not shared (Automated)
[PASS] 5.17 - Ensure that the host's IPC namespace is not shared (Automated)
[PASS] 5.18 - Ensure that host devices are not directly exposed to containers (Manual)
[INFO] 5.19 - Ensure that the default ulimit is overwritten at runtime if needed (Manual)
[INFO]       * Container no default ulimit override: jenkins_server_jenkins-server_1
[PASS] 5.20 - Ensure mount propagation mode is not set to shared (Automated)
[PASS] 5.21 - Ensure that the host's UTS namespace is not shared (Automated)
[PASS] 5.22 - Ensure the default seccomp profile is not Disabled (Automated)
[NOTE] 5.23 - Ensure that docker exec commands are not used with the privileged option (Automated)
[NOTE] 5.24 - Ensure that docker exec commands are not used with the user=root option (Manual)
[PASS] 5.25 - Ensure that cgroup usage is confirmed (Automated)
[WARN] 5.26 - Ensure that the container is restricted from acquiring additional privileges (Automated)
[WARN]       * Privileges not restricted: jenkins_server_jenkins-server_1
[WARN] 5.27 - Ensure that container health is checked at runtime (Automated)
[WARN]       * Health check not set: jenkins_server_jenkins-server_1
[INFO] 5.28 - Ensure that Docker commands always make use of the latest version of their image (Manual)
[WARN] 5.29 - Ensure that the PIDs cgroup limit is used (Automated)
[WARN]       * PIDs limit not set: jenkins_server_jenkins-server_1
[PASS] 5.30 - Ensure that Docker's default bridge 'docker0' is not used (Manual)
[PASS] 5.31 - Ensure that the host's user namespaces are not shared (Automated)
[PASS] 5.32 - Ensure that the Docker socket is not mounted inside any containers (Automated)

[INFO] 6 - Docker Security Operations
[INFO] 6.1 - Ensure that image sprawl is avoided (Manual)
[INFO]      * There are currently: 6 images
[INFO]      * Only 1 out of 6 are in use
[INFO] 6.2 - Ensure that container sprawl is avoided (Manual)
[INFO]      * There are currently a total of 1 containers, with 1 of them currently running

[INFO] 7 - Docker Swarm Configuration
[PASS] 7.1 - Ensure that the minimum number of manager nodes have been created in a swarm (Automated) (Swarm mode not enabled)
[PASS] 7.2 - Ensure that swarm services are bound to a specific host interface (Automated) (Swarm mode not enabled)
[PASS] 7.3 - Ensure that all Docker swarm overlay networks are encrypted (Automated)
[PASS] 7.4 - Ensure that Docker's secret management commands are used for managing secrets in a swarm cluster (Manual) (Swarm mode not enabled)
[PASS] 7.5 - Ensure that swarm manager is run in auto-lock mode (Automated) (Swarm mode not enabled)
[PASS] 7.6 - Ensure that the swarm manager auto-lock key is rotated periodically (Manual) (Swarm mode not enabled)
[PASS] 7.7 - Ensure that node certificates are rotated as appropriate (Manual) (Swarm mode not enabled)
[PASS] 7.8 - Ensure that CA certificates are rotated as appropriate (Manual) (Swarm mode not enabled)
[PASS] 7.9 - Ensure that management plane traffic is separated from data plane traffic (Manual) (Swarm mode not enabled)


Section C - Score

[INFO] Checks: 117
[INFO] Score: 4

The explanations for each check from your Docker Bench Security report to help you understand their implications:

Check results

1. Host Configuration

  • 1.1 - Linux Hosts Specific Configuration
    • [DEPRECATION NOTICE] API is accessible on http://127.0.0.1:2375 without encryption:
      The Docker API on this port is open without encryption, making it vulnerable to unauthorized access. Best practice is to secure the API with TLS or restrict access entirely.
    • bridge-nf-call-iptables/ip6tables disabled:
      This means network traffic between containers may not be properly filtered, leading to potential security risks. Enabling these options ensures container traffic can be controlled via iptables rules.
  • 1.1.1 - Separate partition for containers (Automated):
    A separate partition for container storage prevents containers from filling up the entire disk, ensuring host stability.
  • 1.1.2 - Only trusted users control Docker (Automated):
    The docker group grants root-like access to the system. Restrict membership to trusted users.
  • 1.1.3–1.1.18 - Auditing Docker daemon and files:
    Audit rules ensure actions on critical Docker files and processes are logged. This aids in tracing and identifying security incidents.

1.2 - General Configuration

  • 1.2.1 - Hardened container host (Manual):
    The host should follow best practices for hardening, such as secure kernel parameters and updated packages.
  • 1.2.2 - Docker version is up-to-date (Manual):
    Outdated versions may have unpatched vulnerabilities. You’re using version 27.3.1, which is current.

2. Docker daemon configuration

  • 2.1 - Run Docker daemon as non-root (Manual):
    Reducing privileges minimizes the impact of a potential breach. Use rootless mode for enhanced security.
  • 2.2 - Restrict container-to-container traffic on the default bridge:
    Containers on the default bridge can communicate unrestricted. Enabling isolation mitigates unauthorized communication.
  • 2.3 - Logging level set to 'info':
    Setting an appropriate logging level ensures sufficient details are available for troubleshooting without overwhelming logs.
  • 2.7 - TLS authentication for Docker daemon:
    Without TLS, communication with the Docker daemon is insecure and vulnerable to interception.
  • 2.9 - Enable user namespace support:
    User namespaces map container users to less-privileged host users, reducing risks if a container is compromised.
  • 2.12 - Authorization for Docker client commands:
    Configuring authorization plugins limits actions users can perform, reducing the risk of misuse.
  • 2.14 - Containers restricted from acquiring new privileges:
    Prevent containers from escalating their privileges beyond their initial capabilities.
  • 2.15 - Live restore enabled:
    Live restore ensures containers remain running during Docker daemon restarts, improving uptime and reliability.

3. Docker daemon configuration files

  • 3.1–3.24 - Permissions and ownership checks for Docker files:
    These ensure sensitive configuration files and sockets are owned by root and have restrictive permissions, preventing unauthorized access.

4. Container Images and Build Files

  • 4.1 - User creation for containers:
    Running containers as non-root reduces the impact of a potential breach.
  • 4.5 - Content trust for Docker enabled:
    Content trust ensures images are signed and verified, reducing the risk of using malicious or tampered images.
  • 4.6 - HEALTHCHECK instructions:
    Adding HEALTHCHECK instructions improves container monitoring by allowing the platform to detect unhealthy containers.

5. Container Runtime

  • 5.3 - SELinux security options:
    Configuring SELinux enforces mandatory access controls for containers, providing another layer of security.
  • 5.9 - Limit open ports:
    Only expose ports that are required for the container’s functionality. Unused open ports can be exploited.
  • 5.11 - Limit container memory usage:
    Limiting memory prevents containers from consuming all system resources, ensuring host stability.

Score

The score at the bottom of the Docker Bench for Security report represents an aggregate measure of how well your Docker environment adheres to the CIS Docker Benchmark guidelines. Each check contributes positively (if passed) or negatively (if failed) to the score, depending on the significance of the issue.

Interpreting the Score

  • Low Score (e.g., 4): Indicates that your current Docker configuration has several warnings or failed checks, which means it does not meet many of the best practices for securing Docker in a production environment.
  • High Score (e.g., 100): Suggests that your configuration aligns well with the security guidelines and has passed most or all checks.

Is a Score of 4 Good?

A score of 4 is not good. It signifies that many security issues or deviations from recommended practices were identified in your Docker setup. This could leave your system vulnerable to potential threats or misconfigurations.

Improving Your Score

To improve your score:

  1. Review Warnings and Failures: Go through each warning or failure in the report and understand its significance.
  2. Take Corrective Actions:
    • Address warnings about file permissions, user configurations, and network settings.
    • Harden your Docker host by setting up auditing, user namespace isolation, and TLS authentication.
    • Implement container-specific measures like setting HEALTHCHECK instructions, restricting resource usage, and limiting container privileges.
  3. Re-run the Script: After making adjustments, run the script again to validate improvements.

Read next

Troubleshooting Docker Networking Problems

Docker networking is a crucial aspect of containerization, enabling communication between containers and between containers and external services. However, like any complex system, Docker networking can encounter issues that may disrupt application functionality and deployment.

Diagnosing Container Startup Failures

Containerization has revolutionized the way we develop, deploy, and manage applications. Docker containers provide an isolated environment that allows applications to run consistently across various systems. However, container startup failures.

Debugging Docker: Troubleshooting Common Dockerfile Issues

Docker is a powerful tool for creating containers. However, like any technology, it can present challenges, particularly when building and optimizing Docker images using Dockerfiles. Issues with Dockerfiles can lead to build failures, runtime errors, or inefficient images.