CIS Docker Benchmark Reference (Curated for Todorovi Wines Lab)
This is a curated subset of the CIS Docker Benchmark v1.6 relevant to the lab environment. Not all 200+ items apply to a single-purpose lab container running a web application and monitoring stack. Your job is to determine which items matter for this specific system.
Host Configuration
1.1 -- Ensure a separate partition for containers
Description: Docker containers should run on a separate partition from the host OS.
Rationale: Prevents container storage exhaustion from affecting the host system.
Audit: mountpoint /var/lib/docker
Expected: A dedicated mount point for Docker storage.
Lab note: This is a shared development host. Item may not be applicable -- document why.
1.2 -- Ensure only trusted users are allowed to control Docker daemon
Description: Only trusted users should be in the docker group.
Rationale: Docker group membership grants root-equivalent access to containers.
Audit: getent group docker
Expected: Only the assessment user.
Docker Daemon Configuration
2.1 -- Ensure network traffic is restricted between containers
Description: By default, Docker allows unrestricted inter-container communication on the default bridge network.
Rationale: An attacker who compromises one container can freely access other containers on the same network.
Audit: docker network inspect bridge | grep "com.docker.network.bridge.enable_icc"
Expected: ICC disabled, or containers on separate networks.
2.8 -- Ensure the default ulimit is configured appropriately
Description: Default ulimits for containers should be set to prevent resource exhaustion.
Rationale: An unconstrained container can consume all file descriptors on the host.
Audit: docker info | grep -i ulimit
Expected: Sensible defaults configured.
2.14 -- Ensure containers are restricted from acquiring new privileges
Description: Containers should not be allowed to gain new privileges via setuid or setgid.
Rationale: Prevents privilege escalation within the container.
Audit: docker inspect --format='{{.HostConfig.SecurityOpt}}' <container>
Expected: no-new-privileges:true in security options.
Lab note: Consider whether this applies to single-purpose lab containers vs multi-tenant environments.
Container Images and Build File
4.1 -- Ensure a user for the container has been created
Description: Containers should not run as root.
Rationale: Running as root grants an attacker who compromises the application full control of the container. Non-root USER directly reduces post-compromise capability.
Audit: docker inspect --format='{{.Config.User}}' <container>
Expected: A non-root user specified.
4.5 -- Ensure Content trust for Docker is enabled
Description: Docker Content Trust ensures image integrity and publisher verification.
Rationale: Prevents running tampered or unauthorized images.
Audit: echo $DOCKER_CONTENT_TRUST
Expected: 1
4.6 -- Ensure HEALTHCHECK instructions have been added to container images
Description: Container images should include HEALTHCHECK directives.
Rationale: Enables Docker to determine if a container is still operational.
Audit: docker inspect --format='{{.Config.Healthcheck}}' <container>
Expected: A HEALTHCHECK defined.
4.9 -- Ensure that COPY is used instead of ADD in Dockerfiles
Description: Use COPY for file copying; ADD has additional features (tar extraction, URL fetching) that introduce risk. Rationale: ADD may download from untrusted URLs or extract unexpected archive contents. Audit: Review Dockerfiles for ADD instructions. Expected: COPY used unless tar extraction is specifically needed.
Container Runtime Configuration
5.1 -- Ensure that, if applicable, an AppArmor Profile is enabled
Description: AppArmor provides mandatory access control for container processes.
Rationale: Limits what a compromised container process can access on the host.
Audit: docker inspect --format='{{.AppArmorProfile}}' <container>
Expected: A profile assigned (or documented reason for absence).
5.10 -- Ensure that the host's network namespace is not shared
Description: Containers should not use --net=host.
Rationale: Sharing the host network bypasses Docker network isolation.
Audit: docker inspect --format='{{.HostConfig.NetworkMode}}' <container>
Expected: Not host.
5.12 -- Ensure that the container's root filesystem is mounted as read only
Description: The root filesystem should be read-only with specific writable volumes for application data.
Rationale: Prevents an attacker from modifying the container's filesystem.
Audit: docker inspect --format='{{.HostConfig.ReadonlyRootfs}}' <container>
Expected: true with named volumes for writable paths.
5.15 -- Ensure that the host's process namespace is not shared
Description: Containers should not share the host's PID namespace.
Rationale: Sharing PID namespace allows container processes to see and signal host processes.
Audit: docker inspect --format='{{.HostConfig.PidMode}}' <container>
Expected: Not host.
5.25 -- Ensure that the container is restricted from acquiring additional privileges
Description: Prevent privilege escalation within running containers.
Rationale: Same as 2.14 but applied at container runtime.
Audit: docker inspect --format='{{.HostConfig.SecurityOpt}}' <container>
Expected: no-new-privileges flag set.
5.28 -- Ensure that the PIDs cgroup limit is set
Description: Limit the number of processes a container can create.
Rationale: Prevents fork bomb attacks from within a container.
Audit: docker inspect --format='{{.HostConfig.PidsLimit}}' <container>
Expected: A reasonable limit (e.g., 100-500 depending on application).
How to use this reference
- Run each audit command against the lab containers.
- Determine the status: Pass, Fail, or Not Applicable.
- For each "Not Applicable" classification, document WHY -- this is where professional judgment lives. "This item is not applicable because..." requires understanding the item, the system, and the gap between them.
- For each "Fail" classification, check whether your remediation work (Unit 7) already addressed it.
- Map your exploitation findings to specific items -- "the container running as root (4.1 failure) is why my privilege escalation exploit worked."