From ec7d8ce690bbd38b709b679d85857351c328db09 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Wed, 11 Jul 2018 18:02:12 -0700 Subject: [PATCH] Improve docker-bench-security json output Add a test object for each test performed by the script. Each object has an id N.M, a desc property describing the test, and the result. Some tests include additional information about the test e.g. "No TLS Certificate Found". That can be found in an optional details property of the test object. Also, some tests might also return a list of containers, images, users, etc. This is included in an optional items property of the test object. Instead of having all test results as top-level objects, break the test results into sections. Each section has an id + description e.g. "1" and "Host Configuration". The tests for that section are an array below that object. All of the additional json output is implemented by adding new functions startsectionjson(), endsectionjson(), starttestjson(), and resulttestjson() that take the id/desc/etc as arguments and print the proper json properties. It also required adding an "end" test to each script that calls endsectionjson(). Signed-off-by: Mark Stemm --- docker-bench-security.sh | 4 +- functions_lib.sh | 8 + output_lib.sh | 34 +- tests/1_host_configuration.sh | 191 ++++++--- tests/2_docker_daemon_configuration.sh | 236 +++++++---- tests/3_docker_daemon_configuration_files.sh | 250 +++++++---- tests/4_container_images.sh | 123 ++++-- tests/5_container_runtime.sh | 423 +++++++++++++------ tests/6_docker_security_operations.sh | 30 +- tests/7_docker_swarm_configuration.sh | 120 ++++-- tests/99_community_checks.sh | 14 +- 11 files changed, 1006 insertions(+), 427 deletions(-) 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 +}