diff --git a/docker-bench-security.sh b/docker-bench-security.sh index 27e5714..a1c21a8 100755 --- a/docker-bench-security.sh +++ b/docker-bench-security.sh @@ -141,10 +141,8 @@ main () { printf "\n" info "Checks: $totalChecks" info "Score: $currentScore" - integerjson "checks" "$totalChecks" - integerjson "score" "$currentScore" - endjson "$(date +%s)" + endjson "$totalChecks" "$currentScore" "$(date +%s)" } main "$@" diff --git a/functions_lib.sh b/functions_lib.sh index 6afba6b..26062c8 100644 --- a/functions_lib.sh +++ b/functions_lib.sh @@ -15,6 +15,7 @@ host_configuration() { check_1_11 check_1_12 check_1_13 + check_1_end } docker_daemon_configuration() { @@ -37,6 +38,7 @@ docker_daemon_configuration() { check_2_16 check_2_17 check_2_18 + check_2_end } docker_daemon_files() { @@ -61,6 +63,7 @@ docker_daemon_files() { check_3_18 check_3_19 check_3_20 + check_3_end } container_images() { @@ -76,6 +79,7 @@ container_images() { check_4_9 check_4_10 check_4_11 + check_4_end } container_runtime() { @@ -112,12 +116,14 @@ container_runtime() { check_5_29 check_5_30 check_5_31 + check_5_end } docker_security_operations() { check_6 check_6_1 check_6_2 + check_6_end } docker_swarm_configuration() { @@ -131,11 +137,13 @@ docker_swarm_configuration() { check_7_8 check_7_9 check_7_10 + check_7_end } community_checks() { check_c check_c_1 + check_c_end } # CIS diff --git a/output_lib.sh b/output_lib.sh index af79f02..3bb7ce8 100644 --- a/output_lib.sh +++ b/output_lib.sh @@ -30,17 +30,43 @@ yell () { } beginjson () { - printf "{\n \"dockerbenchsecurity\": \"%s\",\n \"start\": %s," "$1" "$2" | tee "$logger.json" 2>/dev/null 1>&2 + printf "{\n \"dockerbenchsecurity\": \"%s\",\n \"start\": %s,\n \"tests\": [" "$1" "$2" | tee "$logger.json" 2>/dev/null 1>&2 } endjson (){ - printf "\n \"end\": %s \n}\n" "$1" | tee -a "$logger.json" 2>/dev/null 1>&2 + printf "\n ], \"checks\": %s, \"score\": %s, \"end\": %s \n}\n" "$1" "$2" "$3" | tee -a "$logger.json" 2>/dev/null 1>&2 } logjson (){ printf "\n \"%s\": \"%s\"," "$1" "$2" | tee -a "$logger.json" 2>/dev/null 1>&2 } -integerjson (){ - printf "\n \"%s\": %s," "$1" "$2" | tee -a "$logger.json" 2>/dev/null 1>&2 +SSEP= +SEP= +startsectionjson() { + printf "%s\n {\"id\": \"%s\", \"desc\": \"%s\", \"results\": [" "$SSEP" "$1" "$2" | tee -a "$logger.json" 2>/dev/null 1>&2 + SEP= + SSEP="," +} + +endsectionjson() { + printf "\n ]}" | tee -a "$logger.json" 2>/dev/null 1>&2 +} + +starttestjson() { + printf "%s\n {\"id\": \"%s\", \"desc\": \"%s\", " "$SEP" "$1" "$2" | tee -a "$logger.json" 2>/dev/null 1>&2 + SEP="," +} + +resulttestjson() { + if [ $# -eq 1 ]; then + printf "\"result\": \"%s\"}" "$1" | tee -a "$logger.json" 2>/dev/null 1>&2 + elif [ $# -eq 2 ]; then + # Result also contains details + printf "\"result\": \"%s\", \"details\": \"%s\"}" "$1" "$2" | tee -a "$logger.json" 2>/dev/null 1>&2 + else + # Result also includes details and a list of items. Add that directly to details and to an array property "items" + itemsJson=$(printf "["; ISEP=""; for item in $3; do printf "%s\"%s\"" "$ISEP" "$item"; ISEP=","; done; printf "]") + printf "\"result\": \"%s\", \"details\": \"%s: %s\", \"items\": %s}" "$1" "$2" "$3" "$itemsJson" | tee -a "$logger.json" 2>/dev/null 1>&2 + fi } diff --git a/tests/1_host_configuration.sh b/tests/1_host_configuration.sh index 75d259f..a62f11f 100644 --- a/tests/1_host_configuration.sh +++ b/tests/1_host_configuration.sh @@ -2,41 +2,57 @@ check_1() { logit "" - info "1 - Host Configuration" + id_1="1" + desc_1="Host Configuration" + check_1="$id_1 - $desc_1" + info "$check_1" + startsectionjson "$id_1" "$desc_1" } # 1.1 check_1_1() { - check_1_1="1.1 - Ensure a separate partition for containers has been created" + id_1_1="1.1" + desc_1_1="Ensure a separate partition for containers has been created" + check_1_1="$id_1_1 - $desc_1_1" + starttestjson "$id_1_1" "$desc_1_1" + totalChecks=$((totalChecks + 1)) if grep /var/lib/docker /etc/fstab >/dev/null 2>&1; then pass "$check_1_1" - logjson "1.1" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) elif mountpoint -q -- /var/lib/docker >/dev/null 2>&1; then pass "$check_1_1" - logjson "1.1" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_1" - logjson "1.1" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi } # 1.2 check_1_2() { - check_1_2="1.2 - Ensure the container host has been Hardened" + id_1_2="1.2" + desc_1_2="Ensure the container host has been Hardened" + check_1_2="$id_1_2 - $desc_1_2" + starttestjson "$id_1_2" "$desc_1_2" + totalChecks=$((totalChecks + 1)) note "$check_1_2" - logjson "1.2" "INFO" + resulttestjson "INFO" currentScore=$((currentScore + 0)) } # 1.3 check_1_3() { - check_1_3="1.3 - Ensure Docker is up to date" + id_1_3="1.3" + desc_1_3="Ensure Docker is up to date" + check_1_3="$id_1_3 - $desc_1_3" + starttestjson "$id_1_3" "$desc_1_3" + totalChecks=$((totalChecks + 1)) docker_version=$(docker version | grep -i -A2 '^server' | grep ' Version:' \ | awk '{print $NF; exit}' | tr -d '[:alpha:]-,') @@ -46,316 +62,361 @@ check_1_3() { info "$check_1_3" info " * Using $docker_version, verify is it up to date as deemed necessary" info " * Your operating system vendor may provide support and security maintenance for Docker" - logjson "1.3" "INFO" + resulttestjson "INFO" "Using $docker_version" currentScore=$((currentScore + 0)) else pass "$check_1_3" info " * Using $docker_version which is current" info " * Check with your operating system vendor for support and security maintenance for Docker" - logjson "1.3" "PASS" + resulttestjson "PASS" "Using $docker_version" currentScore=$((currentScore + 0)) fi } # 1.4 check_1_4() { - check_1_4="1.4 - Ensure only trusted users are allowed to control Docker daemon" + id_1_4="1.4" + desc_1_4="Ensure only trusted users are allowed to control Docker daemon" + check_1_4="$id_1_4 - $desc_1_4" + starttestjson "$id_1_4" "$desc_1_4" + totalChecks=$((totalChecks + 1)) docker_users=$(getent group docker) info "$check_1_4" for u in $docker_users; do info " * $u" - logjson "1.4" "INFO: $u" done + resulttestjson "INFO" "users" "$docker_users" currentScore=$((currentScore + 0)) } # 1.5 check_1_5() { - check_1_5="1.5 - Ensure auditing is configured for the Docker daemon" + id_1_5="1.5" + desc_1_5="Ensure auditing is configured for the Docker daemon" + check_1_5="$id_1_5 - $desc_1_5" + starttestjson "$id_1_5" "$desc_1_5" + totalChecks=$((totalChecks + 1)) file="/usr/bin/docker " if command -v auditctl >/dev/null 2>&1; then if auditctl -l | grep "$file" >/dev/null 2>&1; then pass "$check_1_5" - logjson "1.5" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_5" - logjson "1.5" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then pass "$check_1_5" - logjson "1.5" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_5" - logjson "1.5" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi } # 1.6 check_1_6() { - check_1_6="1.6 - Ensure auditing is configured for Docker files and directories - /var/lib/docker" + id_1_6="1.6" + desc_1_6="Ensure auditing is configured for Docker files and directories - /var/lib/docker" + check_1_6="$id_1_6 - $desc_1_6" + starttestjson "$id_1_6" "$desc_1_6" + totalChecks=$((totalChecks + 1)) directory="/var/lib/docker" if [ -d "$directory" ]; then if command -v auditctl >/dev/null 2>&1; then if auditctl -l | grep $directory >/dev/null 2>&1; then pass "$check_1_6" - logjson "1.6" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_6" - logjson "1.6" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$directory" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then pass "$check_1_6" - logjson "1.6" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_6" - logjson "1.6" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else info "$check_1_6" info " * Directory not found" - logjson "1.6" "INFO" + resulttestjson "INFO" "Directory not found" currentScore=$((currentScore + 0)) fi } # 1.7 check_1_7() { - check_1_7="1.7 - Ensure auditing is configured for Docker files and directories - /etc/docker" + id_1_7="1.7" + desc_1_7="Ensure auditing is configured for Docker files and directories - /etc/docker" + check_1_7="$id_1_7 - $desc_1_7" + starttestjson "$id_1_7" "$desc_1_7" + totalChecks=$((totalChecks + 1)) directory="/etc/docker" if [ -d "$directory" ]; then if command -v auditctl >/dev/null 2>&1; then if auditctl -l | grep $directory >/dev/null 2>&1; then pass "$check_1_7" - logjson "1.7" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_7" - logjson "1.7" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$directory" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then pass "$check_1_7" - logjson "1.7" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_7" - logjson "1.7" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else info "$check_1_7" info " * Directory not found" - logjson "1.7" "INFO" + resulttestjson "INFO" "Directory not found" currentScore=$((currentScore + 0)) fi } # 1.8 check_1_8() { - check_1_8="1.8 - Ensure auditing is configured for Docker files and directories - docker.service" + id_1_8="1.8" + desc_1_8="Ensure auditing is configured for Docker files and directories - docker.service" + check_1_8="$id_1_8 - $desc_1_8" + starttestjson "$id_1_8" "$desc_1_8" + totalChecks=$((totalChecks + 1)) file="$(get_systemd_service_file docker.service)" if [ -f "$file" ]; then if command -v auditctl >/dev/null 2>&1; then if auditctl -l | grep "$file" >/dev/null 2>&1; then pass "$check_1_8" - logjson "1.8" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_8" - logjson "1.8" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then pass "$check_1_8" - logjson "1.8" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_8" - logjson "1.8" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else info "$check_1_8" info " * File not found" - logjson "1.8" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } # 1.9 check_1_9() { - check_1_9="1.9 - Ensure auditing is configured for Docker files and directories - docker.socket" + id_1_9="1.9" + desc_1_9="Ensure auditing is configured for Docker files and directories - docker.socket" + check_1_9="$id_1_9 - $desc_1_9" + starttestjson "$id_1_9" "$desc_1_9" + totalChecks=$((totalChecks + 1)) file="$(get_systemd_service_file docker.socket)" if [ -e "$file" ]; then if command -v auditctl >/dev/null 2>&1; then if auditctl -l | grep "$file" >/dev/null 2>&1; then pass "$check_1_9" - logjson "1.9" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_9" - logjson "1.9" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then pass "$check_1_9" - logjson "1.9" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_9" - logjson "1.9" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else info "$check_1_9" info " * File not found" - logjson "1.9" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } # 1.10 check_1_10() { - check_1_10="1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker" + id_1_10="1.10" + desc_1_10="Ensure auditing is configured for Docker files and directories - /etc/default/docker" + check_1_10="$id_1_10 - $desc_1_10" + starttestjson "$id_1_10" "$desc_1_10" + totalChecks=$((totalChecks + 1)) file="/etc/default/docker" if [ -f "$file" ]; then if command -v auditctl >/dev/null 2>&1; then if auditctl -l | grep $file >/dev/null 2>&1; then pass "$check_1_10" - logjson "1.10" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_10" - logjson "1.10" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then pass "$check_1_10" - logjson "1.10" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_10" - logjson "1.10" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else info "$check_1_10" info " * File not found" - logjson "1.10" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } # 1.11 check_1_11() { - check_1_11="1.11 - Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json" + id_1_11="1.11" + desc_1_11="Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json" + check_1_11="$id_1_11 - $desc_1_11" + starttestjson "$id_1_11" "$desc_1_11" + totalChecks=$((totalChecks + 1)) file="/etc/docker/daemon.json" if [ -f "$file" ]; then if command -v auditctl >/dev/null 2>&1; then if auditctl -l | grep $file >/dev/null 2>&1; then pass "$check_1_11" - logjson "1.11" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_11" - logjson "1.11" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then pass "$check_1_11" - logjson "1.11" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_11" - logjson "1.11" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else info "$check_1_11" info " * File not found" - logjson "1.11" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } # 1.12 check_1_12() { - check_1_12="1.12 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-containerd" + id_1_12="1.12" + desc_1_12="Ensure auditing is configured for Docker files and directories - /usr/bin/docker-containerd" + check_1_12="$id_1_12 - $desc_1_12" + starttestjson "$id_1_12" "$desc_1_12" + totalChecks=$((totalChecks + 1)) file="/usr/bin/docker-containerd" if [ -f "$file" ]; then if command -v auditctl >/dev/null 2>&1; then if auditctl -l | grep $file >/dev/null 2>&1; then pass "$check_1_12" - logjson "1.12" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_12" - logjson "1.12" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then pass "$check_1_12" - logjson "1.12" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_12" - logjson "1.12" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else info "$check_1_12" info " * File not found" - logjson "1.12" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } # 1.13 check_1_13() { - check_1_13="1.13 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-runc" + id_1_13="1.13" + desc_1_13="Ensure auditing is configured for Docker files and directories - /usr/bin/docker-runc" + check_1_13="$id_1_13 - $desc_1_13" + starttestjson "$id_1_13" "$desc_1_13" + totalChecks=$((totalChecks + 1)) file="/usr/bin/docker-runc" if [ -f "$file" ]; then if command -v auditctl >/dev/null 2>&1; then if auditctl -l | grep $file >/dev/null 2>&1; then pass "$check_1_13" - logjson "1.13" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_13" - logjson "1.13" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then pass "$check_1_13" - logjson "1.13" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_1_13" - logjson "1.13" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else info "$check_1_13" info " * File not found" - logjson "1.13" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } + +check_1_end() { + endsectionjson +} + diff --git a/tests/2_docker_daemon_configuration.sh b/tests/2_docker_daemon_configuration.sh index 230b8e5..5d79a23 100644 --- a/tests/2_docker_daemon_configuration.sh +++ b/tests/2_docker_daemon_configuration.sh @@ -2,262 +2,314 @@ check_2() { logit "\n" - info "2 - Docker daemon configuration" + id_2="2" + desc_2="Docker daemon configuration" + check_2="id_2 - $desc_2" + info "$check_2" + startsectionjson "$id_2" "$desc_2" } # 2.1 check_2_1() { - check_2_1="2.1 - Ensure network traffic is restricted between containers on the default bridge" + id_2_1="2.1" + desc_2_1="Ensure network traffic is restricted between containers on the default bridge" + check_2_1="$id_2_1 - $desc_2_1" + starttestjson "$id_2_1" "$desc_2_1" + totalChecks=$((totalChecks + 1)) if get_docker_effective_command_line_args '--icc' | grep false >/dev/null 2>&1; then pass "$check_2_1" - logjson "2.1" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) elif get_docker_configuration_file_args 'icc' | grep "false" >/dev/null 2>&1; then pass "$check_2_1" - logjson "2.1" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_2_1" - logjson "2.1" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi } # 2.2 check_2_2() { - check_2_2="2.2 - Ensure the logging level is set to 'info'" + id_2_2="2.2" + desc_2_2="Ensure the logging level is set to 'info'" + check_2_2="$id_2_2 - $desc_2_2" + starttestjson "$id_2_2" "$desc_2_2" + totalChecks=$((totalChecks + 1)) if get_docker_configuration_file_args 'log-level' >/dev/null 2>&1; then if get_docker_configuration_file_args 'log-level' | grep info >/dev/null 2>&1; then pass "$check_2_2" - logjson "2.2" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) elif [ -z "$(get_docker_configuration_file_args 'log-level')" ]; then pass "$check_2_2" - logjson "2.2" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_2_2" - logjson "2.2" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif get_docker_effective_command_line_args '-l'; then if get_docker_effective_command_line_args '-l' | grep "info" >/dev/null 2>&1; then pass "$check_2_2" - logjson "2.2" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_2_2" - logjson "2.2" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else pass "$check_2_2" - logjson "2.2" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } # 2.3 check_2_3() { - check_2_3="2.3 - Ensure Docker is allowed to make changes to iptables" + id_2_3="2.3" + desc_2_3="Ensure Docker is allowed to make changes to iptables" + check_2_3="$id_2_3 - $desc_2_3" + starttestjson "$id_2_3" "$desc_2_3" + totalChecks=$((totalChecks + 1)) if get_docker_effective_command_line_args '--iptables' | grep "false" >/dev/null 2>&1; then warn "$check_2_3" - logjson "2.3" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) elif get_docker_configuration_file_args 'iptables' | grep "false" >/dev/null 2>&1; then warn "$check_2_3" - logjson "2.3" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) else pass "$check_2_3" - logjson "2.3" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } # 2.4 check_2_4() { - check_2_4="2.4 - Ensure insecure registries are not used" + id_2_4="2.4" + desc_2_4="Ensure insecure registries are not used" + check_2_4="$id_2_4 - $desc_2_4" + starttestjson "$id_2_4" "$desc_2_4" + totalChecks=$((totalChecks + 1)) if get_docker_effective_command_line_args '--insecure-registry' | grep "insecure-registry" >/dev/null 2>&1; then warn "$check_2_4" - logjson "2.4" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) elif ! [ -z "$(get_docker_configuration_file_args 'insecure-registries')" ]; then if get_docker_configuration_file_args 'insecure-registries' | grep '\[]' >/dev/null 2>&1; then pass "$check_2_4" - logjson "2.4" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_2_4" - logjson "2.4" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else pass "$check_2_4" - logjson "2.4" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } # 2.5 check_2_5() { - check_2_5="2.5 - Ensure aufs storage driver is not used" + id_2_5="2.5" + desc_2_5="Ensure aufs storage driver is not used" + check_2_5="$id_2_5 - $desc_2_5" + starttestjson "$id_2_5" "$desc_2_5" + totalChecks=$((totalChecks + 1)) if docker info 2>/dev/null | grep -e "^Storage Driver:\s*aufs\s*$" >/dev/null 2>&1; then warn "$check_2_5" - logjson "2.5" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) else pass "$check_2_5" - logjson "2.5" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } # 2.6 check_2_6() { - check_2_6="2.6 - Ensure TLS authentication for Docker daemon is configured" + id_2_6="2.6" + desc_2_6="Ensure TLS authentication for Docker daemon is configured" + check_2_6="$id_2_6 - $desc_2_6" + starttestjson "$id_2_6" "$desc_2_6" + totalChecks=$((totalChecks + 1)) if [ grep -i 'tcp://' "$CONFIG_FILE" 2>/dev/null 1>&2 ] || \ [ $(get_docker_cumulative_command_line_args '-H' | grep -vE '(unix|fd)://') >/dev/null 2>&1 ]; then if [ $(get_docker_configuration_file_args '"tlsverify":' | grep 'true') ] || \ [ $(get_docker_cumulative_command_line_args '--tlsverify' | grep 'tlsverify') >/dev/null 2>&1 ]; then pass "$check_2_6" - logjson "2.6" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) elif [ $(get_docker_configuration_file_args '"tls":' | grep 'true') ] || \ [ $(get_docker_cumulative_command_line_args '--tls' | grep 'tls$') >/dev/null 2>&1 ]; then warn "$check_2_6" warn " * Docker daemon currently listening on TCP with TLS, but no verification" - logjson "2.6" "WARN" + resulttestjson "WARN" "Docker daemon currently listening on TCP with TLS, but no verification" currentScore=$((currentScore - 1)) else warn "$check_2_6" warn " * Docker daemon currently listening on TCP without TLS" - logjson "2.6" "WARN" + resulttestjson "WARN" "Docker daemon currently listening on TCP without TLS" currentScore=$((currentScore - 1)) fi else info "$check_2_6" info " * Docker daemon not listening on TCP" - logjson "2.6" "INFO" + resulttestjson "INFO" "Docker daemon not listening on TCP" currentScore=$((currentScore + 0)) fi } # 2.7 check_2_7() { - check_2_7="2.7 - Ensure the default ulimit is configured appropriately" + id_2_7="2.7" + desc_2_7="Ensure the default ulimit is configured appropriately" + check_2_7="$id_2_7 - $desc_2_7" + starttestjson "$id_2_7" "$desc_2_7" + totalChecks=$((totalChecks + 1)) if get_docker_configuration_file_args 'default-ulimit' | grep -v '{}' >/dev/null 2>&1; then pass "$check_2_7" - logjson "2.7" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) elif get_docker_effective_command_line_args '--default-ulimit' | grep "default-ulimit" >/dev/null 2>&1; then pass "$check_2_7" - logjson "2.7" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else info "$check_2_7" info " * Default ulimit doesn't appear to be set" - logjson "2.7" "INFO" + resulttestjson "INFO" "Default ulimit doesn't appear to be set" currentScore=$((currentScore + 0)) fi } # 2.8 check_2_8() { - check_2_8="2.8 - Enable user namespace support" + id_2_8="2.8" + desc_2_8="Enable user namespace support" + check_2_8="$id_2_8 - $desc_2_8" + starttestjson "$id_2_8" "$desc_2_8" + totalChecks=$((totalChecks + 1)) if get_docker_configuration_file_args 'userns-remap' | grep -v '""'; then pass "$check_2_8" - logjson "2.8" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) elif get_docker_effective_command_line_args '--userns-remap' | grep "userns-remap" >/dev/null 2>&1; then pass "$check_2_8" - logjson "2.8" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_2_8" - logjson "2.8" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi } # 2.9 check_2_9() { - check_2_9="2.9 - Ensure the default cgroup usage has been confirmed" + id_2_9="2.9" + desc_2_9="Ensure the default cgroup usage has been confirmed" + check_2_9="$id_2_9 - $desc_2_9" + starttestjson "$id_2_9" "$desc_2_9" + totalChecks=$((totalChecks + 1)) if get_docker_configuration_file_args 'cgroup-parent' | grep -v '""'; then warn "$check_2_9" info " * Confirm cgroup usage" - logjson "2.9" "INFO" + resulttestjson "WARN" "Confirm cgroup usage" currentScore=$((currentScore + 0)) elif get_docker_effective_command_line_args '--cgroup-parent' | grep "cgroup-parent" >/dev/null 2>&1; then warn "$check_2_9" info " * Confirm cgroup usage" - logjson "2.9" "INFO" + resulttestjson "WARN" "Confirm cgroup usage" currentScore=$((currentScore + 0)) else pass "$check_2_9" - logjson "2.9" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } # 2.10 check_2_10() { - check_2_10="2.10 - Ensure base device size is not changed until needed" + id_2_10="2.10" + desc_2_10="Ensure base device size is not changed until needed" + check_2_10="$id_2_10 - $desc_2_10" + starttestjson "$id_2_10" "$desc_2_10" + totalChecks=$((totalChecks + 1)) if get_docker_configuration_file_args 'storage-opts' | grep "dm.basesize" >/dev/null 2>&1; then warn "$check_2_10" - logjson "2.10" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) elif get_docker_effective_command_line_args '--storage-opt' | grep "dm.basesize" >/dev/null 2>&1; then warn "$check_2_10" - logjson "2.10" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) else pass "$check_2_10" - logjson "2.10" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } # 2.11 check_2_11() { - check_2_11="2.11 - Ensure that authorization for Docker client commands is enabled" + id_2_11="2.11" + desc_2_11="Ensure that authorization for Docker client commands is enabled" + check_2_11="$id_2_11 - $desc_2_11" + starttestjson "$id_2_11" "$desc_2_11" + totalChecks=$((totalChecks + 1)) if get_docker_configuration_file_args 'authorization-plugins' | grep -v '\[]'; then pass "$check_2_11" - logjson "2.11" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) elif get_docker_effective_command_line_args '--authorization-plugin' | grep "authorization-plugin" >/dev/null 2>&1; then pass "$check_2_11" - logjson "2.11" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_2_11" - logjson "2.11" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi } # 2.12 check_2_12() { - check_2_12="2.12 - Ensure centralized and remote logging is configured" + id_2_12="2.12" + desc_2_12="Ensure centralized and remote logging is configured" + check_2_12="$id_2_12 - $desc_2_12" + starttestjson "$id_2_12" "$desc_2_12" + totalChecks=$((totalChecks + 1)) if docker info --format '{{ .LoggingDriver }}' | grep 'json-file' >/dev/null 2>&1; then warn "$check_2_12" - logjson "2.12" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) else pass "$check_2_12" - logjson "2.12" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } @@ -267,48 +319,58 @@ check_2_13() { docker_version=$(docker version | grep -i -A2 '^server' | grep ' Version:' \ | awk '{print $NF; exit}' | tr -d '[:alpha:]-,.') totalChecks=$((totalChecks + 1)) + + id_2_13="2.13" + desc_2_13="Ensure operations on legacy registry (v1) are Disabled" + check_2_13="$id_2_13 - $desc_2_13" + starttestjson "$id_2_13" "$desc_2_13" + if [ "$docker_version" -lt 1712 ]; then - check_2_13="2.13 - Ensure operations on legacy registry (v1) are Disabled" if get_docker_configuration_file_args 'disable-legacy-registry' | grep 'true' >/dev/null 2>&1; then pass "$check_2_13" - logjson "2.13" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) elif get_docker_effective_command_line_args '--disable-legacy-registry' | grep "disable-legacy-registry" >/dev/null 2>&1; then pass "$check_2_13" - logjson "2.13" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_2_13" - logjson "2.13" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else - check_2_13="2.13 - Ensure operations on legacy registry (v1) are Disabled (Deprecated)" + desc_2_13="$desc_2_13 (Deprecated)" + check_2_13="$id_2_13 - $desc_2_13" info "$check_2_13" - logjson "2.13" "info" + resulttestjson "INFO" fi } # 2.14 check_2_14() { - check_2_14="2.14 - Ensure live restore is Enabled" + id_2_14="2.14" + desc_2_14="Ensure live restore is Enabled" + check_2_14="$id_2_14 - $desc_2_14" + starttestjson "$id_2_14" "$desc_2_14" + totalChecks=$((totalChecks + 1)) if docker info 2>/dev/null | grep -e "Live Restore Enabled:\s*true\s*" >/dev/null 2>&1; then pass "$check_2_14" - logjson "2.14" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else if docker info 2>/dev/null | grep -e "Swarm:*\sactive\s*" >/dev/null 2>&1; then pass "$check_2_14 (Incompatible with swarm mode)" - logjson "2.14" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) elif get_docker_effective_command_line_args '--live-restore' | grep "live-restore" >/dev/null 2>&1; then pass "$check_2_14" - logjson "2.14" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_2_14" - logjson "2.14" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi fi @@ -316,68 +378,88 @@ check_2_14() { # 2.15 check_2_15() { - check_2_15="2.15 - Ensure Userland Proxy is Disabled" + id_2_15="2.15" + desc_2_15="Ensure Userland Proxy is Disabled" + check_2_15="$id_2_15 - $desc_2_15" + starttestjson "$id_2_15" "$desc_2_15" + totalChecks=$((totalChecks + 1)) if get_docker_configuration_file_args 'userland-proxy' | grep false >/dev/null 2>&1; then pass "$check_2_15" - logjson "2.15" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) elif get_docker_effective_command_line_args '--userland-proxy=false' 2>/dev/null | grep "userland-proxy=false" >/dev/null 2>&1; then pass "$check_2_15" - logjson "2.15" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_2_15" - logjson "2.15" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi } # 2.16 check_2_16() { - check_2_16="2.16 - Ensure daemon-wide custom seccomp profile is applied, if needed" + id_2_16="2.16" + desc_2_16="Ensure daemon-wide custom seccomp profile is applied, if needed" + check_2_16="$id_2_16 - $desc_2_16" + starttestjson "$id_2_16" "$desc_2_16" + totalChecks=$((totalChecks + 1)) if docker info --format '{{ .SecurityOptions }}' | grep 'name=seccomp,profile=default' 2>/dev/null 1>&2; then pass "$check_2_16" - logjson "2.16" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else info "$check_2_16" - logjson "2.16" "INFO" + resulttestjson "INFO" currentScore=$((currentScore + 0)) fi } # 2.17 check_2_17() { - check_2_17="2.17 - Ensure experimental features are avoided in production" + id_2_17="2.17" + desc_2_17="Ensure experimental features are avoided in production" + check_2_17="$id_2_17 - $desc_2_17" + starttestjson "$id_2_17" "$desc_2_17" + totalChecks=$((totalChecks + 1)) if docker version -f '{{.Server.Experimental}}' | grep false 2>/dev/null 1>&2; then pass "$check_2_17" - logjson "2.17" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_2_17" - logjson "2.17" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi } # 2.18 check_2_18() { - check_2_18="2.18 - Ensure containers are restricted from acquiring new privileges" + id_2_18="2.18" + desc_2_18="Ensure containers are restricted from acquiring new privileges" + check_2_18="$id_2_18 - $desc_2_18" + starttestjson "$id_2_18" "$desc_2_18" + totalChecks=$((totalChecks + 1)) if get_docker_effective_command_line_args '--no-new-privileges' | grep "no-new-privileges" >/dev/null 2>&1; then pass "$check_2_18" - logjson "2.18" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) elif get_docker_configuration_file_args 'no-new-privileges' | grep true >/dev/null 2>&1; then pass "$check_2_18" - logjson "2.18" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_2_18" - logjson "2.18" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi } + +check_2_end() { + endsectionjson +} diff --git a/tests/3_docker_daemon_configuration_files.sh b/tests/3_docker_daemon_configuration_files.sh index ddfd9c4..6481b0d 100644 --- a/tests/3_docker_daemon_configuration_files.sh +++ b/tests/3_docker_daemon_configuration_files.sh @@ -2,156 +2,188 @@ check_3() { logit "\n" - info "3 - Docker daemon configuration files" + id_3="3" + desc_3="Docker daemon configuration files" + check_3="$id_3 - $desc_3" + info "$check_3" + startsectionjson "$id_3" "$desc_3" } # 3.1 check_3_1() { - check_3_1="3.1 - Ensure that docker.service file ownership is set to root:root" + id_3_1="3.1" + desc_3_1="Ensure that docker.service file ownership is set to root:root" + check_3_1="$id_3_1 - $desc_3_1" + starttestjson "$id_3_1" "$desc_3_1" + totalChecks=$((totalChecks + 1)) file="$(get_systemd_service_file docker.service)" if [ -f "$file" ]; then if [ "$(stat -c %u%g $file)" -eq 00 ]; then pass "$check_3_1" - logjson "3.1" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_1" warn " * Wrong ownership for $file" - logjson "3.1" "WARN" + resulttestjson "WARN" "Wrong ownership for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_1" info " * File not found" - logjson "3.1" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } # 3.2 check_3_2() { - check_3_2="3.2 - Ensure that docker.service file permissions are set to 644 or more restrictive" + id_3_2="3.2" + desc_3_2="Ensure that docker.service file permissions are set to 644 or more restrictive" + check_3_2="$id_3_2 - $desc_3_2" + starttestjson "$id_3_2" "$desc_3_2" + totalChecks=$((totalChecks + 1)) file="$(get_systemd_service_file docker.service)" if [ -f "$file" ]; then if [ "$(stat -c %a $file)" -eq 644 -o "$(stat -c %a $file)" -eq 600 ]; then pass "$check_3_2" - logjson "3.2" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_2" warn " * Wrong permissions for $file" - logjson "3.2" "WARN" + resulttestjson "WARN" "Wrong permissions for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_2" info " * File not found" - logjson "3.2" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } # 3.3 check_3_3() { - check_3_3="3.3 - Ensure that docker.socket file ownership is set to root:root" + id_3_3="3.3" + desc_3_3="Ensure that docker.socket file ownership is set to root:root" + check_3_3="$id_3_3 - $desc_3_3" + starttestjson "$id_3_3" "$desc_3_3" + totalChecks=$((totalChecks + 1)) file="$(get_systemd_service_file docker.socket)" if [ -f "$file" ]; then if [ "$(stat -c %u%g $file)" -eq 00 ]; then pass "$check_3_3" - logjson "3.3" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_3" warn " * Wrong ownership for $file" - logjson "3.3" "WARN" + resulttestjson "WARN" "Wrong ownership for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_3" info " * File not found" - logjson "3.3" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } # 3.4 check_3_4() { - check_3_4="3.4 - Ensure that docker.socket file permissions are set to 644 or more restrictive" + id_3_4="3.4" + desc_3_4="Ensure that docker.socket file permissions are set to 644 or more restrictive" + check_3_4="$id_3_4 - $desc_3_4" + starttestjson "$id_3_4" "$desc_3_4" + totalChecks=$((totalChecks + 1)) file="$(get_systemd_service_file docker.socket)" if [ -f "$file" ]; then if [ "$(stat -c %a $file)" -eq 644 -o "$(stat -c %a $file)" -eq 600 ]; then pass "$check_3_4" - logjson "3.4" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_4" warn " * Wrong permissions for $file" - logjson "3.4" "WARN" + resulttestjson "WARN" "Wrong permissions for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_4" info " * File not found" - logjson "3.4" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } # 3.5 check_3_5() { - check_3_5="3.5 - Ensure that /etc/docker directory ownership is set to root:root" + id_3_5="3.5" + desc_3_5="Ensure that /etc/docker directory ownership is set to root:root" + check_3_5="$id_3_5 - $desc_3_5" + starttestjson "$id_3_5" "$desc_3_5" + totalChecks=$((totalChecks + 1)) directory="/etc/docker" if [ -d "$directory" ]; then if [ "$(stat -c %u%g $directory)" -eq 00 ]; then pass "$check_3_5" - logjson "3.5" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_5" warn " * Wrong ownership for $directory" - logjson "3.5" "WARN" + resulttestjson "WARN" "Wrong ownership for $directory" currentScore=$((currentScore - 1)) fi else info "$check_3_5" info " * Directory not found" - logjson "3.5" "INFO" + resulttestjson "INFO" "Directory not found" currentScore=$((currentScore + 0)) fi } # 3.6 check_3_6() { - check_3_6="3.6 - Ensure that /etc/docker directory permissions are set to 755 or more restrictive" + id_3_6="3.6" + desc_3_6="Ensure that /etc/docker directory permissions are set to 755 or more restrictive" + check_3_6="$id_3_6 - $desc_3_6" + starttestjson "$id_3_6" "$desc_3_6" + totalChecks=$((totalChecks + 1)) directory="/etc/docker" if [ -d "$directory" ]; then if [ "$(stat -c %a $directory)" -eq 755 -o "$(stat -c %a $directory)" -eq 700 ]; then pass "$check_3_6" - logjson "3.6" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_6" warn " * Wrong permissions for $directory" - logjson "3.6" "WARN" + resulttestjson "WARN" "Wrong permissions for $directory" currentScore=$((currentScore - 1)) fi else info "$check_3_6" info " * Directory not found" - logjson "3.6" "INFO" + resulttestjson "INFO" "Directory not found" currentScore=$((currentScore + 0)) fi } # 3.7 check_3_7() { - check_3_7="3.7 - Ensure that registry certificate file ownership is set to root:root" + id_3_7="3.7" + desc_3_7="Ensure that registry certificate file ownership is set to root:root" + check_3_7="$id_3_7 - $desc_3_7" + starttestjson "$id_3_7" "$desc_3_7" + totalChecks=$((totalChecks + 1)) directory="/etc/docker/certs.d/" if [ -d "$directory" ]; then @@ -165,24 +197,28 @@ check_3_7() { if [ $fail -eq 1 ]; then warn "$check_3_7" warn " * Wrong ownership for $directory" - logjson "3.7" "WARN" + resulttestjson "WARN" "Wrong ownership for $directory" currentScore=$((currentScore - 1)) else pass "$check_3_7" - logjson "3.7" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi else info "$check_3_7" info " * Directory not found" - logjson "3.7" "INFO" + resulttestjson "INFO" "Directory not found" currentScore=$((currentScore + 0)) fi } # 3.8 check_3_8() { - check_3_8="3.8 - Ensure that registry certificate file permissions are set to 444 or more restrictive" + id_3_8="3.8" + desc_3_8="Ensure that registry certificate file permissions are set to 444 or more restrictive" + check_3_8="$id_3_8 - $desc_3_8" + starttestjson "$id_3_8" "$desc_3_8" + totalChecks=$((totalChecks + 1)) directory="/etc/docker/certs.d/" if [ -d "$directory" ]; then @@ -196,24 +232,28 @@ check_3_8() { if [ $fail -eq 1 ]; then warn "$check_3_8" warn " * Wrong permissions for $directory" - logjson "3.8" "WARN" + resulttestjson "WARN" "Wrong permissions for $directory" currentScore=$((currentScore - 1)) else pass "$check_3_8" - logjson "3.8" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi else info "$check_3_8" info " * Directory not found" - logjson "3.8" "INFO" + resulttestjson "INFO" "Directory not found" currentScore=$((currentScore + 0)) fi } # 3.9 check_3_9() { - check_3_9="3.9 - Ensure that TLS CA certificate file ownership is set to root:root" + id_3_9="3.9" + desc_3_9="Ensure that TLS CA certificate file ownership is set to root:root" + check_3_9="$id_3_9 - $desc_3_9" + starttestjson "$id_3_9" "$desc_3_9" + totalChecks=$((totalChecks + 1)) if ! [ -z $(get_docker_configuration_file_args 'tlscacert') ]; then tlscacert=$(get_docker_configuration_file_args 'tlscacert') @@ -223,25 +263,29 @@ check_3_9() { if [ -f "$tlscacert" ]; then if [ "$(stat -c %u%g "$tlscacert")" -eq 00 ]; then pass "$check_3_9" - logjson "3.9" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_9" warn " * Wrong ownership for $tlscacert" - logjson "3.9" "WARN" + resulttestjson "WARN" "Wrong ownership for $tlscacert" currentScore=$((currentScore - 1)) fi else info "$check_3_9" info " * No TLS CA certificate found" - logjson "3.9" "INFO" + resulttestjson "INFO" "No TLS CA certificate found" currentScore=$((currentScore + 0)) fi } # 3.10 check_3_10() { - check_3_10="3.10 - Ensure that TLS CA certificate file permissions are set to 444 or more restrictive" + id_3_10="3.10" + desc_3_10="Ensure that TLS CA certificate file permissions are set to 444 or more restrictive" + check_3_10="$id_3_10 - $desc_3_10" + starttestjson "$id_3_10" "$desc_3_10" + totalChecks=$((totalChecks + 1)) if ! [ -z $(get_docker_configuration_file_args 'tlscacert') ]; then tlscacert=$(get_docker_configuration_file_args 'tlscacert') @@ -251,25 +295,29 @@ check_3_10() { if [ -f "$tlscacert" ]; then if [ "$(stat -c %a $tlscacert)" -eq 444 -o "$(stat -c %a $tlscacert)" -eq 400 ]; then pass "$check_3_10" - logjson "3.10" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_10" warn " * Wrong permissions for $tlscacert" - logjson "3.10" "WARN" + resulttestjson "WARN" "Wrong permissions for $tlscacert" currentScore=$((currentScore - 1)) fi else info "$check_3_10" info " * No TLS CA certificate found" - logjson "3.10" "INFO" + resulttestjson "INFO" "No TLS CA certificate found" currentScore=$((currentScore + 0)) fi } # 3.11 check_3_11() { - check_3_11="3.11 - Ensure that Docker server certificate file ownership is set to root:root" + id_3_11="3.11" + desc_3_11="Ensure that Docker server certificate file ownership is set to root:root" + check_3_11="$id_3_11 - $desc_3_11" + starttestjson "$id_3_11" "$desc_3_11" + totalChecks=$((totalChecks + 1)) if ! [ -z $(get_docker_configuration_file_args 'tlscert') ]; then tlscert=$(get_docker_configuration_file_args 'tlscert') @@ -279,25 +327,29 @@ check_3_11() { if [ -f "$tlscert" ]; then if [ "$(stat -c %u%g "$tlscert")" -eq 00 ]; then pass "$check_3_11" - logjson "3.11" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_11" warn " * Wrong ownership for $tlscert" - logjson "3.11" "WARN" + resulttestjson "WARN" "Wrong ownership for $tlscert" currentScore=$((currentScore - 1)) fi else info "$check_3_11" info " * No TLS Server certificate found" - logjson "3.11" "INFO" + resulttestjson "INFO" "No TLS Server certificate found" currentScore=$((currentScore + 0)) fi } # 3.12 check_3_12() { - check_3_12="3.12 - Ensure that Docker server certificate file permissions are set to 444 or more restrictive" + id_3_12="3.12" + desc_3_12="Ensure that Docker server certificate file permissions are set to 444 or more restrictive" + check_3_12="$id_3_12 - $desc_3_12" + starttestjson "$id_3_12" "$desc_3_12" + totalChecks=$((totalChecks + 1)) if ! [ -z $(get_docker_configuration_file_args 'tlscert') ]; then tlscert=$(get_docker_configuration_file_args 'tlscert') @@ -307,25 +359,29 @@ check_3_12() { if [ -f "$tlscert" ]; then if [ "$(stat -c %a $tlscert)" -eq 444 -o "$(stat -c %a $tlscert)" -eq 400 ]; then pass "$check_3_12" - logjson "3.12" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_12" warn " * Wrong permissions for $tlscert" - logjson "3.12" "WARN" + resulttestjson "WARN" "Wrong permissions for $tlscert" currentScore=$((currentScore - 1)) fi else info "$check_3_12" info " * No TLS Server certificate found" - logjson "3.12" "INFO" + resulttestjson "INFO" "No TLS Server certificate found" currentScore=$((currentScore + 0)) fi } # 3.13 check_3_13() { - check_3_13="3.13 - Ensure that Docker server certificate key file ownership is set to root:root" + id_3_13="3.13" + desc_3_13="Ensure that Docker server certificate key file ownership is set to root:root" + check_3_13="$id_3_13 - $desc_3_13" + starttestjson "$id_3_13" "$desc_3_13" + totalChecks=$((totalChecks + 1)) if ! [ -z $(get_docker_configuration_file_args 'tlskey') ]; then tlskey=$(get_docker_configuration_file_args 'tlskey') @@ -335,25 +391,29 @@ check_3_13() { if [ -f "$tlskey" ]; then if [ "$(stat -c %u%g "$tlskey")" -eq 00 ]; then pass "$check_3_13" - logjson "3.13" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_13" warn " * Wrong ownership for $tlskey" - logjson "3.13" "WARN" + resulttestjson "WARN" "Wrong ownership for $tlskey" currentScore=$((currentScore - 1)) fi else info "$check_3_13" info " * No TLS Key found" - logjson "3.13" "INFO" + resulttestjson "INFO" "No TLS Key found" currentScore=$((currentScore + 0)) fi } # 3.14 check_3_14() { - check_3_14="3.14 - Ensure that Docker server certificate key file permissions are set to 400" + id_3_14="3.14" + desc_3_14="Ensure that Docker server certificate key file permissions are set to 400" + check_3_14="$id_3_14 - $desc_3_14" + starttestjson "$id_3_14" "$desc_3_14" + totalChecks=$((totalChecks + 1)) if ! [ -z $(get_docker_configuration_file_args 'tlskey') ]; then tlskey=$(get_docker_configuration_file_args 'tlskey') @@ -363,162 +423,190 @@ check_3_14() { if [ -f "$tlskey" ]; then if [ "$(stat -c %a $tlskey)" -eq 400 ]; then pass "$check_3_14" - logjson "3.14" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_14" warn " * Wrong permissions for $tlskey" - logjson "3.14" "WARN" + resulttestjson "WARN" "Wrong permissions for $tlskey" currentScore=$((currentScore - 1)) fi else info "$check_3_14" info " * No TLS Key found" - logjson "3.14" "INFO" + resulttestjson "INFO" "No TLS Key found" currentScore=$((currentScore + 0)) fi } # 3.15 check_3_15() { - check_3_15="3.15 - Ensure that Docker socket file ownership is set to root:docker" + id_3_15="3.15" + desc_3_15="Ensure that Docker socket file ownership is set to root:docker" + check_3_15="$id_3_15 - $desc_3_15" + starttestjson "$id_3_15" "$desc_3_15" + totalChecks=$((totalChecks + 1)) file="/var/run/docker.sock" if [ -S "$file" ]; then if [ "$(stat -c %U:%G $file)" = 'root:docker' ]; then pass "$check_3_15" - logjson "3.15" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_15" warn " * Wrong ownership for $file" - logjson "3.15" "WARN" + resulttestjson "WARN" "Wrong ownership for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_15" info " * File not found" - logjson "3.15" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } # 3.16 check_3_16() { - check_3_16="3.16 - Ensure that Docker socket file permissions are set to 660 or more restrictive" + id_3_16="3.16" + desc_3_16="Ensure that Docker socket file permissions are set to 660 or more restrictive" + check_3_16="$id_3_16 - $desc_3_16" + starttestjson "$id_3_16" "$desc_3_16" + totalChecks=$((totalChecks + 1)) file="/var/run/docker.sock" if [ -S "$file" ]; then if [ "$(stat -c %a $file)" -eq 660 -o "$(stat -c %a $file)" -eq 600 ]; then pass "$check_3_16" - logjson "3.16" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_16" warn " * Wrong permissions for $file" - logjson "3.16" "WARN" + resulttestjson "WARN" "Wrong permissions for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_16" info " * File not found" - logjson "3.16" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } # 3.17 check_3_17() { - check_3_17="3.17 - Ensure that daemon.json file ownership is set to root:root" + id_3_17="3.17" + desc_3_17="Ensure that daemon.json file ownership is set to root:root" + check_3_17="$id_3_17 - $desc_3_17" + starttestjson "$id_3_17" "$desc_3_17" + totalChecks=$((totalChecks + 1)) file="/etc/docker/daemon.json" if [ -f "$file" ]; then if [ "$(stat -c %U:%G $file)" = 'root:root' ]; then pass "$check_3_17" - logjson "3.17" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_17" warn " * Wrong ownership for $file" - logjson "3.17" "WARN" + resulttestjson "WARN" "Wrong ownership for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_17" info " * File not found" - logjson "3.17" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } # 3.18 check_3_18() { - check_3_18="3.18 - Ensure that daemon.json file permissions are set to 644 or more restrictive" + id_3_18="3.18" + desc_3_18="Ensure that daemon.json file permissions are set to 644 or more restrictive" + check_3_18="$id_3_18 - $desc_3_18" + starttestjson "$id_3_18" "$desc_3_18" + totalChecks=$((totalChecks + 1)) file="/etc/docker/daemon.json" if [ -f "$file" ]; then if [ "$(stat -c %a $file)" -eq 644 -o "$(stat -c %a $file)" -eq 640 -o "$(stat -c %a $file)" -eq 600 ]; then pass "$check_3_18" - logjson "3.18" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_18" warn " * Wrong permissions for $file" - logjson "3.18" "WARN" + resulttestjson "WARN" "Wrong permissions for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_18" info " * File not found" - logjson "3.18" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } # 3.19 check_3_19() { - check_3_19="3.19 - Ensure that /etc/default/docker file ownership is set to root:root" + id_3_19="3.19" + desc_3_19="Ensure that /etc/default/docker file ownership is set to root:root" + check_3_19="$id_3_19 - $desc_3_19" + starttestjson "$id_3_19" "$desc_3_19" + totalChecks=$((totalChecks + 1)) file="/etc/default/docker" if [ -f "$file" ]; then if [ "$(stat -c %U:%G $file)" = 'root:root' ]; then pass "$check_3_19" - logjson "3.19" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_19" warn " * Wrong ownership for $file" - logjson "3.19" "WARN" + resulttestjson "WARN" "Wrong ownership for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_19" info " * File not found" - logjson "3.19" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } # 3.20 check_3_20() { - check_3_20="3.20 - Ensure that /etc/default/docker file permissions are set to 644 or more restrictive" + id_3_20="3.20" + desc_3_20="Ensure that /etc/default/docker file permissions are set to 644 or more restrictive" + check_3_20="$id_3_20 - $desc_3_20" + starttestjson "$id_3_20" "$desc_3_20" + totalChecks=$((totalChecks + 1)) file="/etc/default/docker" if [ -f "$file" ]; then if [ "$(stat -c %a $file)" -eq 644 -o "$(stat -c %a $file)" -eq 600 ]; then pass "$check_3_20" - logjson "3.20" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_20" warn " * Wrong permissions for $file" - logjson "3.20" "WARN" + resulttestjson "WARN" "Wrong permissions for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_20" info " * File not found" - logjson "3.20" "INFO" + resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } + +check_3_end() { + endsectionjson +} diff --git a/tests/4_container_images.sh b/tests/4_container_images.sh index 10e02a5..cc227db 100644 --- a/tests/4_container_images.sh +++ b/tests/4_container_images.sh @@ -4,19 +4,27 @@ images=$(docker images -q) check_4() { logit "\n" - info "4 - Container Images and Build File" + id_4="4" + desc_4="Container Images and Build File" + check_4="$id_4 - $desc_4" + info "$check_4" + startsectionjson "$id_4" "$desc_4" } # 4.1 check_4_1() { - check_4_1="4.1 - Ensure a user for the container has been created" + id_4_1="4.1" + desc_4_1="Ensure a user for the container has been created" + check_4_1="$id_4_1 - $desc_4_1" + starttestjson "$id_4_1" "$desc_4_1" + totalChecks=$((totalChecks + 1)) # If container_users is empty, there are no running containers if [ -z "$containers" ]; then info "$check_4_1" info " * No containers running" - logjson "4.1" "INFO" + resulttestjson "INFO" "No containers running" currentScore=$((currentScore + 0)) else # We have some containers running, set failure flag to 0. Check for Users. @@ -24,6 +32,7 @@ check_4_1() { # Make the loop separator be a new-line in POSIX compliant fashion set -f; IFS=$' ' + root_containers="" for c in $containers; do user=$(docker inspect --format 'User={{.Config.User}}' "$c") @@ -32,20 +41,21 @@ check_4_1() { if [ $fail -eq 0 ]; then warn "$check_4_1" warn " * Running as root: $c" - logjson "4.1" "WARN: $c" + root_containers="$root_containers $c" fail=1 else warn " * Running as root: $c" - logjson "4.1" "WARN: $c" + root_containers="$root_containers $c" fi fi done # We went through all the containers and found none running as root if [ $fail -eq 0 ]; then pass "$check_4_1" - logjson "4.1" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "running as root" "$root_containers" currentScore=$((currentScore - 1)) fi fi @@ -55,152 +65,201 @@ check_4_1() { # 4.2 check_4_2() { - check_4_2="4.2 - Ensure that containers use trusted base images" + id_4_2="4.2" + desc_4_2="Ensure that containers use trusted base images" + check_4_2="$id_4_2 - $desc_4_2" + starttestjson "$id_4_2" "$desc_4_2" + totalChecks=$((totalChecks + 1)) note "$check_4_2" - logjson "4.2" "NOTE" + resulttestjson "NOTE" currentScore=$((currentScore + 0)) } # 4.3 check_4_3() { - check_4_3="4.3 - Ensure unnecessary packages are not installed in the container" + id_4_3="4.3" + desc_4_3="Ensure unnecessary packages are not installed in the container" + check_4_3="$id_4_3 - $desc_4_3" + starttestjson "$id_4_3" "$desc_4_3" + totalChecks=$((totalChecks + 1)) note "$check_4_3" - logjson "4.3" "NOTE" + resulttestjson "NOTE" currentScore=$((currentScore + 0)) } # 4.4 check_4_4() { - check_4_4="4.4 - Ensure images are scanned and rebuilt to include security patches" + id_4_4="4.4" + desc_4_4="Ensure images are scanned and rebuilt to include security patches" + check_4_4="$id_4_4 - $desc_4_4" + starttestjson "$id_4_4" "$desc_4_4" + totalChecks=$((totalChecks + 1)) note "$check_4_4" - logjson "4.4" "NOTE" + resulttestjson "NOTE" currentScore=$((currentScore + 0)) } # 4.5 check_4_5() { - check_4_5="4.5 - Ensure Content trust for Docker is Enabled" + id_4_5="4.5" + desc_4_5="Ensure Content trust for Docker is Enabled" + check_4_5="$id_4_5 - $desc_4_5" + starttestjson "$id_4_5" "$desc_4_5" + totalChecks=$((totalChecks + 1)) if [ "x$DOCKER_CONTENT_TRUST" = "x1" ]; then pass "$check_4_5" - logjson "4.5" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_4_5" - logjson "4.5" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi } # 4.6 check_4_6() { - check_4_6="4.6 - Ensure HEALTHCHECK instructions have been added to the container image" + id_4_6="4.6" + desc_4_6="Ensure HEALTHCHECK instructions have been added to the container image" + check_4_6="$id_4_6 - $desc_4_6" + starttestjson "$id_4_6" "$desc_4_6" + totalChecks=$((totalChecks + 1)) fail=0 + no_health_images="" for img in $images; do if docker inspect --format='{{.Config.Healthcheck}}' "$img" 2>/dev/null | grep -e "" >/dev/null 2>&1; then if [ $fail -eq 0 ]; then fail=1 warn "$check_4_6" - logjson "4.6" "WARN" fi imgName=$(docker inspect --format='{{.RepoTags}}' "$img" 2>/dev/null) if ! [ "$imgName" = '[]' ]; then warn " * No Healthcheck found: $imgName" - logjson "4.6" "WARN: $imgName" + no_health_images="$no_health_images $imgName" fi fi done if [ $fail -eq 0 ]; then pass "$check_4_6" - logjson "4.6" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Images w/o HEALTHCHECK" "$no_health_images" currentScore=$((currentScore - 1)) fi } # 4.7 check_4_7() { - check_4_7="4.7 - Ensure update instructions are not use alone in the Dockerfile" + id_4_7="4.7" + desc_4_7="Ensure update instructions are not use alone in the Dockerfile" + check_4_7="$id_4_7 - $desc_4_7" + starttestjson "$id_4_7" "$desc_4_7" + totalChecks=$((totalChecks + 1)) fail=0 + update_images="" for img in $images; do if docker history "$img" 2>/dev/null | grep -e "update" >/dev/null 2>&1; then if [ $fail -eq 0 ]; then fail=1 info "$check_4_7" - logjson "4.7" "INFO" fi imgName=$(docker inspect --format='{{.RepoTags}}' "$img" 2>/dev/null) if ! [ "$imgName" = '[]' ]; then info " * Update instruction found: $imgName" + update_images="$update_images $imgName" fi fi done if [ $fail -eq 0 ]; then pass "$check_4_7" - logjson "4.7" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 0)) else + resulttestjson "INFO" "Update instructions found" "$update_images" currentScore=$((currentScore + 0)) fi } # 4.8 check_4_8() { - check_4_8="4.8 - Ensure setuid and setgid permissions are removed in the images" + id_4_8="4.8" + desc_4_8="Ensure setuid and setgid permissions are removed in the images" + check_4_8="$id_4_8 - $desc_4_8" + starttestjson "$id_4_8" "$desc_4_8" + totalChecks=$((totalChecks + 1)) note "$check_4_8" - logjson "4.8" "NOTE" + resulttestjson "NOTE" currentScore=$((currentScore + 0)) } # 4.9 check_4_9() { - check_4_9="4.9 - Ensure COPY is used instead of ADD in Dockerfile" + id_4_9="4.9" + desc_4_9="Ensure COPY is used instead of ADD in Dockerfile" + check_4_9="$id_4_9 - $desc_4_9" + starttestjson "$id_4_9" "$desc_4_9" + totalChecks=$((totalChecks + 1)) fail=0 + add_images="" for img in $images; do docker history "$img" 2> /dev/null | grep 'ADD' >/dev/null 2>&1 if [ $? -eq 0 ]; then if [ $fail -eq 0 ]; then fail=1 info "$check_4_9" - logjson "4.9" "INFO" fi imgName=$(docker inspect --format='{{.RepoTags}}' "$img" 2>/dev/null) if ! [ "$imgName" = '[]' ]; then info " * ADD in image history: $imgName" - logjson "4.9" "INFO: $imgName" + add_images="$add_images $imgName" fi currentScore=$((currentScore + 0)) fi done if [ $fail -eq 0 ]; then pass "$check_4_9" - logjson "4.9" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) + else + resulttestjson "WARN" "Images using ADD" "$add_images" fi } # 4.10 check_4_10() { - check_4_10="4.10 - Ensure secrets are not stored in Dockerfiles" + id_4_10="4.10" + desc_4_10="Ensure secrets are not stored in Dockerfiles" + check_4_10="$id_4_10 - $desc_4_10" + starttestjson "$id_4_10" "$desc_4_10" + totalChecks=$((totalChecks + 1)) note "$check_4_10" - logjson "4.10" "NOTE" + resulttestjson "NOTE" currentScore=$((currentScore + 0)) } # 4.11 check_4_11() { - check_4_11="4.11 - Ensure verified packages are only Installed" + id_4_11="4.11" + desc_4_11="Ensure verified packages are only Installed" + check_4_11="$id_4_11 - $desc_4_11" + starttestjson "$id_4_11" "$desc_4_11" + totalChecks=$((totalChecks + 1)) note "$check_4_11" - logjson "4.11" "NOTE" + resulttestjson "NOTE" currentScore=$((currentScore + 0)) } + +check_4_end() { + endsectionjson +} diff --git a/tests/5_container_runtime.sh b/tests/5_container_runtime.sh index d04b8fd..eaa9ada 100644 --- a/tests/5_container_runtime.sh +++ b/tests/5_container_runtime.sh @@ -1,8 +1,12 @@ #!/bin/sh check_5() { -logit "\n" -info "5 - Container Runtime" + 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() { @@ -24,10 +28,15 @@ check_5_1() { return fi - check_5_1="5.1 - Ensure AppArmor Profile is Enabled" + 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") @@ -36,20 +45,21 @@ check_5_1() { if [ $fail -eq 0 ]; then warn "$check_5_1" warn " * No AppArmorProfile Found: $c" - logjson "5.1" "WARN: $c" + no_apparmor_containers="$no_apparmor_containers $c" fail=1 else warn " * No AppArmorProfile Found: $c" - logjson "5.1" "WARN: $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" - logjson "5.1" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers with no AppArmorProfile" "$no_apparmor_containers" currentScore=$((currentScore - 1)) fi } @@ -60,10 +70,15 @@ check_5_2() { return fi - check_5_2="5.2 - Ensure SELinux security options are set, if applicable" + 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") @@ -72,20 +87,21 @@ check_5_2() { if [ $fail -eq 0 ]; then warn "$check_5_2" warn " * No SecurityOptions Found: $c" - logjson "5.2" "WARN: $c" + no_securityoptions_containers="$no_securityoptions_containers $c" fail=1 else warn " * No SecurityOptions Found: $c" - logjson "5.2" "WARN: $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" - logjson "5.2" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers with no SecurityOptions" "$no_securityoptions_containers" currentScore=$((currentScore - 1)) fi } @@ -96,10 +112,15 @@ check_5_3() { return fi - check_5_3="5.3 - Ensure Linux Kernel Capabilities are restricted within containers" + 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:]" | \ @@ -111,20 +132,21 @@ check_5_3() { if [ $fail -eq 0 ]; then warn "$check_5_3" warn " * Capabilities added: $caps to $c" - logjson "5.3" "WARN: $c" + caps_containers="$caps_containers $c" fail=1 else warn " * Capabilities added: $caps to $c" - logjson "5.3" "WARN: $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" - logjson "5.3" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Capabilities added for containers" "$caps_containers" currentScore=$((currentScore - 1)) fi } @@ -135,10 +157,15 @@ check_5_4() { return fi - check_5_4="5.4 - Ensure privileged containers are not used" + 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") @@ -147,20 +174,21 @@ check_5_4() { if [ $fail -eq 0 ]; then warn "$check_5_4" warn " * Container running in Privileged mode: $c" - logjson "5.4" "WARN: $c" + privileged_containers="$privileged_containers $c" fail=1 else warn " * Container running in Privileged mode: $c" - logjson "5.4" "WARN: $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" - logjson "5.4" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers running in privileged mode" "$privileged_containers" currentScore=$((currentScore - 1)) fi } @@ -171,7 +199,11 @@ check_5_5() { return fi - check_5_5="5.5 - Ensure sensitive host system directories are not mounted on containers" + 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. @@ -185,6 +217,7 @@ check_5_5() { /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") @@ -202,11 +235,11 @@ check_5_5() { if [ $fail -eq 0 ]; then warn "$check_5_5" warn " * Sensitive directory $v mounted in: $c" - logjson "5.5" "WARN: $v in $c" + sensitive_mount_containers="$sensitive_mount_containers $c:$v" fail=1 else warn " * Sensitive directory $v mounted in: $c" - logjson "5.5" "WARN: $v in $c" + sensitive_mount_containers="$sensitive_mount_containers $c:$v" fi fi done @@ -214,9 +247,10 @@ check_5_5() { # We went through all the containers and found none with sensitive mounts if [ $fail -eq 0 ]; then pass "$check_5_5" - logjson "5.5" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers with sensitive directories mounted" "$sensitive_mount_containers" currentScore=$((currentScore - 1)) fi } @@ -227,10 +261,15 @@ check_5_6() { return fi - check_5_6="5.6 - Ensure ssh is not run within containers" + 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 @@ -240,12 +279,12 @@ check_5_6() { if [ $fail -eq 0 ]; then warn "$check_5_6" warn " * Container running sshd: $c" - logjson "5.6" "WARN: $c" + ssh_exec_containers="$ssh_exec_containers $c" fail=1 printcheck=1 else warn " * Container running sshd: $c" - logjson "5.6" "WARN: $c" + ssh_exec_containers="$ssh_exec_containers $c" fi fi @@ -253,11 +292,10 @@ check_5_6() { if [ $? -eq 255 ]; then if [ $printcheck -eq 0 ]; then warn "$check_5_6" - logjson "5.6" "WARN" printcheck=1 fi warn " * Docker exec fails: $c" - logjson "5.6" "WARN: $c" + ssh_exec_containers="$ssh_exec_containers $c" fail=1 fi @@ -265,8 +303,10 @@ check_5_6() { # 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 } @@ -277,10 +317,15 @@ check_5_7() { return fi - check_5_7="5.7 - Ensure privileged ports are not mapped within containers" + 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) @@ -292,11 +337,11 @@ check_5_7() { if [ $fail -eq 0 ]; then warn "$check_5_7" warn " * Privileged Port in use: $port in $c" - logjson "5.7" "WARN: $port in $c" + privileged_port_containers="$privileged_port_containers $c:$port" fail=1 else warn " * Privileged Port in use: $port in $c" - logjson "5.7" "WARN: $port in $c" + privileged_port_containers="$privileged_port_containers $c:$port" fi fi done @@ -304,9 +349,10 @@ check_5_7() { # We went through all the containers and found no privileged ports if [ $fail -eq 0 ]; then pass "$check_5_7" - logjson "5.7" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers using privileged ports" "$privileged_port_containers" currentScore=$((currentScore - 1)) fi } @@ -317,10 +363,14 @@ check_5_8() { return fi - check_5_8="5.8 - Ensure only needed ports are open on the container" + 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" - logjson "5.8" "NOTE" + resulttestjson "NOTE" currentScore=$((currentScore + 0)) } @@ -330,10 +380,15 @@ check_5_9() { return fi - check_5_9="5.9 - Ensure the host's network namespace is not shared" + 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") @@ -342,20 +397,21 @@ check_5_9() { if [ $fail -eq 0 ]; then warn "$check_5_9" warn " * Container running with networking mode 'host': $c" - logjson "5.9" "WARN: $c" + net_host_containers="$net_host_containers $c" fail=1 else warn " * Container running with networking mode 'host': $c" - logjson "5.9" "WARN: $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" - logjson "5.9" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 0)) else + resulttestjson "WARN" "Containers running with networking mode 'host'" "$net_host_containers" currentScore=$((currentScore - 1)) fi } @@ -366,10 +422,15 @@ check_5_10() { return fi - check_5_10="5.10 - Ensure memory usage for container is limited" + 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") @@ -382,20 +443,21 @@ check_5_10() { if [ $fail -eq 0 ]; then warn "$check_5_10" warn " * Container running without memory restrictions: $c" - logjson "5.10" "WARN: $c" + mem_unlimited_containers="$mem_unlimited_containers $c" fail=1 else warn " * Container running without memory restrictions: $c" - logjson "5.10" "WARN: $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" - logjson "5.10" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Container running without memory restrictions" "$mem_unlimited_containers" currentScore=$((currentScore - 1)) fi } @@ -406,10 +468,15 @@ check_5_11() { return fi - check_5_11="5.11 - Ensure CPU priority is set appropriately on the container" + 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") @@ -422,20 +489,21 @@ check_5_11() { if [ $fail -eq 0 ]; then warn "$check_5_11" warn " * Container running without CPU restrictions: $c" - logjson "5.11" "WARN: $c" + cpu_unlimited_containers="$cpu_unlimited_containers $c" fail=1 else warn " * Container running without CPU restrictions: $c" - logjson "5.11" "WARN: $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" - logjson "5.11" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers running without CPU restrictions" "$cpu_unlimited_containers" currentScore=$((currentScore - 1)) fi } @@ -446,10 +514,15 @@ check_5_12() { return fi - check_5_12="5.12 - Ensure the container's root filesystem is mounted as read only" + 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") @@ -458,20 +531,21 @@ check_5_12() { if [ $fail -eq 0 ]; then warn "$check_5_12" warn " * Container running with root FS mounted R/W: $c" - logjson "5.12" "WARN: $c" + fsroot_mount_containers="$fsroot_mount_containers $c" fail=1 else warn " * Container running with root FS mounted R/W: $c" - logjson "5.12" "WARN: $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" - logjson "5.12" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers running with root FS mounted R/W" "$fsroot_mount_containers" currentScore=$((currentScore - 1)) fi } @@ -482,10 +556,15 @@ check_5_13() { return fi - check_5_13="5.13 - Ensure incoming container traffic is binded to a specific host interface" + 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 @@ -493,11 +572,11 @@ check_5_13() { if [ $fail -eq 0 ]; then warn "$check_5_13" warn " * Port being bound to wildcard IP: $ip in $c" - logjson "5.13" "WARN: $ip in $c" + incoming_unbound_containers="$incoming_unbound_containers $c:$ip" fail=1 else warn " * Port being bound to wildcard IP: $ip in $c" - logjson "5.13" "WARN: $ip in $c" + incoming_unbound_containers="$incoming_unbound_containers $c:$ip" fi fi done @@ -505,9 +584,10 @@ check_5_13() { # 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" - logjson "5.13" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers with port bound to wildcard IP" "$incoming_unbound_containers" currentScore=$((currentScore - 1)) fi } @@ -518,10 +598,15 @@ check_5_14() { return fi - check_5_14="5.14 - Ensure 'on-failure' container restart policy is set to '5'" + 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") @@ -530,20 +615,21 @@ check_5_14() { if [ $fail -eq 0 ]; then warn "$check_5_14" warn " * MaximumRetryCount is not set to 5: $c" - logjson "5.14" "WARN: $c" + maxretry_unset_containers="$maxretry_unset_containers $c" fail=1 else warn " * MaximumRetryCount is not set to 5: $c" - logjson "5.14" "WARN: $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" - logjson "5.14" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers with MaximumRetryCount not set to 5" "$maxretry_unset_containers" currentScore=$((currentScore - 1)) fi } @@ -554,10 +640,15 @@ check_5_15() { return fi - check_5_15="5.15 - Ensure the host's process namespace is not shared" + 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") @@ -566,20 +657,21 @@ check_5_15() { if [ $fail -eq 0 ]; then warn "$check_5_15" warn " * Host PID namespace being shared with: $c" - logjson "5.15" "WARN: $c" + pidns_shared_containers="$pidns_shared_containers $c" fail=1 else warn " * Host PID namespace being shared with: $c" - logjson "5.15" "WARN: $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" - logjson "5.15" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers sharing host PID namespace" "$pidns_shared_containers" currentScore=$((currentScore - 1)) fi } @@ -590,10 +682,15 @@ check_5_16() { return fi - check_5_16="5.16 - Ensure the host's IPC namespace is not shared" + 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") @@ -602,20 +699,21 @@ check_5_16() { if [ $fail -eq 0 ]; then warn "$check_5_16" warn " * Host IPC namespace being shared with: $c" - logjson "5.16" "WARN: $c" + ipcns_shared_containers="$ipcns_shared_containers $c" fail=1 else warn " * Host IPC namespace being shared with: $c" - logjson "5.16" "WARN: $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" - logjson "5.16" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers sharing host IPC namespace" "$ipcns_shared_containers" currentScore=$((currentScore - 1)) fi } @@ -626,10 +724,15 @@ check_5_17() { return fi - check_5_17="5.17 - Ensure host devices are not directly exposed to containers" + 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") @@ -638,20 +741,21 @@ check_5_17() { if [ $fail -eq 0 ]; then info "$check_5_17" info " * Container has devices exposed directly: $c" - logjson "5.17" "INFO: $c" + hostdev_exposed_containers="$hostdev_exposed_containers $c" fail=1 else info " * Container has devices exposed directly: $c" - logjson "5.17" "INFO: $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" - logjson "5.17" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "INFO" "Containers with host devices exposed directly" "$hostdev_exposed_containers" currentScore=$((currentScore + 0)) fi } @@ -662,10 +766,15 @@ check_5_18() { return fi - check_5_18="5.18 - Ensure the default ulimit is overwritten at runtime, only if needed" + 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") @@ -674,20 +783,21 @@ check_5_18() { if [ $fail -eq 0 ]; then info "$check_5_18" info " * Container no default ulimit override: $c" - logjson "5.18" "INFO: $c" + no_ulimit_containers="$no_ulimit_containers $c" fail=1 else info " * Container no default ulimit override: $c" - logjson "5.18" "INFO: $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" - logjson "5.18" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "INFO" "Containers with no default ulimit override" "$no_ulimit_containers" currentScore=$((currentScore + 0)) fi } @@ -698,10 +808,15 @@ check_5_19() { return fi - check_5_19="5.19 - Ensure mount propagation mode is not set to shared" + 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 @@ -709,20 +824,21 @@ check_5_19() { if [ $fail -eq 0 ]; then warn "$check_5_19" warn " * Mount propagation mode is shared: $c" - logjson "5.19" "WARN: $c" + mountprop_shared_containers="$mountprop_shared_containers $c" fail=1 else warn " * Mount propagation mode is shared: $c" - logjson "5.19" "WARN: $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" - logjson "5.19" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers with shared mount propagation" "$mountprop_shared_containers" currentScore=$((currentScore - 1)) fi } @@ -733,10 +849,15 @@ check_5_20() { return fi - check_5_20="5.20 - Ensure the host's UTS namespace is not shared" + 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") @@ -745,20 +866,21 @@ check_5_20() { if [ $fail -eq 0 ]; then warn "$check_5_20" warn " * Host UTS namespace being shared with: $c" - logjson "5.20" "WARN: $c" + utcns_shared_containers="$utcns_shared_containers $c" fail=1 else warn " * Host UTS namespace being shared with: $c" - logjson "5.20" "WARN: $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" - logjson "5.20" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers sharing host UTS namespace" "$utcns_shared_containers" currentScore=$((currentScore - 1)) fi } @@ -769,10 +891,15 @@ check_5_21() { return fi - check_5_21="5.21 - Ensure the default seccomp profile is not Disabled" + 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 @@ -780,20 +907,21 @@ check_5_21() { if [ $fail -eq 0 ]; then warn "$check_5_21" warn " * Default seccomp profile disabled: $c" - logjson "5.21" "WARN: $c" + seccomp_disabled_containers="$seccomp_disabled_containers $c" fail=1 else warn " * Default seccomp profile disabled: $c" - logjson "5.21" "WARN: $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" - logjson "5.21" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers with default seccomp profile disabled" "$seccomp_disabled_containers" currentScore=$((currentScore - 1)) fi } @@ -804,10 +932,14 @@ check_5_22() { return fi - check_5_22="5.22 - Ensure docker exec commands are not used with privileged option" + 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" - logjson "5.22" "NOTE" + resulttestjson "NOTE" currentScore=$((currentScore + 0)) } @@ -817,10 +949,14 @@ check_5_23() { return fi - check_5_23="5.23 - Ensure docker exec commands are not used with user option" + 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" - logjson "5.23" "NOTE" + resulttestjson "NOTE" currentScore=$((currentScore + 0)) } @@ -830,10 +966,15 @@ check_5_24() { return fi - check_5_24="5.24 - Ensure cgroup usage is confirmed" + 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") @@ -842,20 +983,21 @@ check_5_24() { if [ $fail -eq 0 ]; then warn "$check_5_24" warn " * Confirm cgroup usage: $c" - logjson "5.24" "WARN: $c" + unexpected_cgroup_containers="$unexpected_cgroup_containers $c" fail=1 else warn " * Confirm cgroup usage: $c" - logjson "5.24" "WARN: $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" - logjson "5.24" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers using unexpected cgroup" "$unexpected_cgroup_containers" currentScore=$((currentScore - 1)) fi } @@ -865,30 +1007,36 @@ check_5_25() { if [ "$running_containers" -ne 1 ]; then return fi - check_5_25="5.25 - Ensure the container is restricted from acquiring additional privileges" + 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" - logjson "5.25" "WARN: $c" + addprivs_containers="$addprivs_containers $c" fail=1 else warn " * Privileges not restricted: $c" - logjson "5.25" "WARN: $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" - logjson "5.25" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers without restricted privileges" "$addprivs_containers" currentScore=$((currentScore - 1)) fi } @@ -899,28 +1047,34 @@ check_5_26() { return fi - check_5_26="5.26 - Ensure container health is checked at runtime" + 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" - logjson "5.26" "WARN: $c" + nohealthcheck_containers="$nohealthcheck_containers $c" fail=1 else warn " * Health check not set: $c" - logjson "5.26" "WARN: $c" + nohealthcheck_containers="$nohealthcheck_containers $c" fi fi done if [ $fail -eq 0 ]; then pass "$check_5_26" - logjson "5.26" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers without health check" "$nohealthcheck_containers" currentScore=$((currentScore - 1)) fi } @@ -931,10 +1085,14 @@ check_5_27() { return fi - check_5_27="5.27 - Ensure docker commands always get the latest version of the image" + 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" - logjson "5.27" "INFO" + resulttestjson "INFO" currentScore=$((currentScore + 0)) } @@ -944,10 +1102,15 @@ check_5_28() { return fi - check_5_28="5.28 - Ensure PIDs cgroup limit is used" + 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") @@ -956,20 +1119,21 @@ check_5_28() { if [ $fail -eq 0 ]; then warn "$check_5_28" warn " * PIDs limit not set: $c" - logjson "5.28" "WARN: $c" + nopids_limit_containers="$nopids_limit_containers $c" fail=1 else warn " * PIDs limit not set: $c" - logjson "5.28" "WARN: $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" - logjson "5.28" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers without PIDs cgroup limit" "$nopids_limit_containers" currentScore=$((currentScore - 1)) fi } @@ -980,10 +1144,15 @@ check_5_29() { return fi - check_5_29="5.29 - Ensure Docker's default bridge docker0 is not used" + 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 @@ -993,7 +1162,6 @@ check_5_29() { if [ -n "$docker0Containers" ]; then if [ $fail -eq 0 ]; then info "$check_5_29" - logjson "5.29" "INFO" fail=1 fi for c in $docker0Containers; do @@ -1005,7 +1173,7 @@ check_5_29() { fi if ! [ -z "$cName" ]; then info " * Container in docker0 network: $cName" - logjson "5.29" "INFO: $c" + docker_network_containers="$docker_network_containers $c:$cName" fi done fi @@ -1015,9 +1183,10 @@ check_5_29() { # We went through all the containers and found none in docker0 network if [ $fail -eq 0 ]; then pass "$check_5_29" - logjson "5.29" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "INFO" "Containers using docker0 network" "$docker_network_containers" currentScore=$((currentScore + 0)) fi } @@ -1028,30 +1197,36 @@ check_5_30() { return fi - check_5_30="5.30 - Ensure the host's user namespaces is not shared" + 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" - logjson "5.30" "WARN: $c" + hostns_shared_containers="$hostns_shared_containers $c" fail=1 else warn " * Namespace shared: $c" - logjson "5.30" "WARN: $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" - logjson "5.30" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers sharing host user namespace" "$hostns_shared_containers" currentScore=$((currentScore - 1)) fi } @@ -1062,30 +1237,40 @@ check_5_31() { return fi - check_5_31="5.31 - Ensure the Docker socket is not mounted inside any containers" + 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" - logjson "5.31" "WARN: $c" + docker_sock_containers="$docker_sock_containers $c" fail=1 else warn " * Docker socket shared: $c" - logjson "5.31" "WARN: $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" - logjson "5.31" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else + resulttestjson "WARN" "Containers sharing docker socket" "$docker_sock_containers" currentScore=$((currentScore - 1)) fi } + +check_5_end() { + endsectionjson +} diff --git a/tests/6_docker_security_operations.sh b/tests/6_docker_security_operations.sh index b76959e..f2ec50c 100644 --- a/tests/6_docker_security_operations.sh +++ b/tests/6_docker_security_operations.sh @@ -2,12 +2,20 @@ check_6() { logit "\n" - info "6 - Docker Security Operations" + id_6="6" + desc_6="Docker Security Operations" + check_6="$id_6 - $desc_6" + info "$check_6" + startsectionjson "$id_6" "$desc_6" } # 6.1 check_6_1() { - check_6_1="6.1 - Avoid image sprawl" + id_6_1="6.1" + desc_6_1="Avoid image sprawl" + check_6_1="$id_6_1 - $desc_6_1" + starttestjson "$id_6_1" "$desc_6_1" + totalChecks=$((totalChecks + 1)) images=$(docker images -q | sort -u | wc -l | awk '{print $1}') active_images=0 @@ -23,26 +31,34 @@ check_6_1() { if [ "$active_images" -lt "$((images / 2))" ]; then info " * Only $active_images out of $images are in use" - logjson "6.1" "INFO: $active_images" fi + resulttestjson "INFO" "$active_images active/$images in use" currentScore=$((currentScore + 0)) } # 6.2 check_6_2() { - check_6_2="6.2 - Avoid container sprawl" + id_6_2="6.2" + desc_6_2="Avoid container sprawl" + check_6_2="$id_6_2 - $desc_6_2" + starttestjson "$id_6_2" "$desc_6_2" + totalChecks=$((totalChecks + 1)) - total_containers=$(docker info 2>/dev/null | grep "^Containers" | awk '{print $2}') + total_containers=$(docker info 2>/dev/null | grep "Containers" | awk '{print $2}') running_containers=$(docker ps -q | wc -l | awk '{print $1}') diff="$((total_containers - running_containers))" if [ "$diff" -gt 25 ]; then info "$check_6_2" info " * There are currently a total of $total_containers containers, with only $running_containers of them currently running" - logjson "6.2" "INFO: $running_containers" + resulttestjson "INFO" "$total_containers total/$running_containers running" else info "$check_6_2" info " * There are currently a total of $total_containers containers, with $running_containers of them currently running" - logjson "6.2" "INFO: $running_containers" + resulttestjson "INFO" "$total_containers total/$running_containers running" fi currentScore=$((currentScore + 0)) } + +check_6_end() { + endsectionjson +} diff --git a/tests/7_docker_swarm_configuration.sh b/tests/7_docker_swarm_configuration.sh index 0f6b3f5..22a4e74 100644 --- a/tests/7_docker_swarm_configuration.sh +++ b/tests/7_docker_swarm_configuration.sh @@ -2,71 +2,91 @@ check_7() { logit "\n" - info "7 - Docker Swarm Configuration" + id_7="7" + desc_7="Docker Swarm Configuration" + check_7="$id_7 - $desc_7" + info "$check_7" + startsectionjson "$id_7" "$desc_7" } # 7.1 check_7_1() { - check_7_1="7.1 - Ensure swarm mode is not Enabled, if not needed" + id_7_1="7.1" + desc_7_1="Ensure swarm mode is not Enabled, if not needed" + check_7_1="$id_7_1 - $desc_7_1" + starttestjson "$id_7_1" "$desc_7_1" + totalChecks=$((totalChecks + 1)) if docker info 2>/dev/null | grep -e "Swarm:*\sinactive\s*" >/dev/null 2>&1; then pass "$check_7_1" - logjson "7.1" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_7_1" - logjson "7.1" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi } # 7.2 check_7_2() { - check_7_2="7.2 - Ensure the minimum number of manager nodes have been created in a swarm" + id_7_2="7.2" + desc_7_2="Ensure the minimum number of manager nodes have been created in a swarm" + check_7_2="$id_7_2 - $desc_7_2" + starttestjson "$id_7_2" "$desc_7_2" + totalChecks=$((totalChecks + 1)) if docker info 2>/dev/null | grep -e "Swarm:*\sactive\s*" >/dev/null 2>&1; then managernodes=$(docker node ls | grep -c "Leader") if [ "$managernodes" -le 1 ]; then pass "$check_7_2" - logjson "7.2" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_7_2" - logjson "7.2" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else pass "$check_7_2 (Swarm mode not enabled)" - logjson "7.2" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } # 7.3 check_7_3() { - check_7_3="7.3 - Ensure swarm services are binded to a specific host interface" + id_7_3="7.3" + desc_7_3="Ensure swarm services are binded to a specific host interface" + check_7_3="$id_7_3 - $desc_7_3" + starttestjson "$id_7_3" "$desc_7_3" + totalChecks=$((totalChecks + 1)) if docker info 2>/dev/null | grep -e "Swarm:*\sactive\s*" >/dev/null 2>&1; then ss -lnt | grep -e '\[::]:2377 ' -e ':::2377' -e '*:2377 ' -e ' 0\.0\.0\.0:2377 ' >/dev/null 2>&1 if [ $? -eq 1 ]; then pass "$check_7_3" - logjson "7.3" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_7_3" - logjson "7.3" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else pass "$check_7_3 (Swarm mode not enabled)" - logjson "7.3" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } # 7.4 check_7_4(){ - check_7_4="7.4 - Ensure data exchanged between containers are encrypted on different nodes on the overlay network" + id_7_4="7.4" + desc_7_4="Ensure data exchanged between containers are encrypted on different nodes on the overlay network" + check_7_4="$id_7_4 - $desc_7_4" + starttestjson "$id_7_4" "$desc_7_4" + totalChecks=$((totalChecks + 1)) if docker network ls --filter driver=overlay --quiet | \ xargs docker network inspect --format '{{.Name}} {{ .Options }}' 2>/dev/null | \ @@ -77,120 +97,148 @@ check_7_4(){ if docker network inspect --format '{{.Name}} {{ .Options }}' "$encnet" | \ grep -v 'encrypted:' 2>/dev/null 1>&2; then warn " * Unencrypted overlay network: $(docker network inspect --format '{{ .Name }} ({{ .Scope }})' "$encnet")" - logjson "7.4" "WARN: $(docker network inspect --format '{{ .Name }} ({{ .Scope }})' "$encnet")" + resulttestjson "WARN" "Unencrypted overlay network: $(docker network inspect --format '{{ .Name }} ({{ .Scope }})' "$encnet")" fi done else pass "$check_7_4" - logjson "7.4" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } # 7.5 check_7_5() { - check_7_5="7.5 - Ensure Docker's secret management commands are used for managing secrets in a Swarm cluster" + id_7_5="7.5" + desc_7_5="Ensure Docker's secret management commands are used for managing secrets in a Swarm cluster" + check_7_5="$id_7_5 - $desc_7_5" + starttestjson "$id_7_5" "$desc_7_5" + totalChecks=$((totalChecks + 1)) if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then if [ "$(docker secret ls -q | wc -l)" -ge 1 ]; then pass "$check_7_5" - logjson "7.5" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else info "$check_7_5" - logjson "7.5" "INFO" + resulttestjson "INFO" currentScore=$((currentScore + 0)) fi else pass "$check_7_5 (Swarm mode not enabled)" - logjson "7.5" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } # 7.6 check_7_6() { - check_7_6="7.6 - Ensure swarm manager is run in auto-lock mode" + id_7_6="7.6" + desc_7_6="Ensure swarm manager is run in auto-lock mode" + check_7_6="$id_7_6 - $desc_7_6" + starttestjson "$id_7_6" "$desc_7_6" + totalChecks=$((totalChecks + 1)) if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then if ! docker swarm unlock-key 2>/dev/null | grep 'SWMKEY' 2>/dev/null 1>&2; then warn "$check_7_6" - logjson "7.6" "WARN" + resulttestjson "WARN" currentScore=$((currentScore - 1)) else pass "$check_7_6" - logjson "7.6" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi else pass "$check_7_6 (Swarm mode not enabled)" - logjson "7.6" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } # 7.7 check_7_7() { - check_7_7="7.7 - Ensure swarm manager auto-lock key is rotated periodically" + id_7_7="7.7" + desc_7_7="Ensure swarm manager auto-lock key is rotated periodically" + check_7_7="$id_7_7 - $desc_7_7" + starttestjson "$id_7_7" "$desc_7_7" + totalChecks=$((totalChecks + 1)) if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then note "$check_7_7" - logjson "7.7" "NOTE" + resulttestjson "NOTE" currentScore=$((currentScore + 0)) else pass "$check_7_7 (Swarm mode not enabled)" - logjson "7.7" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } # 7.8 check_7_8() { - check_7_8="7.8 - Ensure node certificates are rotated as appropriate" + id_7_8="7.8" + desc_7_8="Ensure node certificates are rotated as appropriate" + check_7_8="$id_7_8 - $desc_7_8" + starttestjson "$id_7_8" "$desc_7_8" + totalChecks=$((totalChecks + 1)) if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then if docker info 2>/dev/null | grep "Expiry Duration: 2 days"; then pass "$check_7_8" - logjson "7.8" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) else info "$check_7_8" - logjson "7.8" "INFO" + resulttestjson "INFO" currentScore=$((currentScore + 0)) fi else pass "$check_7_8 (Swarm mode not enabled)" - logjson "7.8" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } # 7.9 check_7_9() { - check_7_9="7.9 - Ensure CA certificates are rotated as appropriate" + id_7_9="7.9" + desc_7_9="Ensure CA certificates are rotated as appropriate" + check_7_9="$id_7_9 - $desc_7_9" + starttestjson "$id_7_9" "$desc_7_9" + totalChecks=$((totalChecks + 1)) if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then info "$check_7_9" - logjson "7.9" "INFO" + resulttestjson "INFO" currentScore=$((currentScore + 0)) else pass "$check_7_9 (Swarm mode not enabled)" - logjson "7.9" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } # 7.10 check_7_10() { - check_7_10="7.10 - Ensure management plane traffic has been separated from data plane traffic" + id_7_10="7.10" + desc_7_10="Ensure management plane traffic has been separated from data plane traffic" + check_7_10="$id_7_10 - $desc_7_10" + starttestjson "$id_7_10" "$desc_7_10" + totalChecks=$((totalChecks + 1)) if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then info "$check_7_10" - logjson "7.10" "INFO" + resulttestjson "INFO" currentScore=$((currentScore + 0)) else pass "$check_7_10 (Swarm mode not enabled)" - logjson "7.10" "PASS" + resulttestjson "PASS" currentScore=$((currentScore + 1)) fi } + +check_7_end() { + endsectionjson +} diff --git a/tests/99_community_checks.sh b/tests/99_community_checks.sh index 953ed5c..ef9177f 100644 --- a/tests/99_community_checks.sh +++ b/tests/99_community_checks.sh @@ -1,7 +1,11 @@ #!/bin/sh check_c() { logit "\n" - info "99 - Community contributed checks" + id_99="99" + desc_99="Community contributed checks" + check_99="$id_99 - $desc_99" + info "$check_99" + startsectionjson "$id_99" "$desc_99" } # check_c_1 @@ -10,9 +14,13 @@ check_c_1() { totalChecks=$((totalChecks + 1)) if docker info --format='{{ .Architecture }}' | grep 'x86_64' 2>/dev/null 1>&2; then pass "$check_c_1" - logjson "c.1" "PASS" + resulttestjson "PASS" else warn "$check_c_1" - logjson "c.1" "WARN" + resulttestjson "WARN" fi } + +check_c_end() { + endsectionjson +}