mirror of
https://github.com/docker/docker-bench-security.git
synced 2025-01-19 00:32:34 +01:00
ec7d8ce690
Add a test object for each test performed by the script. Each object has an id N.M, a desc property describing the test, and the result. Some tests include additional information about the test e.g. "No TLS Certificate Found". That can be found in an optional details property of the test object. Also, some tests might also return a list of containers, images, users, etc. This is included in an optional items property of the test object. Instead of having all test results as top-level objects, break the test results into sections. Each section has an id + description e.g. "1" and "Host Configuration". The tests for that section are an array below that object. All of the additional json output is implemented by adding new functions startsectionjson(), endsectionjson(), starttestjson(), and resulttestjson() that take the id/desc/etc as arguments and print the proper json properties. It also required adding an "end" test to each script that calls endsectionjson(). Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
1276 lines
36 KiB
Bash
1276 lines
36 KiB
Bash
#!/bin/sh
|
|
|
|
check_5() {
|
|
logit "\n"
|
|
id_5="5"
|
|
desc_5="Container Runtime"
|
|
check_5="$id_5 - $desc_5"
|
|
info "$check_5"
|
|
startsectionjson "$id_5" "$desc_5"
|
|
}
|
|
|
|
check_running_containers() {
|
|
# If containers is empty, there are no running containers
|
|
if [ -z "$containers" ]; then
|
|
info " * No containers running, skipping Section 5"
|
|
running_containers=0
|
|
else
|
|
running_containers=1
|
|
# Make the loop separator be a new-line in POSIX compliant fashion
|
|
set -f; IFS=$'
|
|
'
|
|
fi
|
|
}
|
|
|
|
# 5.1
|
|
check_5_1() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_1="5.1"
|
|
desc_5_1="Ensure AppArmor Profile is Enabled"
|
|
check_5_1="$id_5_1 - $desc_5_1"
|
|
starttestjson "$id_5_1" "$desc_5_1"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
no_apparmor_containers=""
|
|
for c in $containers; do
|
|
policy=$(docker inspect --format 'AppArmorProfile={{ .AppArmorProfile }}' "$c")
|
|
|
|
if [ "$policy" = "AppArmorProfile=" -o "$policy" = "AppArmorProfile=[]" -o "$policy" = "AppArmorProfile=<no value>" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_1"
|
|
warn " * No AppArmorProfile Found: $c"
|
|
no_apparmor_containers="$no_apparmor_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * No AppArmorProfile Found: $c"
|
|
no_apparmor_containers="$no_apparmor_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found none without AppArmor
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_1"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers with no AppArmorProfile" "$no_apparmor_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.2
|
|
check_5_2() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_2="5.2"
|
|
desc_5_2="Ensure SELinux security options are set, if applicable"
|
|
check_5_2="$id_5_2 - $desc_5_2"
|
|
starttestjson "$id_5_2" "$desc_5_2"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
no_securityoptions_containers=""
|
|
for c in $containers; do
|
|
policy=$(docker inspect --format 'SecurityOpt={{ .HostConfig.SecurityOpt }}' "$c")
|
|
|
|
if [ "$policy" = "SecurityOpt=" -o "$policy" = "SecurityOpt=[]" -o "$policy" = "SecurityOpt=<no value>" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_2"
|
|
warn " * No SecurityOptions Found: $c"
|
|
no_securityoptions_containers="$no_securityoptions_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * No SecurityOptions Found: $c"
|
|
no_securityoptions_containers="$no_securityoptions_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found none without SELinux
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_2"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers with no SecurityOptions" "$no_securityoptions_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.3
|
|
check_5_3() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_3="5.3"
|
|
desc_5_3="Ensure Linux Kernel Capabilities are restricted within containers"
|
|
check_5_3="$id_5_3 - $desc_5_3"
|
|
starttestjson "$id_5_3" "$desc_5_3"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
caps_containers=""
|
|
for c in $containers; do
|
|
container_caps=$(docker inspect --format 'CapAdd={{ .HostConfig.CapAdd}}' "$c")
|
|
caps=$(echo "$container_caps" | tr "[:lower:]" "[:upper:]" | \
|
|
sed 's/CAPADD/CapAdd/' | \
|
|
sed -r "s/AUDIT_WRITE|CHOWN|DAC_OVERRIDE|FOWNER|FSETID|KILL|MKNOD|NET_BIND_SERVICE|NET_RAW|SETFCAP|SETGID|SETPCAP|SETUID|SYS_CHROOT|\s//g")
|
|
|
|
if [ "$caps" != 'CapAdd=' -a "$caps" != 'CapAdd=[]' -a "$caps" != 'CapAdd=<no value>' -a "$caps" != 'CapAdd=<nil>' ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_3"
|
|
warn " * Capabilities added: $caps to $c"
|
|
caps_containers="$caps_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Capabilities added: $caps to $c"
|
|
caps_containers="$caps_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found none with extra capabilities
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_3"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Capabilities added for containers" "$caps_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.4
|
|
check_5_4() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_4="5.4"
|
|
desc_5_4="Ensure privileged containers are not used"
|
|
check_5_4="$id_5_4 - $desc_5_4"
|
|
starttestjson "$id_5_4" "$desc_5_4"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
privileged_containers=""
|
|
for c in $containers; do
|
|
privileged=$(docker inspect --format '{{ .HostConfig.Privileged }}' "$c")
|
|
|
|
if [ "$privileged" = "true" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_4"
|
|
warn " * Container running in Privileged mode: $c"
|
|
privileged_containers="$privileged_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Container running in Privileged mode: $c"
|
|
privileged_containers="$privileged_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found no privileged containers
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_4"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers running in privileged mode" "$privileged_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.5
|
|
check_5_5() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_5="5.5"
|
|
desc_5_5="Ensure sensitive host system directories are not mounted on containers"
|
|
check_5_5="$id_5_5 - $desc_5_5"
|
|
starttestjson "$id_5_5" "$desc_5_5"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
# List of sensitive directories to test for. Script uses new-lines as a separator.
|
|
# Note the lack of identation. It needs it for the substring comparison.
|
|
sensitive_dirs='/
|
|
/boot
|
|
/dev
|
|
/etc
|
|
/lib
|
|
/proc
|
|
/sys
|
|
/usr'
|
|
fail=0
|
|
sensitive_mount_containers=""
|
|
for c in $containers; do
|
|
if docker inspect --format '{{ .VolumesRW }}' "$c" 2>/dev/null 1>&2; then
|
|
volumes=$(docker inspect --format '{{ .VolumesRW }}' "$c")
|
|
else
|
|
volumes=$(docker inspect --format '{{ .Mounts }}' "$c")
|
|
fi
|
|
# Go over each directory in sensitive dir and see if they exist in the volumes
|
|
for v in $sensitive_dirs; do
|
|
sensitive=0
|
|
if echo "$volumes" | grep -e "{.*\s$v\s.*true\s}" 2>/tmp/null 1>&2; then
|
|
sensitive=1
|
|
fi
|
|
if [ $sensitive -eq 1 ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_5"
|
|
warn " * Sensitive directory $v mounted in: $c"
|
|
sensitive_mount_containers="$sensitive_mount_containers $c:$v"
|
|
fail=1
|
|
else
|
|
warn " * Sensitive directory $v mounted in: $c"
|
|
sensitive_mount_containers="$sensitive_mount_containers $c:$v"
|
|
fi
|
|
fi
|
|
done
|
|
done
|
|
# We went through all the containers and found none with sensitive mounts
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_5"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers with sensitive directories mounted" "$sensitive_mount_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.6
|
|
check_5_6() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_6="5.6"
|
|
desc_5_6="Ensure ssh is not run within containers"
|
|
check_5_6="$id_5_6 - $desc_5_6"
|
|
starttestjson "$id_5_6" "$desc_5_6"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
ssh_exec_containers=""
|
|
printcheck=0
|
|
for c in $containers; do
|
|
|
|
processes=$(docker exec "$c" ps -el 2>/dev/null | grep -c sshd | awk '{print $1}')
|
|
if [ "$processes" -ge 1 ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_6"
|
|
warn " * Container running sshd: $c"
|
|
ssh_exec_containers="$ssh_exec_containers $c"
|
|
fail=1
|
|
printcheck=1
|
|
else
|
|
warn " * Container running sshd: $c"
|
|
ssh_exec_containers="$ssh_exec_containers $c"
|
|
fi
|
|
fi
|
|
|
|
exec_check=$(docker exec "$c" ps -el 2>/dev/null)
|
|
if [ $? -eq 255 ]; then
|
|
if [ $printcheck -eq 0 ]; then
|
|
warn "$check_5_6"
|
|
printcheck=1
|
|
fi
|
|
warn " * Docker exec fails: $c"
|
|
ssh_exec_containers="$ssh_exec_containers $c"
|
|
fail=1
|
|
fi
|
|
|
|
done
|
|
# We went through all the containers and found none with sshd
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_6"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers with sshd/docker exec failures" "$ssh_exec_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.7
|
|
check_5_7() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_7="5.7"
|
|
desc_5_7="Ensure privileged ports are not mapped within containers"
|
|
check_5_7="$id_5_7 - $desc_5_7"
|
|
starttestjson "$id_5_7" "$desc_5_7"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
privileged_port_containers=""
|
|
for c in $containers; do
|
|
# Port format is private port -> ip: public port
|
|
ports=$(docker port "$c" | awk '{print $0}' | cut -d ':' -f2)
|
|
|
|
# iterate through port range (line delimited)
|
|
for port in $ports; do
|
|
if [ ! -z "$port" ] && [ "$port" -lt 1024 ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_7"
|
|
warn " * Privileged Port in use: $port in $c"
|
|
privileged_port_containers="$privileged_port_containers $c:$port"
|
|
fail=1
|
|
else
|
|
warn " * Privileged Port in use: $port in $c"
|
|
privileged_port_containers="$privileged_port_containers $c:$port"
|
|
fi
|
|
fi
|
|
done
|
|
done
|
|
# We went through all the containers and found no privileged ports
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_7"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers using privileged ports" "$privileged_port_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.8
|
|
check_5_8() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_8="5.8"
|
|
desc_5_8="Ensure only needed ports are open on the container"
|
|
check_5_8="$id_5_8 - $desc_5_8"
|
|
starttestjson "$id_5_8" "$desc_5_8"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
note "$check_5_8"
|
|
resulttestjson "NOTE"
|
|
currentScore=$((currentScore + 0))
|
|
}
|
|
|
|
# 5.9
|
|
check_5_9() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_9="5.9"
|
|
desc_5_9="Ensure the host's network namespace is not shared"
|
|
check_5_9="$id_5_9 - $desc_5_9"
|
|
starttestjson "$id_5_9" "$desc_5_9"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
net_host_containers=""
|
|
for c in $containers; do
|
|
mode=$(docker inspect --format 'NetworkMode={{ .HostConfig.NetworkMode }}' "$c")
|
|
|
|
if [ "$mode" = "NetworkMode=host" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_9"
|
|
warn " * Container running with networking mode 'host': $c"
|
|
net_host_containers="$net_host_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Container running with networking mode 'host': $c"
|
|
net_host_containers="$net_host_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found no Network Mode host
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_9"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 0))
|
|
else
|
|
resulttestjson "WARN" "Containers running with networking mode 'host'" "$net_host_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.10
|
|
check_5_10() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_10="5.10"
|
|
desc_5_10="Ensure memory usage for container is limited"
|
|
check_5_10="$id_5_10 - $desc_5_10"
|
|
starttestjson "$id_5_10" "$desc_5_10"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
mem_unlimited_containers=""
|
|
for c in $containers; do
|
|
if docker inspect --format '{{ .Config.Memory }}' "$c" 2> /dev/null 1>&2; then
|
|
memory=$(docker inspect --format '{{ .Config.Memory }}' "$c")
|
|
else
|
|
memory=$(docker inspect --format '{{ .HostConfig.Memory }}' "$c")
|
|
fi
|
|
|
|
if [ "$memory" = "0" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_10"
|
|
warn " * Container running without memory restrictions: $c"
|
|
mem_unlimited_containers="$mem_unlimited_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Container running without memory restrictions: $c"
|
|
mem_unlimited_containers="$mem_unlimited_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found no lack of Memory restrictions
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_10"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Container running without memory restrictions" "$mem_unlimited_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.11
|
|
check_5_11() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_11="5.11"
|
|
desc_5_11="Ensure CPU priority is set appropriately on the container"
|
|
check_5_11="$id_5_11 - $desc_5_11"
|
|
starttestjson "$id_5_11" "$desc_5_11"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
cpu_unlimited_containers=""
|
|
for c in $containers; do
|
|
if docker inspect --format '{{ .Config.CpuShares }}' "$c" 2> /dev/null 1>&2; then
|
|
shares=$(docker inspect --format '{{ .Config.CpuShares }}' "$c")
|
|
else
|
|
shares=$(docker inspect --format '{{ .HostConfig.CpuShares }}' "$c")
|
|
fi
|
|
|
|
if [ "$shares" = "0" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_11"
|
|
warn " * Container running without CPU restrictions: $c"
|
|
cpu_unlimited_containers="$cpu_unlimited_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Container running without CPU restrictions: $c"
|
|
cpu_unlimited_containers="$cpu_unlimited_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found no lack of CPUShare restrictions
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_11"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers running without CPU restrictions" "$cpu_unlimited_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.12
|
|
check_5_12() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_12="5.12"
|
|
desc_5_12="Ensure the container's root filesystem is mounted as read only"
|
|
check_5_12="$id_5_12 - $desc_5_12"
|
|
starttestjson "$id_5_12" "$desc_5_12"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
fsroot_mount_containers=""
|
|
for c in $containers; do
|
|
read_status=$(docker inspect --format '{{ .HostConfig.ReadonlyRootfs }}' "$c")
|
|
|
|
if [ "$read_status" = "false" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_12"
|
|
warn " * Container running with root FS mounted R/W: $c"
|
|
fsroot_mount_containers="$fsroot_mount_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Container running with root FS mounted R/W: $c"
|
|
fsroot_mount_containers="$fsroot_mount_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found no R/W FS mounts
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_12"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers running with root FS mounted R/W" "$fsroot_mount_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.13
|
|
check_5_13() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_13="5.13"
|
|
desc_5_13="Ensure incoming container traffic is binded to a specific host interface"
|
|
check_5_13="$id_5_13 - $desc_5_13"
|
|
starttestjson "$id_5_13" "$desc_5_13"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
incoming_unbound_containers=""
|
|
for c in $containers; do
|
|
for ip in $(docker port "$c" | awk '{print $3}' | cut -d ':' -f1); do
|
|
if [ "$ip" = "0.0.0.0" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_13"
|
|
warn " * Port being bound to wildcard IP: $ip in $c"
|
|
incoming_unbound_containers="$incoming_unbound_containers $c:$ip"
|
|
fail=1
|
|
else
|
|
warn " * Port being bound to wildcard IP: $ip in $c"
|
|
incoming_unbound_containers="$incoming_unbound_containers $c:$ip"
|
|
fi
|
|
fi
|
|
done
|
|
done
|
|
# We went through all the containers and found no ports bound to 0.0.0.0
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_13"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers with port bound to wildcard IP" "$incoming_unbound_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.14
|
|
check_5_14() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_14="5.14"
|
|
desc_5_14="Ensure 'on-failure' container restart policy is set to '5'"
|
|
check_5_14="$id_5_14 - $desc_5_14"
|
|
starttestjson "$id_5_14" "$desc_5_14"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
maxretry_unset_containers=""
|
|
for c in $containers; do
|
|
policy=$(docker inspect --format MaximumRetryCount='{{ .HostConfig.RestartPolicy.MaximumRetryCount }}' "$c")
|
|
|
|
if [ "$policy" != "MaximumRetryCount=5" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_14"
|
|
warn " * MaximumRetryCount is not set to 5: $c"
|
|
maxretry_unset_containers="$maxretry_unset_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * MaximumRetryCount is not set to 5: $c"
|
|
maxretry_unset_containers="$maxretry_unset_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and they all had MaximumRetryCount=5
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_14"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers with MaximumRetryCount not set to 5" "$maxretry_unset_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.15
|
|
check_5_15() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_15="5.15"
|
|
desc_5_15="Ensure the host's process namespace is not shared"
|
|
check_5_15="$id_5_15 - $desc_5_15"
|
|
starttestjson "$id_5_15" "$desc_5_15"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
pidns_shared_containers=""
|
|
for c in $containers; do
|
|
mode=$(docker inspect --format 'PidMode={{.HostConfig.PidMode }}' "$c")
|
|
|
|
if [ "$mode" = "PidMode=host" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_15"
|
|
warn " * Host PID namespace being shared with: $c"
|
|
pidns_shared_containers="$pidns_shared_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Host PID namespace being shared with: $c"
|
|
pidns_shared_containers="$pidns_shared_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found none with PidMode as host
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_15"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers sharing host PID namespace" "$pidns_shared_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.16
|
|
check_5_16() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_16="5.16"
|
|
desc_5_16="Ensure the host's IPC namespace is not shared"
|
|
check_5_16="$id_5_16 - $desc_5_16"
|
|
starttestjson "$id_5_16" "$desc_5_16"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
ipcns_shared_containers=""
|
|
for c in $containers; do
|
|
mode=$(docker inspect --format 'IpcMode={{.HostConfig.IpcMode }}' "$c")
|
|
|
|
if [ "$mode" = "IpcMode=host" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_16"
|
|
warn " * Host IPC namespace being shared with: $c"
|
|
ipcns_shared_containers="$ipcns_shared_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Host IPC namespace being shared with: $c"
|
|
ipcns_shared_containers="$ipcns_shared_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found none with IPCMode as host
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_16"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers sharing host IPC namespace" "$ipcns_shared_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.17
|
|
check_5_17() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_17="5.17"
|
|
desc_5_17="Ensure host devices are not directly exposed to containers"
|
|
check_5_17="$id_5_17 - $desc_5_17"
|
|
starttestjson "$id_5_17" "$desc_5_17"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
hostdev_exposed_containers=""
|
|
for c in $containers; do
|
|
devices=$(docker inspect --format 'Devices={{ .HostConfig.Devices }}' "$c")
|
|
|
|
if [ "$devices" != "Devices=" -a "$devices" != "Devices=[]" -a "$devices" != "Devices=<no value>" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
info "$check_5_17"
|
|
info " * Container has devices exposed directly: $c"
|
|
hostdev_exposed_containers="$hostdev_exposed_containers $c"
|
|
fail=1
|
|
else
|
|
info " * Container has devices exposed directly: $c"
|
|
hostdev_exposed_containers="$hostdev_exposed_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found none with devices
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_17"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "INFO" "Containers with host devices exposed directly" "$hostdev_exposed_containers"
|
|
currentScore=$((currentScore + 0))
|
|
fi
|
|
}
|
|
|
|
# 5.18
|
|
check_5_18() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_18="5.18"
|
|
desc_5_18="Ensure the default ulimit is overwritten at runtime, only if needed"
|
|
check_5_18="$id_5_18 - $desc_5_18"
|
|
starttestjson "$id_5_18" "$desc_5_18"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
no_ulimit_containers=""
|
|
for c in $containers; do
|
|
ulimits=$(docker inspect --format 'Ulimits={{ .HostConfig.Ulimits }}' "$c")
|
|
|
|
if [ "$ulimits" = "Ulimits=" -o "$ulimits" = "Ulimits=[]" -o "$ulimits" = "Ulimits=<no value>" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
info "$check_5_18"
|
|
info " * Container no default ulimit override: $c"
|
|
no_ulimit_containers="$no_ulimit_containers $c"
|
|
fail=1
|
|
else
|
|
info " * Container no default ulimit override: $c"
|
|
no_ulimit_containers="$no_ulimit_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found none without Ulimits
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_18"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "INFO" "Containers with no default ulimit override" "$no_ulimit_containers"
|
|
currentScore=$((currentScore + 0))
|
|
fi
|
|
}
|
|
|
|
# 5.19
|
|
check_5_19() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_19="5.19"
|
|
desc_5_19="Ensure mount propagation mode is not set to shared"
|
|
check_5_19="$id_5_19 - $desc_5_19"
|
|
starttestjson "$id_5_19" "$desc_5_19"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
mountprop_shared_containers=""
|
|
for c in $containers; do
|
|
if docker inspect --format 'Propagation={{range $mnt := .Mounts}} {{json $mnt.Propagation}} {{end}}' "$c" | \
|
|
grep shared 2>/dev/null 1>&2; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_19"
|
|
warn " * Mount propagation mode is shared: $c"
|
|
mountprop_shared_containers="$mountprop_shared_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Mount propagation mode is shared: $c"
|
|
mountprop_shared_containers="$mountprop_shared_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found none with shared propagation mode
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_19"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers with shared mount propagation" "$mountprop_shared_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.20
|
|
check_5_20() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_20="5.20"
|
|
desc_5_20="Ensure the host's UTS namespace is not shared"
|
|
check_5_20="$id_5_20 - $desc_5_20"
|
|
starttestjson "$id_5_20" "$desc_5_20"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
utcns_shared_containers=""
|
|
for c in $containers; do
|
|
mode=$(docker inspect --format 'UTSMode={{.HostConfig.UTSMode }}' "$c")
|
|
|
|
if [ "$mode" = "UTSMode=host" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_20"
|
|
warn " * Host UTS namespace being shared with: $c"
|
|
utcns_shared_containers="$utcns_shared_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Host UTS namespace being shared with: $c"
|
|
utcns_shared_containers="$utcns_shared_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found none with UTSMode as host
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_20"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers sharing host UTS namespace" "$utcns_shared_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.21
|
|
check_5_21() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_21="5.21"
|
|
desc_5_21="Ensure the default seccomp profile is not Disabled"
|
|
check_5_21="$id_5_21 - $desc_5_21"
|
|
starttestjson "$id_5_21" "$desc_5_21"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
seccomp_disabled_containers=""
|
|
for c in $containers; do
|
|
if docker inspect --format 'SecurityOpt={{.HostConfig.SecurityOpt }}' "$c" | \
|
|
grep -E 'seccomp:unconfined|seccomp=unconfined' 2>/dev/null 1>&2; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_21"
|
|
warn " * Default seccomp profile disabled: $c"
|
|
seccomp_disabled_containers="$seccomp_disabled_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Default seccomp profile disabled: $c"
|
|
seccomp_disabled_containers="$seccomp_disabled_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found none with default secomp profile disabled
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_21"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers with default seccomp profile disabled" "$seccomp_disabled_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.22
|
|
check_5_22() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_22="5.22"
|
|
desc_5_22="Ensure docker exec commands are not used with privileged option"
|
|
check_5_22="$id_5_22 - $desc_5_22"
|
|
starttestjson "$id_5_22" "$desc_5_22"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
note "$check_5_22"
|
|
resulttestjson "NOTE"
|
|
currentScore=$((currentScore + 0))
|
|
}
|
|
|
|
# 5.23
|
|
check_5_23() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_23="5.23"
|
|
desc_5_23="Ensure docker exec commands are not used with user option"
|
|
check_5_23="$id_5_23 - $desc_5_23"
|
|
starttestjson "$id_5_23" "$desc_5_23"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
note "$check_5_23"
|
|
resulttestjson "NOTE"
|
|
currentScore=$((currentScore + 0))
|
|
}
|
|
|
|
# 5.24
|
|
check_5_24() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_24="5.24"
|
|
desc_5_24="Ensure cgroup usage is confirmed"
|
|
check_5_24="$id_5_24 - $desc_5_24"
|
|
starttestjson "$id_5_24" "$desc_5_24"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
unexpected_cgroup_containers=""
|
|
for c in $containers; do
|
|
mode=$(docker inspect --format 'CgroupParent={{.HostConfig.CgroupParent }}x' "$c")
|
|
|
|
if [ "$mode" != "CgroupParent=x" ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_24"
|
|
warn " * Confirm cgroup usage: $c"
|
|
unexpected_cgroup_containers="$unexpected_cgroup_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Confirm cgroup usage: $c"
|
|
unexpected_cgroup_containers="$unexpected_cgroup_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found none with UTSMode as host
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_24"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers using unexpected cgroup" "$unexpected_cgroup_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.25
|
|
check_5_25() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
id_5_25="5.25"
|
|
desc_5_25="Ensure the container is restricted from acquiring additional privileges"
|
|
check_5_25="$id_5_25 - $desc_5_25"
|
|
starttestjson "$id_5_25" "$desc_5_25"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
addprivs_containers=""
|
|
for c in $containers; do
|
|
if ! docker inspect --format 'SecurityOpt={{.HostConfig.SecurityOpt }}' "$c" | grep 'no-new-privileges' 2>/dev/null 1>&2; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_25"
|
|
warn " * Privileges not restricted: $c"
|
|
addprivs_containers="$addprivs_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Privileges not restricted: $c"
|
|
addprivs_containers="$addprivs_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found none with capability to acquire additional privileges
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_25"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers without restricted privileges" "$addprivs_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.26
|
|
check_5_26() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_26="5.26"
|
|
desc_5_26="Ensure container health is checked at runtime"
|
|
check_5_26="$id_5_26 - $desc_5_26"
|
|
starttestjson "$id_5_26" "$desc_5_26"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
nohealthcheck_containers=""
|
|
for c in $containers; do
|
|
if ! docker inspect --format '{{ .Id }}: Health={{ .State.Health.Status }}' "$c" 2>/dev/null 1>&2; then
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_26"
|
|
warn " * Health check not set: $c"
|
|
nohealthcheck_containers="$nohealthcheck_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Health check not set: $c"
|
|
nohealthcheck_containers="$nohealthcheck_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_26"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers without health check" "$nohealthcheck_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.27
|
|
check_5_27() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_27="5.27"
|
|
desc_5_27="Ensure docker commands always get the latest version of the image"
|
|
check_5_27="$id_5_27 - $desc_5_27"
|
|
starttestjson "$id_5_27" "$desc_5_27"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
info "$check_5_27"
|
|
resulttestjson "INFO"
|
|
currentScore=$((currentScore + 0))
|
|
}
|
|
|
|
# 5.28
|
|
check_5_28() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_28="5.28"
|
|
desc_5_28="Ensure PIDs cgroup limit is used"
|
|
check_5_28="$id_5_28 - $desc_5_28"
|
|
starttestjson "$id_5_28" "$desc_5_28"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
nopids_limit_containers=""
|
|
for c in $containers; do
|
|
pidslimit=$(docker inspect --format '{{.HostConfig.PidsLimit }}' "$c")
|
|
|
|
if [ "$pidslimit" -le 0 ]; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_28"
|
|
warn " * PIDs limit not set: $c"
|
|
nopids_limit_containers="$nopids_limit_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * PIDs limit not set: $c"
|
|
nopids_limit_containers="$nopids_limit_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found all with PIDs limit
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_28"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers without PIDs cgroup limit" "$nopids_limit_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.29
|
|
check_5_29() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_29="5.29"
|
|
desc_5_29="Ensure Docker's default bridge docker0 is not used"
|
|
check_5_29="$id_5_29 - $desc_5_29"
|
|
starttestjson "$id_5_29" "$desc_5_29"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
docker_network_containers=""
|
|
networks=$(docker network ls -q 2>/dev/null)
|
|
for net in $networks; do
|
|
if docker network inspect --format '{{ .Options }}' "$net" 2>/dev/null | grep "com.docker.network.bridge.name:docker0" >/dev/null 2>&1; then
|
|
docker0Containers=$(docker network inspect --format='{{ range $k, $v := .Containers }} {{ $k }} {{ end }}' "$net" | \
|
|
sed -e 's/^ //' -e 's/ /\n/g' 2>/dev/null)
|
|
|
|
if [ -n "$docker0Containers" ]; then
|
|
if [ $fail -eq 0 ]; then
|
|
info "$check_5_29"
|
|
fail=1
|
|
fi
|
|
for c in $docker0Containers; do
|
|
if [ -z "$exclude" ]; then
|
|
cName=$(docker inspect --format '{{.Name}}' "$c" 2>/dev/null | sed 's/\///g')
|
|
else
|
|
pattern=$(echo "$exclude" | sed 's/,/|/g')
|
|
cName=$(docker inspect --format '{{.Name}}' "$c" 2>/dev/null | sed 's/\///g' | grep -Ev "$pattern" )
|
|
fi
|
|
if ! [ -z "$cName" ]; then
|
|
info " * Container in docker0 network: $cName"
|
|
docker_network_containers="$docker_network_containers $c:$cName"
|
|
fi
|
|
done
|
|
fi
|
|
currentScore=$((currentScore + 0))
|
|
fi
|
|
done
|
|
# We went through all the containers and found none in docker0 network
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_29"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "INFO" "Containers using docker0 network" "$docker_network_containers"
|
|
currentScore=$((currentScore + 0))
|
|
fi
|
|
}
|
|
|
|
# 5.30
|
|
check_5_30() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_30="5.30"
|
|
desc_5_30="Ensure the host's user namespaces is not shared"
|
|
check_5_30="$id_5_30 - $desc_5_30"
|
|
starttestjson "$id_5_30" "$desc_5_30"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
hostns_shared_containers=""
|
|
for c in $containers; do
|
|
if docker inspect --format '{{ .HostConfig.UsernsMode }}' "$c" 2>/dev/null | grep -i 'host' >/dev/null 2>&1; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_30"
|
|
warn " * Namespace shared: $c"
|
|
hostns_shared_containers="$hostns_shared_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Namespace shared: $c"
|
|
hostns_shared_containers="$hostns_shared_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found none with host's user namespace shared
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_30"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers sharing host user namespace" "$hostns_shared_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
# 5.31
|
|
check_5_31() {
|
|
if [ "$running_containers" -ne 1 ]; then
|
|
return
|
|
fi
|
|
|
|
id_5_31="5.31"
|
|
desc_5_31="Ensure the Docker socket is not mounted inside any containers"
|
|
check_5_31="$id_5_31 - $desc_5_31"
|
|
starttestjson "$id_5_31" "$desc_5_31"
|
|
|
|
totalChecks=$((totalChecks + 1))
|
|
|
|
fail=0
|
|
docker_sock_containers=""
|
|
for c in $containers; do
|
|
if docker inspect --format '{{ .Mounts }}' "$c" 2>/dev/null | grep 'docker.sock' >/dev/null 2>&1; then
|
|
# If it's the first container, fail the test
|
|
if [ $fail -eq 0 ]; then
|
|
warn "$check_5_31"
|
|
warn " * Docker socket shared: $c"
|
|
docker_sock_containers="$docker_sock_containers $c"
|
|
fail=1
|
|
else
|
|
warn " * Docker socket shared: $c"
|
|
docker_sock_containers="$docker_sock_containers $c"
|
|
fi
|
|
fi
|
|
done
|
|
# We went through all the containers and found none with docker.sock shared
|
|
if [ $fail -eq 0 ]; then
|
|
pass "$check_5_31"
|
|
resulttestjson "PASS"
|
|
currentScore=$((currentScore + 1))
|
|
else
|
|
resulttestjson "WARN" "Containers sharing docker socket" "$docker_sock_containers"
|
|
currentScore=$((currentScore - 1))
|
|
fi
|
|
}
|
|
|
|
check_5_end() {
|
|
endsectionjson
|
|
}
|