Securing your containerized applications isn’t just about writing secure code; it’s also about ensuring the underlying Docker host and its runtime environment are configured securely. In this chapter, we’ll shift our focus to proactive security by auditing our Docker setup using docker-bench-security. This tool helps validate your Docker installation against the best practices outlined in the CIS Docker Benchmark.
By the end of this chapter, you’ll be able to run a comprehensive security audit on your Docker environment, understand its findings, and begin to implement the necessary remediations. This is a critical step in hardening your production deployments and maintaining a strong security posture.
Project Overview: Hardening the Docker Environment
Our goal in this chapter is to proactively identify and address potential security weaknesses in our Docker environment. We will use an industry-recognized tool to scan our Docker host and running containers, comparing their configurations against established security benchmarks. This isn’t about finding bugs in our application code, but rather misconfigurations in the platform that hosts it.
The outcome of this chapter is a detailed security report for your Docker setup, highlighting areas for improvement. You’ll gain practical experience in interpreting these reports and understanding the implications of various security recommendations, ultimately making your multi-service application stack more resilient to attacks.
Tech Stack: docker-bench-security and CIS Docker Benchmark
The core of our security auditing process relies on two key components:
docker-bench-security: An open-source script developed by Docker that automates security checks. It’s designed to be run on a Docker host and inspects the daemon, host configuration, and running containers. It outputs results categorized asPASS,INFO, orWARN.- CIS Docker Benchmark: A comprehensive set of guidelines from the Center for Internet Security (CIS) that provides prescriptive recommendations for securely configuring Docker.
docker-bench-securityuses these guidelines as its reference.
This combination allows us to leverage expert-defined best practices without manually checking hundreds of configuration items.
Milestones: Auditing Workflow
To effectively audit our Docker environment, we’ll follow a structured workflow:
- Prepare the Environment: Ensure Docker is running and we have access to the necessary tools.
- Run the Audit Tool: Execute
docker-bench-securityas a privileged container to perform comprehensive checks. - Analyze the Report: Interpret the
PASS,INFO, andWARNmessages generated by the tool. - Prioritize Remediations: Identify critical security findings and understand their impact.
- Plan for Continuous Auditing: Discuss how to integrate these checks into a production workflow.
Architecture: Security Audit Process Flow
The auditing process involves docker-bench-security interacting with various components of your Docker host and daemon to gather configuration information.
The docker-bench-security container requires specific host privileges and volume mounts to access the necessary files and sockets for a thorough audit. This allows it to inspect the Docker daemon’s configuration, /etc files for host-level settings, and /var/lib for Docker’s internal data.
Step-by-Step Implementation: Running docker-bench-security
docker-bench-security is a shell script, and the recommended way to run it is as a privileged container. This ensures it has the necessary access to inspect your Docker daemon and host configuration while being isolated from your host system.
Prerequisites:
- A Docker Engine installation (we’re using the setup from previous chapters).
- Internet access to pull the
aquasec/docker-benchimage. - Basic command-line proficiency.
Method 1: Running as a Container (Recommended)
Running docker-bench-security as a container is generally preferred as it isolates the tool’s dependencies and provides a consistent execution environment.
First, ensure your Docker daemon is running and you have no critical workloads that would be impacted by a momentary resource spike from the audit.
Open your terminal and execute the following command:
docker run --net host --pid host --userns host --cap-add audit_control \
-e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
-v /var/lib:/var/lib \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /etc:/etc --label docker_bench_security \
--read-only --tmpfs /tmp \
aquasec/docker-bench:latestLet’s break down these flags:
docker run: Executes a Docker container.--net host: Allows the container to share the host’s network namespace, necessary for some network-related checks.--pid host: Allows the container to share the host’s PID namespace, enabling checks on host processes.--userns host: Necessary for user namespace related checks, especially important for host user/group mappings.--cap-add audit_control: Grants the container theaudit_controlcapability, allowing it to interact with the kernel’s audit subsystem to perform deeper security checks.-e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST: Passes theDOCKER_CONTENT_TRUSTenvironment variable from your host to the container. If you have Docker Content Trust enabled, this ensures the check is performed correctly.-v /var/lib:/var/lib: Mounts the/var/libdirectory from the host. This contains Docker’s data directory, including image layers, volumes, and container metadata.-v /var/run/docker.sock:/var/run/docker.sock: Mounts the Docker daemon’s Unix socket. This is crucial for the tool to communicate with the Docker daemon and perform checks on running containers and daemon configuration.-v /etc:/etc: Mounts the/etcdirectory, allowing the tool to check host configuration files relevant to Docker and general system security.--label docker_bench_security: Adds a label to the container for easy identification if you need to inspect it later.--read-only: Makes the container’s root filesystem read-only, enhancing the security of the audit tool itself.--tmpfs /tmp: Mounts/tmpas atmpfs(in-memory filesystem), preventing any persistent writes to disk by the audit tool.aquasec/docker-bench:latest: Specifies the Docker image to use. Theaquasecorganization maintains a regularly updated image. As of 2026-05-22,latestrefers to the most recent stable release, ensuring you use an up-to-date benchmark.
Method 2: Running from a Cloned Repository (Alternative)
If you prefer to run the script directly, you can clone the repository. This might be useful for development, or if you need to inspect or modify the script itself.
Clone the repository:
git clone https://github.com/docker/docker-bench-security.git cd docker-bench-securityRun the script:
sudo sh docker-bench-security.shYou need
sudobecause the script performs checks that require root privileges to access system files and Docker daemon information.Note: When running directly, ensure your environment has all necessary dependencies (e.g.,
auditctlfor some audit checks). The containerized approach (Method 1) handles these dependencies for you by including them in theaquasec/docker-benchimage.
Testing & Verification: Analyzing the Audit Report
Once the command executes, you’ll see a stream of output in your terminal. This output is the audit report, categorizing findings as INFO, WARN, or PASS.
Let’s look at an example snippet of what you might see:
[INFO] 1 - Host Configuration
[INFO] 1.1 - Linux Host Configuration
[INFO] 1.1.1 - Ensure a separate partition for containers has been created (Not Scored)
[INFO] * Recommendation: Create a separate partition for /var/lib/docker and /var/log/docker.
[INFO] 1.1.2 - Ensure the host's kernel is updated (Not Scored)
[INFO] * Recommendation: Ensure the host's kernel is updated to the latest version.
...
[WARN] 2 - Docker Daemon Configuration
[WARN] 2.1 - Docker daemon configuration
[WARN] 2.1.1 - Ensure the docker.service file ownership is set to root:root (Scored)
[WARN] * Expected value: root:root
[WARN] * Actual value: user:user (example if misconfigured)
[INFO] * Remediation: systemctl daemon-reload && systemctl restart docker
...
[PASS] 4 - Container Images, Build, and Registry
[PASS] 4.1 - Container Image and Build File
[PASS] 4.1.1 - Ensure a `HEALTHCHECK` instruction has been added to the container image (Scored)
...
[INFO] Overall results:
[INFO] 18 checks PASS
[INFO] 5 checks WARN
[INFO] 2 checks INFOInterpreting the Output:
[PASS]: The check passed, meaning your configuration adheres to the benchmark recommendation.[INFO]: These are informational messages, often about checks that are “Not Scored” in the benchmark, or recommendations that are good practices but not critical failures. You should still review them as they often point to general hardening opportunities.[WARN]: These are critical findings. They indicate a deviation from best practices that could pose a significant security risk. EachWARNtypically includes aRemediationsuggestion. These are your top priority for action.
Verification Steps:
- Review the Entire Report: Carefully scroll through the entire output. Don’t just look at the summary.
- Focus on
[WARN]Messages: Identify each specific warning, noting the benchmark item number (e.g.,2.1.1) and the exact recommendation. - Understand the Remediation: For each
[WARN], read the suggestedRemediationand understand why it’s recommended. For example, a warning aboutdocker.servicefile ownership (2.1.1) indicates that non-root users might be able to tamper with Docker’s core configuration. - Prioritize Remediations: Not all
WARNmessages have the same severity in every context. Use your judgment based on your application’s risk profile and compliance requirements. An exposed Docker socket (2.3) is generally a higher priority than minor file permission issues on less critical files. - Consider
Not ScoredItems: Even if they don’t generateWARNs,INFOmessages forNot Scoreditems (like1.1.1 Ensure a separate partition for containers) are important best practices to consider for production environments.
By systematically reviewing these findings, you gain a clear picture of your Docker environment’s current security posture and a concrete action plan for improvement.
Production Considerations: Continuous Security Auditing
Running docker-bench-security once is a good start, but continuous security is paramount in production. Security posture can degrade over time due to configuration drift, new software installations, or emerging vulnerabilities.
- Automate Audits in CI/CD: Integrate
docker-bench-securityinto your CI/CD pipeline. This can be a nightly job or triggered before significant deployments. If the audit fails (e.g., introduces newWARNs above a threshold), it can block the deployment, enforcing a secure baseline. - Scheduled Scans on Production Hosts: Schedule
docker-bench-securityto run periodically on your production hosts (e.g., weekly or monthly) via a cron job or an orchestration tool. Send reports to a central logging or alerting system. This helps detect configuration drift or new vulnerabilities that emerge. - Baselining and Trend Analysis: Establish a “clean” audit report as your security baseline. Any new
WARNs or significant changes in subsequent scans indicate a deviation in your security posture that needs immediate investigation. Track these trends over time. - Alerting on Critical Findings: Configure alerts for critical
WARNfindings. For example, if a check related to Docker daemon permissions changes fromPASStoWARN, an alert should notify the security or operations team immediately via email, Slack, or PagerDuty. - Documentation and Risk Acceptance: Document your security posture, all remediations, and any accepted risks. If a
WARNcannot be fully remediated due to specific operational requirements (e.g., a necessary custom kernel module), document the justification, any compensating controls, and get appropriate sign-off. - Keep the Benchmark Current: The CIS Docker Benchmark is updated periodically to reflect new threats and best practices. Ensure you are using a recent version of
docker-bench-securityand review new recommendations as they emerge.
Common Issues & Solutions
Permission Denied Errors when Running Directly:
- Issue: When running the script directly (Method 2), you might encounter permission denied errors for certain checks, especially those accessing
/procor specific Docker daemon files. - Solution: Ensure you are running the script with
sudoprivileges. The containerized approach (Method 1) typically handles this by mounting the necessary host paths and capabilities, abstracting away the directsudorequirement for the script itself.
- Issue: When running the script directly (Method 2), you might encounter permission denied errors for certain checks, especially those accessing
Overwhelming Output / Difficulty in Parsing:
- Issue: The default output can be very verbose, making it hard to pinpoint critical issues quickly, especially in automated environments.
- Solution: The
docker-bench-securityscript supports an output file. You can redirect the output to a file for easier parsing and review:Then, you can usedocker run --net host ... aquasec/docker-bench:latest -o /opt/audit_report.txtdocker cpto copy the report out of the container:Alternatively, you can usedocker cp <container_id_or_name>:/opt/audit_report.txt .grepto filter forWARNmessages directly in the terminal:docker run --net host ... aquasec/docker-bench:latest | grep WARN
“False Positives” or Irrelevant Warnings:
- Issue: Some
WARNmessages might not be applicable to your specific setup or might be considered acceptable risks given your unique operational requirements. For example, if you intentionally expose the Docker API to a trusted internal network with strong firewall rules, aWARNabout the exposed socket might be deemed an acceptable risk. - Solution: Understand why a check is warning. Don’t blindly disable checks without understanding the security implications. If a warning is genuinely not applicable or the risk is accepted, document the justification, compensating controls, and get appropriate sign-off from security stakeholders. This process is known as risk acceptance.
- Issue: Some
Summary & Next Step
In this chapter, we’ve taken a crucial step towards securing our Docker deployments by learning how to audit the Docker host and containers using docker-bench-security. We explored how to run the tool, interpret its output based on the CIS Docker Benchmark, and discussed how to integrate these audits into a production workflow for continuous security.
By proactively addressing the WARN messages and considering the INFO recommendations, you significantly improve the security posture of your container environment. Remember, security is an ongoing process, not a one-time fix. Regular audits and prompt remediation are essential for maintaining a robust, production-ready system.
You now have a solid foundation for deploying a multi-service application with Docker Compose, complete with image optimization, persistent data, environment management, health checks, and a practical understanding of security auditing.
Next, we’ll focus on the final steps of preparing for deployment, including configuring resource limits and exploring more advanced deployment strategies to ensure our application runs efficiently and reliably at scale.
References
- Docker Documentation: https://docs.docker.com/
- CIS Docker Benchmark: httpswww.cisecurity.org/benchmark/docker
docker-bench-securityGitHub Repository: https://github.com/docker/docker-bench-security- Compose Specification Versioning: https://github.com/jamesatdocker/docker-docs/blob/main/compose/compose-file/compose-versioning.md
This page is AI-assisted and reviewed. It references official documentation and recognized resources where relevant.