Docker audit fixes

Runtime & Resources: fixing all 6 checks

The runtime audit reads each running container's HostConfig: the seccomp and AppArmor confinement that contains an escape, and the memory, CPU and PID caps that stop a container taking down the host.

All six checks print the same line, "No running containers to evaluate", whether the daemon was unreachable or the host simply had nothing running, so six skips do not tell you which of the two happened. The Docker Inventory check in the Daemon and Socket audit is what separates them.

6
checks in this audit
0
rated high severity
6
need root or sudo
~10s
automated run time

Transcribed from the docker-security-runtime-resources audit script.

Every check

Find your finding

Listed in the order the audit runs them. Take the check name from the third field of the result line and open its page.

  • Seccomp Profile

    Soon

    Check whether any running container disables the default seccomp syscall filter

    MediumNeeds root3 results
  • Container AppArmor/SELinux

    Soon

    Check whether AppArmor or SELinux confines running containers and is enforcing on the host

    MediumNeeds root3 results
  • Memory Limits

    Soon

    Check whether running containers have a memory limit set

    MediumNeeds root3 results
  • CPU Limits

    Soon

    Check whether running containers have a CPU limit set

    LowNeeds root3 results
  • PID Limits

    Soon

    Check whether running containers cap process count to contain fork bombs

    LowNeeds root3 results
  • Container Restart Policy

    Soon

    Check whether any container uses an unbounded always restart policy

    LowNeeds root3 results
Shared script behaviour

How the Runtime & Resources audit reads your server

Every check in this audit runs after the same preamble, and several of its results only make sense once you know what that preamble could and could not see.

Running containers only.

Docker detection: DOCK=direct if docker ps works as the audit user (docker group), DOCK=root if it works through sudo; the dk helper wraps docker accordingly. IDS is the list of running container IDs and NRUN their count; dk inspect --format is used with Go templates. Podman is recognised but not audited.

Why checks skip

A SKIP is never a pass

A skipped check verified nothing at all. The most common cause is privilege: 6 of the 6 checks in this audit need root for a complete result. Before every run, each script works out which of four privilege modes it is in.

The four privilege modes an audit script can run in, and what each one means for checks that need root
ModeHow it is reachedWhat it means for your results
rootThe audit runs as UID 0.Every privileged branch runs directly. No check skips for lack of permission.
nopasssudo -n true succeeds, so the account has passwordless sudo.Privileged commands run through sudo -n.
passA sudo password was supplied in the CtrlOps audit settings and accepted.Privileged commands run through sudo -S.
noneNone of the above worked.CAN_ROOT=0. Every privileged branch returns SKIP with a "Need root" message rather than guessing.

If many checks skip with a “need root” message, run the audit as root, grant the audit account sudo (with or without NOPASSWD), or supply the sudo password in the CtrlOps audit settings. For Docker checks, membership of the docker group is an alternative to sudo: run usermod -aG docker <user> and log in again.

FAQ

Runtime & Resources questions

The script tests both conditions in a single branch: an empty DOCK, meaning no daemon access as the audit user, through sudo or via the docker group, and a running-container count of zero produce the identical message. Run docker ps as the audit account to tell them apart, or read the Docker Inventory line in the Daemon and Socket audit, which reports "Docker not installed", a daemon that is not reachable, or an engine version with running and total container counts.
On a host where getenforce returns Enforcing, the check treats SELinux as covering the containers and passes without inspecting any of them; it only walks the per-container profiles when AppArmor is present on the host. Many Docker CE installs on RHEL family systems never set selinux-enabled, so containers are not in fact labelled. Look for apparmor or selinux under Security Options in docker info before trusting that PASS.
Only if you accept the CIS position behind it. The check flags always because an unbounded restart loop burns resources, but Docker's own guidance is that long-running services should survive a reboot, and on-failure:5 leaves a service down when a slow dependency makes it crash five times at boot. Note also that unless-stopped behaves the same as always except after a manual stop and is not flagged, so switching to it silences the warning without changing the behaviour CIS is concerned about. Decide deliberately and write the decision down.
Audit your fleet

Run all 6 Runtime & Resources checks, in one click

CtrlOps runs this audit over your existing SSH connection - no agents, no scripts to manage. $7/user/month after a 1 month free trial - no credit card required.

Start instantly· No credit card· No sneaky autorenewals