From 67202075125744851618835a2b619ac334a000c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Mon, 26 Aug 2019 14:10:42 +0200 Subject: [PATCH 01/25] FROM alpine:3.10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- distros/Dockerfile.alpine | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distros/Dockerfile.alpine b/distros/Dockerfile.alpine index a724dad..2bbaad3 100644 --- a/distros/Dockerfile.alpine +++ b/distros/Dockerfile.alpine @@ -1,4 +1,4 @@ -FROM alpine:3.9 +FROM alpine:3.10 LABEL \ org.label-schema.name="docker-bench-security" \ From 227f2faa5b92930c67a0c91f74c1eabaedcaae03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Mon, 26 Aug 2019 14:11:10 +0200 Subject: [PATCH 02/25] bump version to 1.3.5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- docker-bench-security.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-bench-security.sh b/docker-bench-security.sh index 2e7d0e6..35e23b9 100755 --- a/docker-bench-security.sh +++ b/docker-bench-security.sh @@ -7,7 +7,7 @@ # Checks for dozens of common best-practices around deploying Docker containers in production. # ------------------------------------------------------------------------------ -version='1.3.4' +version='1.3.5' # Load dependencies . ./functions_lib.sh From 7685c0417ac3b4635b0282992c8d7008052e7c6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Mon, 26 Aug 2019 14:12:03 +0200 Subject: [PATCH 03/25] update CIS Docker Benchmark version and link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index d5e97c1..9109302 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,7 @@ The Docker Bench for Security is a script that checks for dozens of common best-practices around deploying Docker containers in production. The tests are -all automated, and are inspired by the [CIS Docker Community Edition Benchmark v1.1.0](https://benchmarks.cisecurity.org/tools2/docker/CIS_Docker_Community_Edition_Benchmark_v1.1.0.pdf). -We are releasing this as a follow-up to our [Understanding Docker Security and Best Practices](https://blog.docker.com/2015/05/understanding-docker-security-and-best-practices/) -blog post. +all automated, and are inspired by the [CIS Docker Benchmark v1.2.0](https://www.cisecurity.org/benchmark/docker/). We are making this available as an open-source utility so the Docker community can have an easy way to self-assess their hosts and docker containers against From 6105f02a162eed34db82c6c6e465f5c2e21d5d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Mon, 26 Aug 2019 14:37:25 +0200 Subject: [PATCH 04/25] first pass on section 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- tests/1_host_configuration.sh | 300 ++++++++++++++++++---------------- 1 file changed, 160 insertions(+), 140 deletions(-) diff --git a/tests/1_host_configuration.sh b/tests/1_host_configuration.sh index 3ecb844..8a4d99e 100644 --- a/tests/1_host_configuration.sh +++ b/tests/1_host_configuration.sh @@ -9,45 +9,34 @@ check_1() { startsectionjson "$id_1" "$desc_1" } -# 1.1 check_1_1() { - 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 mountpoint -q -- "$(docker info -f '{{ .DockerRootDir }}')" >/dev/null 2>&1; then - pass "$check_1_1" - resulttestjson "PASS" - currentScore=$((currentScore + 1)) - else - warn "$check_1_1" - resulttestjson "WARN" - currentScore=$((currentScore - 1)) - fi + logit "" + id_1_1="1_1" + desc_1_1="General Configuration" + check_1_1="$id_1_1 - $desc_1_1" + info "$check_1_1" + startsectionjson "$id_1_1" "$desc_1_1" } -# 1.2 -check_1_2() { - 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" +# 1.1.1 +check_1_1_1() { + id_1_1_1="1.1.1" + desc_1_1_1="Ensure the container host has been Hardened" + check_1_1_1="$id_1_1_1 - $desc_1_1_1" + starttestjson "$id_1_1_1" "$desc_1_1_1" totalChecks=$((totalChecks + 1)) - note "$check_1_2" + note "$check_1_1_1" resulttestjson "INFO" currentScore=$((currentScore + 0)) } -# 1.3 -check_1_3() { - 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" +# 1.1.2 +check_1_1_2() { + id_1_1_2="1.1.2" + desc_1_1_2="Ensure Docker is up to date" + check_1_1_2="$id_1_1_2 - $desc_1_1_2" + starttestjson "$id_1_1_2" "$desc_1_1_2" totalChecks=$((totalChecks + 1)) docker_version=$(docker version | grep -i -A2 '^server' | grep ' Version:' \ @@ -55,13 +44,13 @@ check_1_3() { docker_current_version="$(date +%y.%m.0 -d @$(( $(date +%s) - 2592000)))" do_version_check "$docker_current_version" "$docker_version" if [ $? -eq 11 ]; then - info "$check_1_3" + info "$check_1_1_2" 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" resulttestjson "INFO" "Using $docker_version" currentScore=$((currentScore + 0)) else - pass "$check_1_3" + pass "$check_1_1_2" info " * Using $docker_version which is current" info " * Check with your operating system vendor for support and security maintenance for Docker" resulttestjson "PASS" "Using $docker_version" @@ -69,16 +58,45 @@ check_1_3() { fi } -# 1.4 -check_1_4() { - 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" +check_1_2() { + logit "" + id_1_2="1_2" + desc_1_2="Linux Hosts Specific Configuration" + check_1_2="$id_1_2 - $desc_1_2" + info "$check_1_2" + startsectionjson "$id_1_2" "$desc_1_2" +} + +# 1.2.1 +check_1_2_1() { + id_1_2_1="1.2.1" + desc_1_2_1="Ensure a separate partition for containers has been created" + check_1_2_1="$id_1_2_1 - $desc_1_2_1" + starttestjson "$id_1_2_1" "$desc_1_2_1" + + totalChecks=$((totalChecks + 1)) + + if mountpoint -q -- "$(docker info -f '{{ .DockerRootDir }}')" >/dev/null 2>&1; then + pass "$check_1_2_1" + resulttestjson "PASS" + currentScore=$((currentScore + 1)) + else + warn "$check_1_2_1" + resulttestjson "WARN" + currentScore=$((currentScore - 1)) + fi +} + +# 1.2.2 +check_1_2_2() { + id_1_2_2="1.2.2" + desc_1_2_2="Ensure only trusted users are allowed to control Docker daemon" + check_1_2_2="$id_1_2_2 - $desc_1_2_2" + starttestjson "$id_1_2_2" "$desc_1_2_2" totalChecks=$((totalChecks + 1)) docker_users=$(getent group docker) - info "$check_1_4" + info "$check_1_2_2" for u in $docker_users; do info " * $u" done @@ -86,326 +104,328 @@ check_1_4() { currentScore=$((currentScore + 0)) } -# 1.5 -check_1_5() { - 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" +# 1.2.3 +check_1_2_3() { + id_1_2_3="1.2.3" + desc_1_2_3="Ensure auditing is configured for the Docker daemon" + check_1_2_3="$id_1_2_3 - $desc_1_2_3" + starttestjson "$id_1_2_3" "$desc_1_2_3" totalChecks=$((totalChecks + 1)) - file="/usr/bin/docker " + file="/usr/bin/dockerd" if command -v auditctl >/dev/null 2>&1; then if auditctl -l | grep "$file" >/dev/null 2>&1; then - pass "$check_1_5" + pass "$check_1_2_3" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_5" + warn "$check_1_2_3" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then - pass "$check_1_5" + pass "$check_1_2_3" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_5" + warn "$check_1_2_3" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi } -# 1.6 -check_1_6() { - 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" +# 1.2.4 +check_1_2_4() { + id_1_2_4="1.2.4" + desc_1_2_4="Ensure auditing is configured for Docker files and directories - /var/lib/docker" + check_1_2_4="$id_1_2_4 - $desc_1_2_4" + starttestjson "$id_1_2_4" "$desc_1_2_4" 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" + pass "$check_1_2_4" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_6" + warn "$check_1_2_4" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$directory" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then - pass "$check_1_6" + pass "$check_1_2_4" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_6" + warn "$check_1_2_4" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else - info "$check_1_6" + info "$check_1_2_4" info " * Directory not found" resulttestjson "INFO" "Directory not found" currentScore=$((currentScore + 0)) fi } -# 1.7 -check_1_7() { - 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" +# 1.2.5 +check_1_2_5() { + id_1_2_5="1.2.5" + desc_1_2_5="Ensure auditing is configured for Docker files and directories - /etc/docker" + check_1_2_5="$id_1_2_5 - $desc_1_2_5" + starttestjson "$id_1_2_5" "$desc_1_2_5" 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" + pass "$check_1_2_5" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_7" + warn "$check_1_2_5" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$directory" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then - pass "$check_1_7" + pass "$check_1_2_5" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_7" + warn "$check_1_2_5" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else - info "$check_1_7" + info "$check_1_2_5" info " * Directory not found" resulttestjson "INFO" "Directory not found" currentScore=$((currentScore + 0)) fi } -# 1.8 -check_1_8() { - 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" +# 1.2.6 +check_1_2_6() { + id_1_2_6="1.2.6" + desc_1_2_6="Ensure auditing is configured for Docker files and directories - docker.service" + check_1_2_6="$id_1_2_6 - $desc_1_2_6" + starttestjson "$id_1_2_6" "$desc_1_2_6" 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" + pass "$check_1_2_6" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_8" + warn "$check_1_2_6" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then - pass "$check_1_8" + pass "$check_1_2_6" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_8" + warn "$check_1_2_6" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else - info "$check_1_8" + info "$check_1_2_6" info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } -# 1.9 -check_1_9() { - 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" +# 1.2.7 +check_1_2_7() { + id_1_2_7="1.2.7" + desc_1_2_7="Ensure auditing is configured for Docker files and directories - docker.socket" + check_1_2_7="$id_1_2_7 - $desc_1_2_7" + starttestjson "$id_1_2_7" "$desc_1_2_7" 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" + pass "$check_1_2_7" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_9" + warn "$check_1_2_7" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then - pass "$check_1_9" + pass "$check_1_2_7" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_9" + warn "$check_1_2_7" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else - info "$check_1_9" + info "$check_1_2_7" info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } -# 1.10 -check_1_10() { - 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" +# 1.2.8 +check_1_2_8() { + id_1_2_8="1.2.8" + desc_1_2_8="Ensure auditing is configured for Docker files and directories - /etc/default/docker" + check_1_2_8="$id_1_2_8 - $desc_1_2_8" + starttestjson "$id_1_2_8" "$desc_1_2_8" 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" + pass "$check_1_2_8" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_10" + warn "$check_1_2_8" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then - pass "$check_1_10" + pass "$check_1_2_8" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_10" + warn "$check_1_2_8" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else - info "$check_1_10" + info "$check_1_2_8" info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } -# 1.11 -check_1_11() { - 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" +# 1.2.9 Ensure auditing is configured for Docker files and directories -/etc/sysconfig/docker (Scored) + +# 1.2.10 +check_1_2_10() { + id_1_2_10="1.2.10" + desc_1_2_10="Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json" + check_1_2_10="$id_1_2_10 - $desc_1_2_10" + starttestjson "$id_1_2_10" "$desc_1_2_10" 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" + pass "$check_1_2_10" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_11" + warn "$check_1_2_10" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then - pass "$check_1_11" + pass "$check_1_2_10" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_11" + warn "$check_1_2_10" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else - info "$check_1_11" + info "$check_1_2_10" info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } -# 1.12 -check_1_12() { - 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" +# 1.2.11 +check_1_2_11() { + id_1_2_11="1.2.11" + desc_1_2_11="Ensure auditing is configured for Docker files and directories - /usr/bin/containerd" + check_1_2_11="$id_1_2_11 - $desc_1_2_11" + starttestjson "$id_1_2_11" "$desc_1_2_11" totalChecks=$((totalChecks + 1)) - file="/usr/bin/docker-containerd" + file="/usr/bin/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" + pass "$check_1_2_11" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_12" + warn "$check_1_2_11" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then - pass "$check_1_12" + pass "$check_1_2_11" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_12" + warn "$check_1_2_11" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else - info "$check_1_12" + info "$check_1_2_11" info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi } -# 1.13 -check_1_13() { - 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" +# 1.2.12 +check_1_2_12() { + id_1_2_12="1.2.12" + desc_1_2_12="Ensure auditing is configured for Docker files and directories - /usr/sbin/runc" + check_1_2_12="$id_1_2_12 - $desc_1_2_12" + starttestjson "$id_1_2_12" "$desc_1_2_12" totalChecks=$((totalChecks + 1)) - file="/usr/bin/docker-runc" + file="/usr/sbin/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" + pass "$check_1_2_12" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_13" + warn "$check_1_2_12" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then - pass "$check_1_13" + pass "$check_1_2_12" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_1_13" + warn "$check_1_2_12" resulttestjson "WARN" currentScore=$((currentScore - 1)) fi else - info "$check_1_13" + info "$check_1_2_12" info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) From 28f16f0afd2a5b8d2850b392653d25fd7254eedd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Mon, 26 Aug 2019 14:41:37 +0200 Subject: [PATCH 05/25] add 1.2.9, #ref https://github.com/docker/docker-bench-security/pull/359 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- tests/1_host_configuration.sh | 37 ++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/tests/1_host_configuration.sh b/tests/1_host_configuration.sh index 8a4d99e..c5271cc 100644 --- a/tests/1_host_configuration.sh +++ b/tests/1_host_configuration.sh @@ -319,7 +319,42 @@ check_1_2_8() { fi } -# 1.2.9 Ensure auditing is configured for Docker files and directories -/etc/sysconfig/docker (Scored) +# 1.2.9 +check_1_2_9() { + id_1_2_9="1.2.9" + desc_1_2_9="Ensure auditing is configured for Docker files and directories - /etc/sysconfig/docker" + check_1_2_9="$id_1_2_9 - $desc_1_2_9" + starttestjson "$id_1_2_9" "$desc_1_2_9" + + totalChecks=$((totalChecks + 1)) + file="/etc/sysconfig/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_2_9" + resulttestjson "PASS" + currentScore=$((currentScore + 1)) + else + warn "$check_1_2_9" + resulttestjson "WARN" + currentScore=$((currentScore - 1)) + fi + elif grep -s "$file" "$auditrules" | grep "^[^#;]" 2>/dev/null 1>&2; then + pass "$check_1_2_9" + resulttestjson "PASS" + currentScore=$((currentScore + 1)) + else + warn "$check_1_2_9" + resulttestjson "WARN" + currentScore=$((currentScore - 1)) + fi + else + info "$check_1_2_9" + info " * File not found" + resulttestjson "INFO" "File not found" + currentScore=$((currentScore + 0)) + fi +} # 1.2.10 check_1_2_10() { From f2a7e6d6a6b1bf04924d149537efad99fb10561b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Mon, 26 Aug 2019 15:13:31 +0200 Subject: [PATCH 06/25] update sect 1 function names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- functions_lib.sh | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/functions_lib.sh b/functions_lib.sh index f7c32ba..60a898f 100644 --- a/functions_lib.sh +++ b/functions_lib.sh @@ -3,18 +3,21 @@ host_configuration() { check_1 check_1_1 + check_1_1_1 + check_1_1_2 check_1_2 - check_1_3 - check_1_4 - check_1_5 - check_1_6 - check_1_7 - check_1_8 - check_1_9 - check_1_10 - check_1_11 - check_1_12 - check_1_13 + check_1_2_1 + check_1_2_2 + check_1_2_3 + check_1_2_4 + check_1_2_5 + check_1_2_6 + check_1_2_7 + check_1_2_8 + check_1_2_9 + check_1_2_10 + check_1_2_11 + check_1_2_12 check_1_end } From d963b93fcc10939f6927d8fedff2f66a65c3db94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Mon, 26 Aug 2019 15:13:50 +0200 Subject: [PATCH 07/25] update info output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- tests/1_host_configuration.sh | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/1_host_configuration.sh b/tests/1_host_configuration.sh index c5271cc..c7f8d5d 100644 --- a/tests/1_host_configuration.sh +++ b/tests/1_host_configuration.sh @@ -11,7 +11,7 @@ check_1() { check_1_1() { logit "" - id_1_1="1_1" + id_1_1="1.1" desc_1_1="General Configuration" check_1_1="$id_1_1 - $desc_1_1" info "$check_1_1" @@ -45,14 +45,14 @@ check_1_1_2() { do_version_check "$docker_current_version" "$docker_version" if [ $? -eq 11 ]; then info "$check_1_1_2" - 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" + 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" resulttestjson "INFO" "Using $docker_version" currentScore=$((currentScore + 0)) else pass "$check_1_1_2" - info " * Using $docker_version which is current" - info " * Check with your operating system vendor for support and security maintenance for Docker" + info " * Using $docker_version which is current" + info " * Check with your operating system vendor for support and security maintenance for Docker" resulttestjson "PASS" "Using $docker_version" currentScore=$((currentScore + 0)) fi @@ -60,7 +60,7 @@ check_1_1_2() { check_1_2() { logit "" - id_1_2="1_2" + id_1_2="1.2" desc_1_2="Linux Hosts Specific Configuration" check_1_2="$id_1_2 - $desc_1_2" info "$check_1_2" @@ -98,7 +98,7 @@ check_1_2_2() { docker_users=$(getent group docker) info "$check_1_2_2" for u in $docker_users; do - info " * $u" + info " * $u" done resulttestjson "INFO" "users" "$docker_users" currentScore=$((currentScore + 0)) @@ -165,7 +165,7 @@ check_1_2_4() { fi else info "$check_1_2_4" - info " * Directory not found" + info " * Directory not found" resulttestjson "INFO" "Directory not found" currentScore=$((currentScore + 0)) fi @@ -202,7 +202,7 @@ check_1_2_5() { fi else info "$check_1_2_5" - info " * Directory not found" + info " * Directory not found" resulttestjson "INFO" "Directory not found" currentScore=$((currentScore + 0)) fi @@ -239,7 +239,7 @@ check_1_2_6() { fi else info "$check_1_2_6" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi @@ -276,7 +276,7 @@ check_1_2_7() { fi else info "$check_1_2_7" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi @@ -313,7 +313,7 @@ check_1_2_8() { fi else info "$check_1_2_8" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi @@ -350,7 +350,7 @@ check_1_2_9() { fi else info "$check_1_2_9" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi @@ -387,7 +387,7 @@ check_1_2_10() { fi else info "$check_1_2_10" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi @@ -424,7 +424,7 @@ check_1_2_11() { fi else info "$check_1_2_11" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi @@ -461,7 +461,7 @@ check_1_2_12() { fi else info "$check_1_2_12" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi From 82644982a80274f697a030e9208718e570ad2440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Tue, 27 Aug 2019 14:53:42 +0200 Subject: [PATCH 08/25] move old 2.13 to community checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- tests/99_community_checks.sh | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/99_community_checks.sh b/tests/99_community_checks.sh index ef9177f..9ad1774 100644 --- a/tests/99_community_checks.sh +++ b/tests/99_community_checks.sh @@ -21,6 +21,39 @@ check_c_1() { fi } +# check_c_2 +check_c_2() { + docker_version=$(docker version | grep -i -A2 '^server' | grep ' Version:' \ + | awk '{print $NF; exit}' | tr -d '[:alpha:]-,.' | cut -c 1-4) + totalChecks=$((totalChecks + 1)) + + id_c_2="C.2" + desc_c_2="Ensure operations on legacy registry (v1) are Disabled" + check_c_2="$id_c_2 - $desc_c_2" + starttestjson "$id_c_2" "$desc_c_2" + + if [ "$docker_version" -lt 1712 ]; then + if get_docker_configuration_file_args 'disable-legacy-registry' | grep 'true' >/dev/null 2>&1; then + pass "$check_c_2" + 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_c_2" + resulttestjson "PASS" + currentScore=$((currentScore + 1)) + else + warn "$check_c_2" + resulttestjson "WARN" + currentScore=$((currentScore - 1)) + fi + else + desc_c_2="$desc_c_2 (Deprecated)" + check_c_2="$id_c_2 - $desc_c_2" + info "$check_c_2" + resulttestjson "INFO" + fi +} + check_c_end() { endsectionjson } From 6c6d0836a4fbb4d43fd13265cf6c2b1fa191a079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Tue, 27 Aug 2019 14:54:08 +0200 Subject: [PATCH 09/25] first pass on section 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- tests/2_docker_daemon_configuration.sh | 103 +++++++++---------------- 1 file changed, 35 insertions(+), 68 deletions(-) diff --git a/tests/2_docker_daemon_configuration.sh b/tests/2_docker_daemon_configuration.sh index 9f24e8f..90210af 100644 --- a/tests/2_docker_daemon_configuration.sh +++ b/tests/2_docker_daemon_configuration.sh @@ -316,21 +316,22 @@ check_2_12() { # 2.13 check_2_13() { - docker_version=$(docker version | grep -i -A2 '^server' | grep ' Version:' \ - | awk '{print $NF; exit}' | tr -d '[:alpha:]-,.' | cut -c 1-4) - totalChecks=$((totalChecks + 1)) - id_2_13="2.13" - desc_2_13="Ensure operations on legacy registry (v1) are Disabled" + desc_2_13="Ensure live restore is Enabled" check_2_13="$id_2_13 - $desc_2_13" starttestjson "$id_2_13" "$desc_2_13" - if [ "$docker_version" -lt 1712 ]; then - if get_docker_configuration_file_args 'disable-legacy-registry' | grep 'true' >/dev/null 2>&1; then - pass "$check_2_13" + 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_13" + 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_13 (Incompatible with swarm mode)" resulttestjson "PASS" currentScore=$((currentScore + 1)) - elif get_docker_effective_command_line_args '--disable-legacy-registry' | grep "disable-legacy-registry" >/dev/null 2>&1; then + elif get_docker_effective_command_line_args '--live-restore' | grep "live-restore" >/dev/null 2>&1; then pass "$check_2_13" resulttestjson "PASS" currentScore=$((currentScore + 1)) @@ -339,94 +340,83 @@ check_2_13() { resulttestjson "WARN" currentScore=$((currentScore - 1)) fi - else - desc_2_13="$desc_2_13 (Deprecated)" - check_2_13="$id_2_13 - $desc_2_13" - info "$check_2_13" - resulttestjson "INFO" fi } # 2.14 check_2_14() { id_2_14="2.14" - desc_2_14="Ensure live restore is Enabled" + desc_2_14="Ensure Userland Proxy is Disabled" 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 + if get_docker_configuration_file_args 'userland-proxy' | grep false >/dev/null 2>&1; then + pass "$check_2_14" + 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_14" 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)" - 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" - resulttestjson "PASS" - currentScore=$((currentScore + 1)) - else - warn "$check_2_14" - resulttestjson "WARN" - currentScore=$((currentScore - 1)) - fi + warn "$check_2_14" + resulttestjson "WARN" + currentScore=$((currentScore - 1)) fi } # 2.15 check_2_15() { id_2_15="2.15" - desc_2_15="Ensure Userland Proxy is Disabled" + desc_2_15="Ensure that a daemon-wide custom seccomp profile is applied if appropriate" 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" - 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 + if docker info --format '{{ .SecurityOptions }}' | grep 'name=seccomp,profile=default' 2>/dev/null 1>&2; then pass "$check_2_15" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - warn "$check_2_15" - resulttestjson "WARN" - currentScore=$((currentScore - 1)) + info "$check_2_15" + resulttestjson "INFO" + currentScore=$((currentScore + 0)) fi } # 2.16 check_2_16() { id_2_16="2.16" - desc_2_16="Ensure daemon-wide custom seccomp profile is applied, if needed" + desc_2_16="Ensure that experimental features are not implemented in production" 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 + if docker version -f '{{.Server.Experimental}}' | grep false 2>/dev/null 1>&2; then pass "$check_2_16" resulttestjson "PASS" currentScore=$((currentScore + 1)) else - info "$check_2_16" - resulttestjson "INFO" - currentScore=$((currentScore + 0)) + warn "$check_2_16" + resulttestjson "WARN" + currentScore=$((currentScore - 1)) fi } # 2.17 check_2_17() { id_2_17="2.17" - desc_2_17="Ensure experimental features are avoided in production" + desc_2_17="Ensure containers are restricted from acquiring new privileges" 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 + if get_docker_effective_command_line_args '--no-new-privileges' | grep "no-new-privileges" >/dev/null 2>&1; then + pass "$check_2_17" + resulttestjson "PASS" + currentScore=$((currentScore + 1)) + elif get_docker_configuration_file_args 'no-new-privileges' | grep true >/dev/null 2>&1; then pass "$check_2_17" resulttestjson "PASS" currentScore=$((currentScore + 1)) @@ -437,29 +427,6 @@ check_2_17() { fi } -# 2.18 -check_2_18() { - 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" - 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" - resulttestjson "PASS" - currentScore=$((currentScore + 1)) - else - warn "$check_2_18" - resulttestjson "WARN" - currentScore=$((currentScore - 1)) - fi -} - check_2_end() { endsectionjson } From bb0d65ceb1d81387e68e5db0c5aa2f8e3353dd03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Tue, 27 Aug 2019 14:54:23 +0200 Subject: [PATCH 10/25] update function list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- functions_lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions_lib.sh b/functions_lib.sh index 60a898f..dfb8d93 100644 --- a/functions_lib.sh +++ b/functions_lib.sh @@ -40,7 +40,6 @@ docker_daemon_configuration() { check_2_15 check_2_16 check_2_17 - check_2_18 check_2_end } @@ -147,6 +146,7 @@ docker_swarm_configuration() { community_checks() { check_c check_c_1 + check_c_2 check_c_end } From f96859705112b3f3b2394eb6473d858cef1cf5b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Tue, 27 Aug 2019 15:13:19 +0200 Subject: [PATCH 11/25] first pass on section 3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- functions_lib.sh | 2 + tests/3_docker_daemon_configuration_files.sh | 68 ++++++++++++++++++-- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/functions_lib.sh b/functions_lib.sh index dfb8d93..13ea1e7 100644 --- a/functions_lib.sh +++ b/functions_lib.sh @@ -65,6 +65,8 @@ docker_daemon_files() { check_3_18 check_3_19 check_3_20 + check_3_21 + check_3_22 check_3_end } diff --git a/tests/3_docker_daemon_configuration_files.sh b/tests/3_docker_daemon_configuration_files.sh index 74831a6..3f488c3 100644 --- a/tests/3_docker_daemon_configuration_files.sh +++ b/tests/3_docker_daemon_configuration_files.sh @@ -40,7 +40,7 @@ check_3_1() { # 3.2 check_3_2() { id_3_2="3.2" - desc_3_2="Ensure that docker.service file permissions are set to 644 or more restrictive" + desc_3_2="Ensure that docker.service file permissions are appropriately set" check_3_2="$id_3_2 - $desc_3_2" starttestjson "$id_3_2" "$desc_3_2" @@ -582,21 +582,21 @@ check_3_19() { # 3.20 check_3_20() { id_3_20="3.20" - desc_3_20="Ensure that /etc/default/docker file permissions are set to 644 or more restrictive" + desc_3_20="Ensure that the /etc/sysconfig/docker file ownership is set to root:root" check_3_20="$id_3_20 - $desc_3_20" starttestjson "$id_3_20" "$desc_3_20" totalChecks=$((totalChecks + 1)) - file="/etc/default/docker" + file="/etc/sysconfig/docker" if [ -f "$file" ]; then - if [ "$(stat -c %a $file)" -eq 644 ] || [ "$(stat -c %a $file)" -eq 600 ]; then + if [ "$(stat -c %U:%G $file)" = 'root:root' ]; then pass "$check_3_20" resulttestjson "PASS" currentScore=$((currentScore + 1)) else warn "$check_3_20" - warn " * Wrong permissions for $file" - resulttestjson "WARN" "Wrong permissions for $file" + warn " * Wrong ownership for $file" + resulttestjson "WARN" "Wrong ownership for $file" currentScore=$((currentScore - 1)) fi else @@ -607,6 +607,62 @@ check_3_20() { fi } +# 3.21 +check_3_21() { + id_3_21="3.21" + desc_3_21="Ensure that /etc/default/docker file permissions are set to 644 or more restrictive" + check_3_21="$id_3_21 - $desc_3_21" + starttestjson "$id_3_21" "$desc_3_21" + + totalChecks=$((totalChecks + 1)) + file="/etc/default/docker" + if [ -f "$file" ]; then + if [ "$(stat -c %a $file)" -eq 644 ] || [ "$(stat -c %a $file)" -eq 600 ]; then + pass "$check_3_21" + resulttestjson "PASS" + currentScore=$((currentScore + 1)) + else + warn "$check_3_21" + warn " * Wrong permissions for $file" + resulttestjson "WARN" "Wrong permissions for $file" + currentScore=$((currentScore - 1)) + fi + else + info "$check_3_21" + info " * File not found" + resulttestjson "INFO" "File not found" + currentScore=$((currentScore + 0)) + fi +} + +# 3.22 +check_3_22() { + id_3_22="3.22" + desc_3_22="Ensure that /etc/default/docker file permissions are set to 644 or more restrictive" + check_3_22="$id_3_22 - $desc_3_22" + starttestjson "$id_3_22" "$desc_3_22" + + totalChecks=$((totalChecks + 1)) + file="/etc/default/docker" + if [ -f "$file" ]; then + if [ "$(stat -c %a $file)" -eq 644 ] || [ "$(stat -c %a $file)" -eq 600 ]; then + pass "$check_3_22" + resulttestjson "PASS" + currentScore=$((currentScore + 1)) + else + warn "$check_3_22" + warn " * Wrong permissions for $file" + resulttestjson "WARN" "Wrong permissions for $file" + currentScore=$((currentScore - 1)) + fi + else + info "$check_3_22" + info " * File not found" + resulttestjson "INFO" "File not found" + currentScore=$((currentScore + 0)) + fi +} + check_3_end() { endsectionjson } From e5c22c5f0160b5c943a519f7ea2b8b8bd667dfc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Tue, 27 Aug 2019 15:25:54 +0200 Subject: [PATCH 12/25] first pass on section 4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- tests/4_container_images.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/4_container_images.sh b/tests/4_container_images.sh index 0df2676..2592952 100644 --- a/tests/4_container_images.sh +++ b/tests/4_container_images.sh @@ -79,7 +79,7 @@ check_4_1() { # 4.2 check_4_2() { id_4_2="4.2" - desc_4_2="Ensure that containers use trusted base images" + desc_4_2="Ensure that containers use only trusted base images" check_4_2="$id_4_2 - $desc_4_2" starttestjson "$id_4_2" "$desc_4_2" @@ -92,7 +92,7 @@ check_4_2() { # 4.3 check_4_3() { id_4_3="4.3" - desc_4_3="Ensure unnecessary packages are not installed in the container" + desc_4_3="Ensure that unnecessary packages are not installed in the container" check_4_3="$id_4_3 - $desc_4_3" starttestjson "$id_4_3" "$desc_4_3" @@ -137,7 +137,7 @@ check_4_5() { # 4.6 check_4_6() { id_4_6="4.6" - desc_4_6="Ensure HEALTHCHECK instructions have been added to the container image" + desc_4_6="Ensure that HEALTHCHECK instructions have been added to container images" check_4_6="$id_4_6 - $desc_4_6" starttestjson "$id_4_6" "$desc_4_6" @@ -203,7 +203,7 @@ check_4_7() { # 4.8 check_4_8() { id_4_8="4.8" - desc_4_8="Ensure setuid and setgid permissions are removed in the images" + desc_4_8="Ensure setuid and setgid permissions are removed" check_4_8="$id_4_8 - $desc_4_8" starttestjson "$id_4_8" "$desc_4_8" @@ -216,7 +216,7 @@ check_4_8() { # 4.9 check_4_9() { id_4_9="4.9" - desc_4_9="Ensure COPY is used instead of ADD in Dockerfile" + desc_4_9="Ensure that COPY is used instead of ADD in Dockerfiles" check_4_9="$id_4_9 - $desc_4_9" starttestjson "$id_4_9" "$desc_4_9" @@ -263,7 +263,7 @@ check_4_10() { # 4.11 check_4_11() { id_4_11="4.11" - desc_4_11="Ensure verified packages are only Installed" + desc_4_11="Ensure only verified packages are installed" check_4_11="$id_4_11 - $desc_4_11" starttestjson "$id_4_11" "$desc_4_11" From 0b007baf7e361ec04a556902ff20b104d6466a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Tue, 27 Aug 2019 15:43:29 +0200 Subject: [PATCH 13/25] first pass on section 5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- tests/5_container_runtime.sh | 40 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/5_container_runtime.sh b/tests/5_container_runtime.sh index 9db54d8..1aefd80 100644 --- a/tests/5_container_runtime.sh +++ b/tests/5_container_runtime.sh @@ -29,7 +29,7 @@ check_5_1() { fi id_5_1="5.1" - desc_5_1="Ensure AppArmor Profile is Enabled" + desc_5_1="Ensure that, if applicable, an AppArmor Profile is enabled " check_5_1="$id_5_1 - $desc_5_1" starttestjson "$id_5_1" "$desc_5_1" @@ -71,7 +71,7 @@ check_5_2() { fi id_5_2="5.2" - desc_5_2="Ensure SELinux security options are set, if applicable" + desc_5_2="Ensure that, if applicable, SELinux security options are set" check_5_2="$id_5_2 - $desc_5_2" starttestjson "$id_5_2" "$desc_5_2" @@ -158,7 +158,7 @@ check_5_4() { fi id_5_4="5.4" - desc_5_4="Ensure privileged containers are not used" + desc_5_4="Ensure that privileged containers are not used" check_5_4="$id_5_4 - $desc_5_4" starttestjson "$id_5_4" "$desc_5_4" @@ -262,7 +262,7 @@ check_5_6() { fi id_5_6="5.6" - desc_5_6="Ensure ssh is not run within containers" + desc_5_6="Ensure sshd is not run within containers" check_5_6="$id_5_6 - $desc_5_6" starttestjson "$id_5_6" "$desc_5_6" @@ -364,7 +364,7 @@ check_5_8() { fi id_5_8="5.8" - desc_5_8="Ensure only needed ports are open on the container" + desc_5_8="Ensure that only needed ports are open on the container" check_5_8="$id_5_8 - $desc_5_8" starttestjson "$id_5_8" "$desc_5_8" @@ -423,7 +423,7 @@ check_5_10() { fi id_5_10="5.10" - desc_5_10="Ensure memory usage for container is limited" + desc_5_10="Ensure that the memory usage for containers is limited" check_5_10="$id_5_10 - $desc_5_10" starttestjson "$id_5_10" "$desc_5_10" @@ -515,7 +515,7 @@ check_5_12() { fi id_5_12="5.12" - desc_5_12="Ensure the container's root filesystem is mounted as read only" + desc_5_12="Ensure that 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" @@ -557,7 +557,7 @@ check_5_13() { fi id_5_13="5.13" - desc_5_13="Ensure incoming container traffic is binded to a specific host interface" + desc_5_13="Ensure that incoming container traffic is bound to a specific host interface" check_5_13="$id_5_13 - $desc_5_13" starttestjson "$id_5_13" "$desc_5_13" @@ -599,7 +599,7 @@ check_5_14() { fi id_5_14="5.14" - desc_5_14="Ensure 'on-failure' container restart policy is set to '5'" + desc_5_14="Ensure that the '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" @@ -725,7 +725,7 @@ check_5_17() { fi id_5_17="5.17" - desc_5_17="Ensure host devices are not directly exposed to containers" + desc_5_17="Ensure that host devices are not directly exposed to containers" check_5_17="$id_5_17 - $desc_5_17" starttestjson "$id_5_17" "$desc_5_17" @@ -767,7 +767,7 @@ check_5_18() { fi id_5_18="5.18" - desc_5_18="Ensure the default ulimit is overwritten at runtime, only if needed" + desc_5_18="Ensure that the default ulimit is overwritten at runtime if needed" check_5_18="$id_5_18 - $desc_5_18" starttestjson "$id_5_18" "$desc_5_18" @@ -950,7 +950,7 @@ check_5_23() { fi id_5_23="5.23" - desc_5_23="Ensure docker exec commands are not used with user option" + desc_5_23="Ensure that docker exec commands are not used with the user=root option" check_5_23="$id_5_23 - $desc_5_23" starttestjson "$id_5_23" "$desc_5_23" @@ -967,7 +967,7 @@ check_5_24() { fi id_5_24="5.24" - desc_5_24="Ensure cgroup usage is confirmed" + desc_5_24="Ensure that cgroup usage is confirmed" check_5_24="$id_5_24 - $desc_5_24" starttestjson "$id_5_24" "$desc_5_24" @@ -1008,7 +1008,7 @@ check_5_25() { return fi id_5_25="5.25" - desc_5_25="Ensure the container is restricted from acquiring additional privileges" + desc_5_25="Ensure that the container is restricted from acquiring additional privileges" check_5_25="$id_5_25 - $desc_5_25" starttestjson "$id_5_25" "$desc_5_25" @@ -1048,7 +1048,7 @@ check_5_26() { fi id_5_26="5.26" - desc_5_26="Ensure container health is checked at runtime" + desc_5_26="Ensure that container health is checked at runtime" check_5_26="$id_5_26 - $desc_5_26" starttestjson "$id_5_26" "$desc_5_26" @@ -1086,7 +1086,7 @@ check_5_27() { fi id_5_27="5.27" - desc_5_27="Ensure docker commands always get the latest version of the image" + desc_5_27="Ensure that Docker commands always make use of the latest version of their image" check_5_27="$id_5_27 - $desc_5_27" starttestjson "$id_5_27" "$desc_5_27" @@ -1103,7 +1103,7 @@ check_5_28() { fi id_5_28="5.28" - desc_5_28="Ensure PIDs cgroup limit is used" + desc_5_28="Ensure that the PIDs cgroup limit is used" check_5_28="$id_5_28 - $desc_5_28" starttestjson "$id_5_28" "$desc_5_28" @@ -1145,7 +1145,7 @@ check_5_29() { fi id_5_29="5.29" - desc_5_29="Ensure Docker's default bridge docker0 is not used" + desc_5_29="Ensure that Docker's default bridge 'docker0' is not used" check_5_29="$id_5_29 - $desc_5_29" starttestjson "$id_5_29" "$desc_5_29" @@ -1198,7 +1198,7 @@ check_5_30() { fi id_5_30="5.30" - desc_5_30="Ensure the host's user namespaces is not shared" + desc_5_30="Ensure that the host's user namespaces are not shared" check_5_30="$id_5_30 - $desc_5_30" starttestjson "$id_5_30" "$desc_5_30" @@ -1238,7 +1238,7 @@ check_5_31() { fi id_5_31="5.31" - desc_5_31="Ensure the Docker socket is not mounted inside any containers" + desc_5_31="Ensure that 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" From 3d6dd819569c5eb378d42d1ca342d7f08ad7f59c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Tue, 27 Aug 2019 15:52:06 +0200 Subject: [PATCH 14/25] first pass on section 6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- tests/6_docker_security_operations.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/6_docker_security_operations.sh b/tests/6_docker_security_operations.sh index f2ec50c..9216e80 100644 --- a/tests/6_docker_security_operations.sh +++ b/tests/6_docker_security_operations.sh @@ -12,7 +12,7 @@ check_6() { # 6.1 check_6_1() { id_6_1="6.1" - desc_6_1="Avoid image sprawl" + desc_6_1="Ensure that image sprawl is avoided" check_6_1="$id_6_1 - $desc_6_1" starttestjson "$id_6_1" "$desc_6_1" @@ -39,7 +39,7 @@ check_6_1() { # 6.2 check_6_2() { id_6_2="6.2" - desc_6_2="Avoid container sprawl" + desc_6_2="Ensure that container sprawl is avoided" check_6_2="$id_6_2 - $desc_6_2" starttestjson "$id_6_2" "$desc_6_2" From ca3714bc16694ae916d88c3e9f196ebd9ea5465a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Tue, 27 Aug 2019 16:03:29 +0200 Subject: [PATCH 15/25] first pass on section 7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- tests/7_docker_swarm_configuration.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/7_docker_swarm_configuration.sh b/tests/7_docker_swarm_configuration.sh index be1dd7b..00d340f 100644 --- a/tests/7_docker_swarm_configuration.sh +++ b/tests/7_docker_swarm_configuration.sh @@ -31,14 +31,14 @@ check_7_1() { # 7.2 check_7_2() { id_7_2="7.2" - desc_7_2="Ensure the minimum number of manager nodes have been created in a swarm" + desc_7_2="Ensure that 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 + if [ "$managernodes" -eq 1 ]; then pass "$check_7_2" resulttestjson "PASS" currentScore=$((currentScore + 1)) @@ -57,7 +57,7 @@ check_7_2() { # 7.3 check_7_3() { id_7_3="7.3" - desc_7_3="Ensure swarm services are binded to a specific host interface" + desc_7_3="Ensure that swarm services are bound to a specific host interface" check_7_3="$id_7_3 - $desc_7_3" starttestjson "$id_7_3" "$desc_7_3" @@ -83,7 +83,7 @@ check_7_3() { # 7.4 check_7_4() { id_7_4="7.4" - desc_7_4="Ensure data exchanged between containers are encrypted on different nodes on the overlay network" + desc_7_4="Ensure that all Docker swarm overlay networks are encrypted" check_7_4="$id_7_4 - $desc_7_4" starttestjson "$id_7_4" "$desc_7_4" @@ -116,7 +116,7 @@ check_7_4() { # 7.5 check_7_5() { id_7_5="7.5" - desc_7_5="Ensure Docker's secret management commands are used for managing secrets in a Swarm cluster" + desc_7_5="Ensure that 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" @@ -141,7 +141,7 @@ check_7_5() { # 7.6 check_7_6() { id_7_6="7.6" - desc_7_6="Ensure swarm manager is run in auto-lock mode" + desc_7_6="Ensure that swarm manager is run in auto-lock mode" check_7_6="$id_7_6 - $desc_7_6" starttestjson "$id_7_6" "$desc_7_6" @@ -166,7 +166,7 @@ check_7_6() { # 7.7 check_7_7() { id_7_7="7.7" - desc_7_7="Ensure swarm manager auto-lock key is rotated periodically" + desc_7_7="Ensure that the swarm manager auto-lock key is rotated periodically" check_7_7="$id_7_7 - $desc_7_7" starttestjson "$id_7_7" "$desc_7_7" @@ -185,7 +185,7 @@ check_7_7() { # 7.8 check_7_8() { id_7_8="7.8" - desc_7_8="Ensure node certificates are rotated as appropriate" + desc_7_8="Ensure that node certificates are rotated as appropriate" check_7_8="$id_7_8 - $desc_7_8" starttestjson "$id_7_8" "$desc_7_8" @@ -210,7 +210,7 @@ check_7_8() { # 7.9 check_7_9() { id_7_9="7.9" - desc_7_9="Ensure CA certificates are rotated as appropriate" + desc_7_9="Ensure that CA certificates are rotated as appropriate" check_7_9="$id_7_9 - $desc_7_9" starttestjson "$id_7_9" "$desc_7_9" @@ -229,7 +229,7 @@ check_7_9() { # 7.10 check_7_10() { id_7_10="7.10" - desc_7_10="Ensure management plane traffic has been separated from data plane traffic" + desc_7_10="Ensure that management plane traffic is separated from data plane traffic" check_7_10="$id_7_10 - $desc_7_10" starttestjson "$id_7_10" "$desc_7_10" From bcd6e5dd55cb0571d7ecbb32485bbb19cee77dc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Tue, 27 Aug 2019 16:10:59 +0200 Subject: [PATCH 16/25] json sections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- tests/1_host_configuration.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/1_host_configuration.sh b/tests/1_host_configuration.sh index c7f8d5d..9947163 100644 --- a/tests/1_host_configuration.sh +++ b/tests/1_host_configuration.sh @@ -58,6 +58,10 @@ check_1_1_2() { fi } +check_1_1_end() { + endsectionjson +} + check_1_2() { logit "" id_1_2="1.2" @@ -467,6 +471,10 @@ check_1_2_12() { fi } +check_1_2_end() { + endsectionjson +} + check_1_end() { endsectionjson } From 7110df800b40f67ae7c4184f0236f316cc28907c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Tue, 27 Aug 2019 16:11:38 +0200 Subject: [PATCH 17/25] section 8 docker enterprise skeleton MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- tests/8_docker_enterprise_configuration.sh | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 tests/8_docker_enterprise_configuration.sh diff --git a/tests/8_docker_enterprise_configuration.sh b/tests/8_docker_enterprise_configuration.sh new file mode 100644 index 0000000..56228fc --- /dev/null +++ b/tests/8_docker_enterprise_configuration.sh @@ -0,0 +1,40 @@ +#!/bin/sh + +check_8() { + logit "\n" + id_8="8" + desc_8="Docker Enterprise Configuration" + check_8="$id_8 - $desc_8" + info "$check_8" + startsectionjson "$id_8" "$desc_8" +} + +check_8_1() { + logit "\n" + id_8_1="8.1" + desc_8_1="Universal Control Plane Configuration" + check_8_1="$id_8_1 - $desc_8_1" + info "$check_8_1" + startsectionjson "$id_8_1" "$desc_8_1" +} + +check_8_1_end() { + endsectionjson +} + +check_8_2() { + logit "\n" + id_8_2="8.2" + desc_8_2="Docker Trusted Registry Configuration" + check_8_2="$id_8_2 - $desc_8_2" + info "$check_8_2" + startsectionjson "$id_8_2" "$desc_8_2" +} + +check_8_2_end() { + endsectionjson +} + +check_8_end() { + endsectionjson +} From adb6a42c4a0c388fc49a2c022b66980ab1d86122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Tue, 27 Aug 2019 16:11:55 +0200 Subject: [PATCH 18/25] update function names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- functions_lib.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/functions_lib.sh b/functions_lib.sh index 13ea1e7..aeab107 100644 --- a/functions_lib.sh +++ b/functions_lib.sh @@ -5,6 +5,7 @@ host_configuration() { check_1_1 check_1_1_1 check_1_1_2 + check_1_1_end check_1_2 check_1_2_1 check_1_2_2 @@ -18,6 +19,7 @@ host_configuration() { check_1_2_10 check_1_2_11 check_1_2_12 + check_1_2_end check_1_end } @@ -145,6 +147,15 @@ docker_swarm_configuration() { check_7_end } +docker_enterprise_configuration() { + check_8 + check_8_1 + check_8_1_end + check_8_2 + check_8_2_end + check_8_end +} + community_checks() { check_c check_c_1 @@ -161,6 +172,7 @@ cis() { container_runtime docker_security_operations docker_swarm_configuration + docker_enterprise_configuration } # Community contributed From a785c02c59723d8d2817012d815015cc7a52205f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Wed, 28 Aug 2019 10:26:44 +0200 Subject: [PATCH 19/25] add INFO for section 8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- tests/8_docker_enterprise_configuration.sh | 144 +++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/tests/8_docker_enterprise_configuration.sh b/tests/8_docker_enterprise_configuration.sh index 56228fc..0384b87 100644 --- a/tests/8_docker_enterprise_configuration.sh +++ b/tests/8_docker_enterprise_configuration.sh @@ -1,5 +1,14 @@ #!/bin/sh +check_product_license() { + if docker info -f '{{ .ProductLicense }}' | grep -qi 'Community Engine'; then + info " * Community Engine license, skipping section 8." + enterprise_license=0 + else + enterprise_license=1 + fi +} + check_8() { logit "\n" id_8="8" @@ -18,6 +27,125 @@ check_8_1() { startsectionjson "$id_8_1" "$desc_8_1" } +# 8.1.1 +check_8_1_1() { + if [ "$enterprise_license" -ne 1 ]; then + return + fi + + id_8_1_1="8.1.1" + desc_8_1_1="Configure the LDAP authentication service" + check_8_1_1="$id_8_1_1 - $desc_8_1_1" + starttestjson "$id_8_1_1" "$desc_8_1_1" + + totalChecks=$((totalChecks + 1)) + note "$check_8_1_1" + resulttestjson "INFO" + currentScore=$((currentScore + 0)) +} + +# 8.1.2 +check_8_1_2() { + if [ "$enterprise_license" -ne 1 ]; then + return + fi + + id_8_1_2="8.1.2" + desc_8_1_2="Use external certificates" + check_8_1_2="$id_8_1_2 - $desc_8_1_2" + starttestjson "$id_8_1_2" "$desc_8_1_2" + + totalChecks=$((totalChecks + 1)) + note "$check_8_1_2" + resulttestjson "INFO" + currentScore=$((currentScore + 0)) +} + +# 8.1.3 +check_8_1_3() { + if [ "$enterprise_license" -ne 1 ]; then + return + fi + + id_8_1_3="8.1.3" + desc_8_1_3="Enforce the use of client certificate bundles for unprivileged users" + check_8_1_3="$id_8_1_3 - $desc_8_1_3" + starttestjson "$id_8_1_3" "$desc_8_1_3" + + totalChecks=$((totalChecks + 1)) + note "$check_8_1_3" + resulttestjson "INFO" + currentScore=$((currentScore + 0)) +} + +# 8.1.4 +check_8_1_4() { + if [ "$enterprise_license" -ne 1 ]; then + return + fi + + id_8_1_4="8.1.4" + desc_8_1_4="Configure applicable cluster role-based access control policies" + check_8_1_4="$id_8_1_4 - $desc_8_1_4" + starttestjson "$id_8_1_4" "$desc_8_1_4" + + totalChecks=$((totalChecks + 1)) + note "$check_8_1_4" + resulttestjson "INFO" + currentScore=$((currentScore + 0)) +} + +# 8.1.5 +check_8_1_5() { + if [ "$enterprise_license" -ne 1 ]; then + return + fi + + id_8_1_5="8.1.5" + desc_8_1_5="Enable signed image enforcement" + check_8_1_5="$id_8_1_5 - $desc_8_1_5" + starttestjson "$id_8_1_5" "$desc_8_1_5" + + totalChecks=$((totalChecks + 1)) + note "$check_8_1_5" + resulttestjson "INFO" + currentScore=$((currentScore + 0)) +} + +# 8.1.6 +check_8_1_6() { + if [ "$enterprise_license" -ne 1 ]; then + return + fi + + id_8_1_6="8.1.6" + desc_8_1_6="Set the Per-User Session Limit to a value of '3' or lower" + check_8_1_6="$id_8_1_6 - $desc_8_1_6" + starttestjson "$id_8_1_6" "$desc_8_1_6" + + totalChecks=$((totalChecks + 1)) + note "$check_8_1_6" + resulttestjson "INFO" + currentScore=$((currentScore + 0)) +} + +# 8.1.7 +check_8_1_7() { + if [ "$enterprise_license" -ne 1 ]; then + return + fi + + id_8_1_7="8.1.7" + desc_8_1_7="Set the 'Lifetime Minutes' and 'Renewal Threshold Minutes' values to '15' or lower and '0' respectively" + check_8_1_7="$id_8_1_7 - $desc_8_1_7" + starttestjson "$id_8_1_7" "$desc_8_1_7" + + totalChecks=$((totalChecks + 1)) + note "$check_8_1_7" + resulttestjson "INFO" + currentScore=$((currentScore + 0)) +} + check_8_1_end() { endsectionjson } @@ -31,6 +159,22 @@ check_8_2() { startsectionjson "$id_8_2" "$desc_8_2" } +check_8_2_1() { + if [ "$enterprise_license" -ne 1 ]; then + return + fi + + id_8_2_1="8.2.1" + desc_8_2_1="Enable image vulnerability scanning" + check_8_2_1="$id_8_2_1 - $desc_8_2_1" + starttestjson "$id_8_2_1" "$desc_8_2_1" + + totalChecks=$((totalChecks + 1)) + note "$check_8_2_1" + resulttestjson "INFO" + currentScore=$((currentScore + 0)) +} + check_8_2_end() { endsectionjson } From d7f1d9753ab27e359b6455da0306c9f42080c56a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Wed, 28 Aug 2019 11:49:22 +0200 Subject: [PATCH 20/25] ignore section 8 if community edition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- functions_lib.sh | 9 ++++++++ tests/8_docker_enterprise_configuration.sh | 26 ++++++++++++++-------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/functions_lib.sh b/functions_lib.sh index aeab107..037eb52 100644 --- a/functions_lib.sh +++ b/functions_lib.sh @@ -149,9 +149,18 @@ docker_swarm_configuration() { docker_enterprise_configuration() { check_8 + check_product_license check_8_1 + check_8_1_1 + check_8_1_2 + check_8_1_3 + check_8_1_4 + check_8_1_5 + check_8_1_6 + check_8_1_7 check_8_1_end check_8_2 + check_8_2_1 check_8_2_end check_8_end } diff --git a/tests/8_docker_enterprise_configuration.sh b/tests/8_docker_enterprise_configuration.sh index 0384b87..f8bca33 100644 --- a/tests/8_docker_enterprise_configuration.sh +++ b/tests/8_docker_enterprise_configuration.sh @@ -1,14 +1,5 @@ #!/bin/sh -check_product_license() { - if docker info -f '{{ .ProductLicense }}' | grep -qi 'Community Engine'; then - info " * Community Engine license, skipping section 8." - enterprise_license=0 - else - enterprise_license=1 - fi -} - check_8() { logit "\n" id_8="8" @@ -18,7 +9,20 @@ check_8() { startsectionjson "$id_8" "$desc_8" } +check_product_license() { + if docker version | grep -qi '^Client.*Community$'; then + info " * Community Engine license, skipping section 8" + enterprise_license=0 + else + enterprise_license=1 + fi +} + check_8_1() { + if [ "$enterprise_license" -ne 1 ]; then + return + fi + logit "\n" id_8_1="8.1" desc_8_1="Universal Control Plane Configuration" @@ -151,6 +155,10 @@ check_8_1_end() { } check_8_2() { + if [ "$enterprise_license" -ne 1 ]; then + return + fi + logit "\n" id_8_2="8.2" desc_8_2="Docker Trusted Registry Configuration" From 17c6262d2fb3ce963fccc0ddce289185b2165998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Wed, 28 Aug 2019 12:14:35 +0200 Subject: [PATCH 21/25] formating MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- tests/1_host_configuration.sh | 1 - tests/3_docker_daemon_configuration_files.sh | 52 ++++++++++---------- tests/5_container_runtime.sh | 2 +- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/tests/1_host_configuration.sh b/tests/1_host_configuration.sh index 9947163..8d88303 100644 --- a/tests/1_host_configuration.sh +++ b/tests/1_host_configuration.sh @@ -478,4 +478,3 @@ check_1_2_end() { check_1_end() { endsectionjson } - diff --git a/tests/3_docker_daemon_configuration_files.sh b/tests/3_docker_daemon_configuration_files.sh index 3f488c3..ec440bb 100644 --- a/tests/3_docker_daemon_configuration_files.sh +++ b/tests/3_docker_daemon_configuration_files.sh @@ -299,13 +299,13 @@ check_3_10() { currentScore=$((currentScore + 1)) else warn "$check_3_10" - warn " * Wrong permissions for $tlscacert" + warn " * Wrong permissions for $tlscacert" resulttestjson "WARN" "Wrong permissions for $tlscacert" currentScore=$((currentScore - 1)) fi else info "$check_3_10" - info " * No TLS CA certificate found" + info " * No TLS CA certificate found" resulttestjson "INFO" "No TLS CA certificate found" currentScore=$((currentScore + 0)) fi @@ -331,13 +331,13 @@ check_3_11() { currentScore=$((currentScore + 1)) else warn "$check_3_11" - warn " * Wrong ownership for $tlscert" + warn " * Wrong ownership for $tlscert" resulttestjson "WARN" "Wrong ownership for $tlscert" currentScore=$((currentScore - 1)) fi else info "$check_3_11" - info " * No TLS Server certificate found" + info " * No TLS Server certificate found" resulttestjson "INFO" "No TLS Server certificate found" currentScore=$((currentScore + 0)) fi @@ -363,13 +363,13 @@ check_3_12() { currentScore=$((currentScore + 1)) else warn "$check_3_12" - warn " * Wrong permissions for $tlscert" + warn " * Wrong permissions for $tlscert" resulttestjson "WARN" "Wrong permissions for $tlscert" currentScore=$((currentScore - 1)) fi else info "$check_3_12" - info " * No TLS Server certificate found" + info " * No TLS Server certificate found" resulttestjson "INFO" "No TLS Server certificate found" currentScore=$((currentScore + 0)) fi @@ -395,13 +395,13 @@ check_3_13() { currentScore=$((currentScore + 1)) else warn "$check_3_13" - warn " * Wrong ownership for $tlskey" + warn " * Wrong ownership for $tlskey" resulttestjson "WARN" "Wrong ownership for $tlskey" currentScore=$((currentScore - 1)) fi else info "$check_3_13" - info " * No TLS Key found" + info " * No TLS Key found" resulttestjson "INFO" "No TLS Key found" currentScore=$((currentScore + 0)) fi @@ -427,13 +427,13 @@ check_3_14() { currentScore=$((currentScore + 1)) else warn "$check_3_14" - warn " * Wrong permissions for $tlskey" + warn " * Wrong permissions for $tlskey" resulttestjson "WARN" "Wrong permissions for $tlskey" currentScore=$((currentScore - 1)) fi else info "$check_3_14" - info " * No TLS Key found" + info " * No TLS Key found" resulttestjson "INFO" "No TLS Key found" currentScore=$((currentScore + 0)) fi @@ -455,13 +455,13 @@ check_3_15() { currentScore=$((currentScore + 1)) else warn "$check_3_15" - warn " * Wrong ownership for $file" + warn " * Wrong ownership for $file" resulttestjson "WARN" "Wrong ownership for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_15" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi @@ -483,13 +483,13 @@ check_3_16() { currentScore=$((currentScore + 1)) else warn "$check_3_16" - warn " * Wrong permissions for $file" + warn " * Wrong permissions for $file" resulttestjson "WARN" "Wrong permissions for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_16" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi @@ -511,13 +511,13 @@ check_3_17() { currentScore=$((currentScore + 1)) else warn "$check_3_17" - warn " * Wrong ownership for $file" + warn " * Wrong ownership for $file" resulttestjson "WARN" "Wrong ownership for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_17" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi @@ -539,13 +539,13 @@ check_3_18() { currentScore=$((currentScore + 1)) else warn "$check_3_18" - warn " * Wrong permissions for $file" + warn " * Wrong permissions for $file" resulttestjson "WARN" "Wrong permissions for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_18" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi @@ -567,13 +567,13 @@ check_3_19() { currentScore=$((currentScore + 1)) else warn "$check_3_19" - warn " * Wrong ownership for $file" + warn " * Wrong ownership for $file" resulttestjson "WARN" "Wrong ownership for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_19" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi @@ -595,13 +595,13 @@ check_3_20() { currentScore=$((currentScore + 1)) else warn "$check_3_20" - warn " * Wrong ownership for $file" + warn " * Wrong ownership for $file" resulttestjson "WARN" "Wrong ownership for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_20" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi @@ -623,13 +623,13 @@ check_3_21() { currentScore=$((currentScore + 1)) else warn "$check_3_21" - warn " * Wrong permissions for $file" + warn " * Wrong permissions for $file" resulttestjson "WARN" "Wrong permissions for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_21" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi @@ -651,13 +651,13 @@ check_3_22() { currentScore=$((currentScore + 1)) else warn "$check_3_22" - warn " * Wrong permissions for $file" + warn " * Wrong permissions for $file" resulttestjson "WARN" "Wrong permissions for $file" currentScore=$((currentScore - 1)) fi else info "$check_3_22" - info " * File not found" + info " * File not found" resulttestjson "INFO" "File not found" currentScore=$((currentScore + 0)) fi diff --git a/tests/5_container_runtime.sh b/tests/5_container_runtime.sh index 1aefd80..fcaa326 100644 --- a/tests/5_container_runtime.sh +++ b/tests/5_container_runtime.sh @@ -12,7 +12,7 @@ check_5() { check_running_containers() { # If containers is empty, there are no running containers if [ -z "$containers" ]; then - info " * No containers running, skipping Section 5" + info " * No containers running, skipping Section 5" running_containers=0 else running_containers=1 From 7ad1c816e891bc8cb572d7599a8c80d8eac6d0ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Wed, 28 Aug 2019 12:30:34 +0200 Subject: [PATCH 22/25] update README and contributors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- CONTRIBUTING.md | 6 ++++-- CONTRIBUTORS.md | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bae896e..c1e3d98 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,7 +47,9 @@ tests/ ├── 4_container_images.sh ├── 5_container_runtime.sh ├── 6_docker_security_operations.sh -└── 7_docker_swarm_configuration.sh +├── 7_docker_swarm_configuration.sh +├── 8_docker_enterprise_configuration.sh +└── 99_community_checks.sh ``` To modify the Docker Bench for Security you should first clone the repository, @@ -55,7 +57,7 @@ make your changes, check your code with `shellcheck`, `checkbashisms` or similar tools, and then sign off on your commits. After that feel free to send us a pull request with the changes. -While this tool was inspired by the [CIS Docker 1.11.0 benchmark](https://benchmarks.cisecurity.org/downloads/show-single/index.cfm?file=docker16.110) +While this tool was inspired by the [CIS Docker 1.11.0 benchmark](https://www.cisecurity.org/benchmark/docker/) and its successors, feel free to add new tests. We will try to turn [dockerbench.com](https://dockerbench.com) into a list of good community benchmarks for both security and performance, and we would love community diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index a61d89b..ffd95d7 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -14,6 +14,7 @@ The following people, listed in alphabetical order, have contributed to docker-b * Ernst de Haan * HuKeping * Ivan Angelov +* J0WI * Jessica Frazelle * Joachim Lusiardi * Joachim Lusiardi @@ -52,4 +53,4 @@ The following people, listed in alphabetical order, have contributed to docker-b * will Farrell * Zvi "Viz" Effron -This list was generated Sun May 5 20:30:13 UTC 2019. +This list was generated Wed Aug 28 10:19:31 UTC 2019. From 71f63a192a3c05c428f199006f6676c091e3ce16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Wed, 28 Aug 2019 12:36:49 +0200 Subject: [PATCH 23/25] tmp fix for json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- functions_lib.sh | 4 ---- tests/1_host_configuration.sh | 10 ---------- tests/8_docker_enterprise_configuration.sh | 10 ---------- 3 files changed, 24 deletions(-) diff --git a/functions_lib.sh b/functions_lib.sh index 037eb52..3e07147 100644 --- a/functions_lib.sh +++ b/functions_lib.sh @@ -5,7 +5,6 @@ host_configuration() { check_1_1 check_1_1_1 check_1_1_2 - check_1_1_end check_1_2 check_1_2_1 check_1_2_2 @@ -19,7 +18,6 @@ host_configuration() { check_1_2_10 check_1_2_11 check_1_2_12 - check_1_2_end check_1_end } @@ -158,10 +156,8 @@ docker_enterprise_configuration() { check_8_1_5 check_8_1_6 check_8_1_7 - check_8_1_end check_8_2 check_8_2_1 - check_8_2_end check_8_end } diff --git a/tests/1_host_configuration.sh b/tests/1_host_configuration.sh index 8d88303..a9374a1 100644 --- a/tests/1_host_configuration.sh +++ b/tests/1_host_configuration.sh @@ -15,7 +15,6 @@ check_1_1() { desc_1_1="General Configuration" check_1_1="$id_1_1 - $desc_1_1" info "$check_1_1" - startsectionjson "$id_1_1" "$desc_1_1" } # 1.1.1 @@ -58,17 +57,12 @@ check_1_1_2() { fi } -check_1_1_end() { - endsectionjson -} - check_1_2() { logit "" id_1_2="1.2" desc_1_2="Linux Hosts Specific Configuration" check_1_2="$id_1_2 - $desc_1_2" info "$check_1_2" - startsectionjson "$id_1_2" "$desc_1_2" } # 1.2.1 @@ -471,10 +465,6 @@ check_1_2_12() { fi } -check_1_2_end() { - endsectionjson -} - check_1_end() { endsectionjson } diff --git a/tests/8_docker_enterprise_configuration.sh b/tests/8_docker_enterprise_configuration.sh index f8bca33..29359fc 100644 --- a/tests/8_docker_enterprise_configuration.sh +++ b/tests/8_docker_enterprise_configuration.sh @@ -28,7 +28,6 @@ check_8_1() { desc_8_1="Universal Control Plane Configuration" check_8_1="$id_8_1 - $desc_8_1" info "$check_8_1" - startsectionjson "$id_8_1" "$desc_8_1" } # 8.1.1 @@ -150,10 +149,6 @@ check_8_1_7() { currentScore=$((currentScore + 0)) } -check_8_1_end() { - endsectionjson -} - check_8_2() { if [ "$enterprise_license" -ne 1 ]; then return @@ -164,7 +159,6 @@ check_8_2() { desc_8_2="Docker Trusted Registry Configuration" check_8_2="$id_8_2 - $desc_8_2" info "$check_8_2" - startsectionjson "$id_8_2" "$desc_8_2" } check_8_2_1() { @@ -183,10 +177,6 @@ check_8_2_1() { currentScore=$((currentScore + 0)) } -check_8_2_end() { - endsectionjson -} - check_8_end() { endsectionjson } From 261e3f2611498ed257d784e256f381ddd64ddd58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Wed, 28 Aug 2019 12:43:06 +0200 Subject: [PATCH 24/25] update version yell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- helper_lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper_lib.sh b/helper_lib.sh index 3756861..a38d653 100644 --- a/helper_lib.sh +++ b/helper_lib.sh @@ -117,6 +117,6 @@ yell "# ------------------------------------------------------------------------ # Docker, Inc. (c) 2015- # # Checks for dozens of common best-practices around deploying Docker containers in production. -# Inspired by the CIS Docker Community Edition Benchmark v1.1.0. +# Inspired by the CIS Docker Benchmark v1.2.0. # ------------------------------------------------------------------------------" } From 77a3bc65d78466bb150a9fdaae45ab16f99a155a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Wed, 28 Aug 2019 12:59:49 +0200 Subject: [PATCH 25/25] fix 5.28 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Sjögren --- tests/5_container_runtime.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/5_container_runtime.sh b/tests/5_container_runtime.sh index fcaa326..343563c 100644 --- a/tests/5_container_runtime.sh +++ b/tests/5_container_runtime.sh @@ -1112,9 +1112,9 @@ check_5_28() { fail=0 nopids_limit_containers="" for c in $containers; do - pidslimit=$(docker inspect --format '{{.HostConfig.PidsLimit }}' "$c") + pidslimit="$(docker inspect --format '{{.HostConfig.PidsLimit }}' "$c")" - if [ "$pidslimit" -le 0 ]; then + if [ "$pidslimit" = "0" ] || [ "$pidslimit" = "" ] || [ "$pidslimit" = "-1" ]; then # If it's the first container, fail the test if [ $fail -eq 0 ]; then warn "$check_5_28"