npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
Overview
Docker Bench for Security is an open-source script that checks dozens of common best practices around deploying Docker containers in production. Based on the CIS Docker Benchmark, it audits host configuration, Docker daemon settings, container images, runtime configurations, and security operations to generate a compliance report with pass/fail/warn results.
When to Use
- When conducting security assessments that involve performing docker bench security assessment
- When following incident response procedures for related security events
- When performing scheduled security testing or auditing activities
- When validating security controls through hands-on testing
Prerequisites
- Docker Engine installed and running
- Root or sudo access on Docker host
- Docker Bench Security script or container image
Workflow
Step 1: Run Docker Bench Security
# Run as a container (recommended)
docker run --rm --net host --pid host --userns host --cap-add audit_control \
-e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
-v /etc:/etc:ro \
-v /usr/bin/containerd:/usr/bin/containerd:ro \
-v /usr/bin/runc:/usr/bin/runc:ro \
-v /usr/lib/systemd:/usr/lib/systemd:ro \
-v /var/lib:/var/lib:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
--label docker_bench_security \
docker/docker-bench-security
# Run with JSON output
docker run --rm --net host --pid host --userns host --cap-add audit_control \
-v /etc:/etc:ro \
-v /var/lib:/var/lib:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
docker/docker-bench-security -l /dev/stdout 2>/dev/null | tee docker-bench-results.json
# Run specific sections only
docker run --rm --net host --pid host --userns host \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
docker/docker-bench-security -c container_images,container_runtimeStep 2: Interpret Results
[INFO] 1 - Host Configuration
[PASS] 1.1.1 - Ensure a separate partition for containers has been created
[WARN] 1.1.2 - Ensure only trusted users are allowed to control Docker daemon
[PASS] 1.1.3 - Ensure auditing is configured for the Docker daemon
[INFO] 2 - Docker daemon configuration
[FAIL] 2.1 - Run the Docker daemon as a non-root user
[PASS] 2.2 - Ensure network traffic is restricted between containers on the default bridgeStep 3: Remediate Common Failures
# Fix 2.2: Restrict inter-container communication
echo '{"icc": false}' | sudo tee /etc/docker/daemon.json
# Fix 2.17: Restrict containers from acquiring new privileges
echo '{"no-new-privileges": true}' | sudo tee -a /etc/docker/daemon.json
# Fix 5.3: Restrict Linux kernel capabilities
# Use --cap-drop ALL in docker run commands
# Fix 5.12: Mount container's root filesystem as read only
# Use --read-only flag in docker run commands
# Restart Docker daemon after configuration changes
sudo systemctl restart dockerStep 4: Automate Scheduled Assessments
# docker-compose for scheduled assessment
version: '3.8'
services:
bench-security:
image: docker/docker-bench-security
network_mode: host
pid: host
userns_mode: host
cap_add:
- audit_control
volumes:
- /etc:/etc:ro
- /var/lib:/var/lib:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./results:/results
command: -l /results/bench-$(date +%Y%m%d).log
deploy:
restart_policy:
condition: noneValidation Commands
# Verify remediation
docker run --rm docker/docker-bench-security 2>&1 | grep -E "(PASS|FAIL|WARN)" | sort | uniq -c
# Count results by type
docker run --rm docker/docker-bench-security 2>&1 | grep -c "PASS"
docker run --rm docker/docker-bench-security 2>&1 | grep -c "FAIL"
docker run --rm docker/docker-bench-security 2>&1 | grep -c "WARN"References
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 3
api-reference.md1.1 KB
API Reference — Performing Docker Bench Security Assessment
Libraries Used
- subprocess: Run docker-bench-security container and docker inspect commands
- json: Parse docker inspect JSON output
CLI Interface
python agent.py bench # Run full docker-bench-security
python agent.py containers # Check running container configurationsCore Functions
run_docker_bench()
Runs the docker/docker-bench-security container with host access for CIS benchmark checks.
parse_bench_output(output)
Parses [WARN], [PASS], [NOTE] lines into structured findings with sections.
check_container_configs()
Inspects all running containers for CIS Docker Benchmark violations.
CIS Checks Performed on Containers
| Check | CIS ID | Severity |
|---|---|---|
| Privileged mode | 5.4 | CRITICAL |
| Host PID namespace | 5.15 | HIGH |
| Host network namespace | 5.13 | HIGH |
| Dangerous capabilities | 5.3 | HIGH |
| Running as root | 4.1 | MEDIUM |
| Sensitive host mounts | 5.5 | HIGH |
Dependencies
Docker must be installed and accessible. No Python packages required beyond stdlib.
standards.md0.7 KB
Standards - Docker Bench Security Assessment
CIS Docker Benchmark v1.8.0 Sections
| Section | Area | Checks |
|---|---|---|
| 1 | Host Configuration | Partition, users, audit rules |
| 2 | Docker Daemon | ICC, TLS, logging, seccomp, privileges |
| 3 | Docker Daemon Config Files | File permissions and ownership |
| 4 | Container Images | Non-root user, scanning, trusted images |
| 5 | Container Runtime | Capabilities, rootfs, resources, privileges |
| 6 | Docker Security Operations | Monitoring, CVE scanning |
Scoring
- PASS: Check meets CIS recommendation
- FAIL: Check does not meet recommendation (remediation required)
- WARN: Check requires manual verification
- INFO: Informational, no scoring impact
workflows.md0.7 KB
Workflows - Docker Bench Security Assessment
Assessment Workflow
[Run Docker Bench] --> [Parse Results] --> [Prioritize FAIL findings]
| | |
v v v
Initial baseline Export JSON Group by section
assessment for tracking and severity
| | |
+--------------------+----------------------+
|
v
[Create Remediation Plan]
|
v
[Apply Fixes] --> [Re-run Assessment] --> [Compare Scores]Scripts 2
agent.py5.7 KB
#!/usr/bin/env python3
"""Agent for performing Docker CIS Benchmark security assessment."""
import json
import argparse
import subprocess
from datetime import datetime
def run_docker_bench():
"""Run docker-bench-security and parse results."""
cmd = [
"docker", "run", "--rm", "--net", "host", "--pid", "host",
"--userns", "host", "--cap-add", "audit_control",
"-e", "DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST",
"-v", "/etc:/etc:ro", "-v", "/var/lib:/var/lib:ro",
"-v", "/var/run/docker.sock:/var/run/docker.sock:ro",
"-v", "/usr/lib/systemd:/usr/lib/systemd:ro",
"--label", "docker_bench_security",
"docker/docker-bench-security", "-l", "/dev/stdout"
]
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=600)
return parse_bench_output(result.stdout)
except subprocess.TimeoutExpired:
return {"error": "docker-bench-security timed out after 600s"}
except FileNotFoundError:
return {"error": "docker command not found"}
def parse_bench_output(output):
"""Parse docker-bench-security output into structured findings."""
findings = []
current_section = ""
for line in output.split("\n"):
line = line.strip()
if not line:
continue
if line.startswith("[INFO]") and "- " in line and any(c.isdigit() for c in line[:20]):
current_section = line.replace("[INFO]", "").strip()
elif line.startswith("[WARN]"):
findings.append({"level": "WARN", "section": current_section, "message": line.replace("[WARN]", "").strip()})
elif line.startswith("[PASS]"):
findings.append({"level": "PASS", "section": current_section, "message": line.replace("[PASS]", "").strip()})
elif line.startswith("[NOTE]"):
findings.append({"level": "NOTE", "section": current_section, "message": line.replace("[NOTE]", "").strip()})
warn_count = sum(1 for f in findings if f["level"] == "WARN")
pass_count = sum(1 for f in findings if f["level"] == "PASS")
return {
"timestamp": datetime.utcnow().isoformat(),
"total_checks": len(findings),
"warnings": warn_count,
"passed": pass_count,
"score_pct": round(pass_count / max(len(findings), 1) * 100, 1),
"findings": findings,
}
def check_container_configs():
"""Check running container configurations against CIS benchmarks."""
try:
result = subprocess.run(
["docker", "ps", "--format", "{{json .}}"],
capture_output=True, text=True, timeout=30
)
except (subprocess.TimeoutExpired, FileNotFoundError):
return {"error": "docker not available"}
containers = []
for line in result.stdout.strip().split("\n"):
if not line:
continue
try:
c = json.loads(line)
containers.append(c)
except json.JSONDecodeError:
continue
findings = []
for container in containers:
cid = container.get("ID", "")
name = container.get("Names", "")
inspect = _inspect_container(cid)
if isinstance(inspect, dict) and "error" not in inspect:
issues = _check_container_security(inspect, name)
findings.append({"container": name, "id": cid, "issues": issues})
return {"containers_checked": len(findings), "findings": findings}
def _inspect_container(container_id):
try:
result = subprocess.run(
["docker", "inspect", container_id], capture_output=True, text=True, timeout=10
)
data = json.loads(result.stdout)
return data[0] if data else {}
except Exception:
return {"error": "inspect failed"}
def _check_container_security(inspect, name):
issues = []
host_config = inspect.get("HostConfig", {})
if host_config.get("Privileged"):
issues.append({"severity": "CRITICAL", "check": "5.4", "finding": "Container running in privileged mode"})
if host_config.get("PidMode") == "host":
issues.append({"severity": "HIGH", "check": "5.15", "finding": "Container shares host PID namespace"})
if host_config.get("NetworkMode") == "host":
issues.append({"severity": "HIGH", "check": "5.13", "finding": "Container shares host network namespace"})
caps = host_config.get("CapAdd") or []
dangerous_caps = {"SYS_ADMIN", "NET_ADMIN", "SYS_PTRACE", "ALL"}
added_dangerous = set(caps) & dangerous_caps
if added_dangerous:
issues.append({"severity": "HIGH", "check": "5.3", "finding": f"Dangerous capabilities added: {added_dangerous}"})
config = inspect.get("Config", {})
if config.get("User", "") in ("", "root", "0"):
issues.append({"severity": "MEDIUM", "check": "4.1", "finding": "Container running as root user"})
mounts = host_config.get("Binds") or []
sensitive = ["/etc", "/var/run/docker.sock", "/proc", "/sys"]
for mount in mounts:
src = mount.split(":")[0]
if any(src.startswith(s) for s in sensitive):
issues.append({"severity": "HIGH", "check": "5.5", "finding": f"Sensitive host path mounted: {src}"})
return issues
def main():
parser = argparse.ArgumentParser(description="Docker CIS Benchmark Security Assessment")
sub = parser.add_subparsers(dest="command")
sub.add_parser("bench", help="Run docker-bench-security")
sub.add_parser("containers", help="Check running container configurations")
args = parser.parse_args()
if args.command == "bench":
result = run_docker_bench()
elif args.command == "containers":
result = check_container_configs()
else:
parser.print_help()
return
print(json.dumps(result, indent=2, default=str))
if __name__ == "__main__":
main()
process.py1.8 KB
#!/usr/bin/env python3
"""Docker Bench Security Assessment Runner and Parser."""
import subprocess
import json
import sys
import re
def run_docker_bench():
"""Run Docker Bench Security and parse results."""
cmd = [
"docker", "run", "--rm", "--net", "host", "--pid", "host",
"--userns", "host", "--cap-add", "audit_control",
"-v", "/etc:/etc:ro", "-v", "/var/lib:/var/lib:ro",
"-v", "/var/run/docker.sock:/var/run/docker.sock:ro",
"docker/docker-bench-security"
]
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
output = result.stdout + result.stderr
except (subprocess.TimeoutExpired, FileNotFoundError) as e:
print(f"[!] Failed to run Docker Bench: {e}")
sys.exit(1)
results = {"PASS": [], "FAIL": [], "WARN": [], "INFO": []}
for line in output.split("\n"):
for status in ["PASS", "FAIL", "WARN", "INFO"]:
if f"[{status}]" in line:
check = line.strip()
results[status].append(check)
break
print(f"\n{'='*60}")
print("DOCKER BENCH SECURITY RESULTS")
print(f"{'='*60}")
print(f"PASS: {len(results['PASS'])}")
print(f"FAIL: {len(results['FAIL'])}")
print(f"WARN: {len(results['WARN'])}")
print(f"INFO: {len(results['INFO'])}")
total = len(results['PASS']) + len(results['FAIL'])
if total > 0:
score = (len(results['PASS']) / total) * 100
print(f"Score: {score:.1f}%")
if results["FAIL"]:
print(f"\nFAILED CHECKS:")
for f in results["FAIL"]:
print(f" {f}")
with open("docker_bench_results.json", "w") as fh:
json.dump(results, fh, indent=2)
print(f"\n[*] Results saved to docker_bench_results.json")
if __name__ == "__main__":
run_docker_bench()