From 41a9e0d1f9d15b36f7ae1277acccec7ab2984b70 Mon Sep 17 00:00:00 2001
From: MikeRitter <mike.ritter@target.com>
Date: Thu, 22 Feb 2018 14:01:32 -0600
Subject: [PATCH 1/3] New Features

Signed-off-by: MikeRitter <mike.ritter@target.com>
Signed-off-by: Mike Ritter <mike.ritter@target.com>
---
 README.md                |  3 ++-
 docker-bench-security.sh | 35 +++++++++++++++++++++++++----------
 2 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/README.md b/README.md
index 004b3c8..28f1572 100644
--- a/README.md
+++ b/README.md
@@ -50,7 +50,8 @@ version 1.13.0 or later.
 ```sh
   -h           optional  Print this help message
   -l FILE      optional  Log output in FILE
-  -c CHECK     optional  Run specific check or group of checks
+  -c CHECK     optional  Comma delimited list of specific check(s)
+  -x EXCLUDE   optional  Comma delimited list of patterns within a container to exclude from check
 ```
 
 By default the Docker Bench for Security script will run all available CIS tests
diff --git a/docker-bench-security.sh b/docker-bench-security.sh
index 5700c55..14d2e31 100755
--- a/docker-bench-security.sh
+++ b/docker-bench-security.sh
@@ -37,19 +37,21 @@ usage () {
 
   -h           optional  Print this help message
   -l FILE      optional  Log output in FILE
-  -c CHECK     optional  Run specific check
+  -c CHECK     optional  Comma delimited list of specific check(s)
+  -x EXCLUDE   optional  Comma delimited list of patterns within a container to exclude from check
 EOF
 }
 
 # Get the flags
 # If you add an option here, please
 # remember to update usage() above.
-while getopts hl:c: args
+while getopts hl:c:x: args
 do
   case $args in
   h) usage; exit 0 ;;
   l) logger="$OPTARG" ;;
   c) check="$OPTARG" ;;
+  x) exclude="$OPTARG" ;;
   *) usage; exit 1 ;;
   esac
 done
@@ -86,7 +88,12 @@ beginjson "1.3.4" "$(date +%s)"
 # Load all the tests from tests/ and run them
 main () {
   # List all running containers
-  containers=$(docker ps | sed '1d' | awk '{print $NF}')
+  if [ -z $exclude ]; then
+    containers=$(docker ps | sed '1d' | awk '{print $NF}')
+  else
+    pattern=$(echo $exclude | sed 's/,/|/g')
+    containers=$(docker ps | sed '1d' | grep -Ev '$pattern' | awk '{print $NF}')
+  fi
   # If there is a container with label docker_bench_security, memorize it:
   benchcont="nil"
   for c in $containers; do
@@ -96,7 +103,12 @@ main () {
     fi
   done
   # List all running containers except docker-bench (use names to improve readability in logs)
-  containers=$(docker ps | sed '1d' |  awk '{print $NF}' | grep -v "$benchcont")
+  if [ -z $exclude ]; then
+    containers=$(docker ps | sed '1d' |  awk '{print $NF}' | grep -v "$benchcont")
+  else
+    pattern=$(echo $exclude | sed 's/,/|/g')
+    containers=$(docker ps | sed '1d' | grep -Ev "$pattern" | awk '{print $NF}' | grep -v "$benchcont")
+  fi
 
   if [ -z "$containers" ]; then
     running_containers=0
@@ -112,12 +124,15 @@ main () {
   if [ -z "$check" ]; then
     cis
   else
-    if command -v "$check" 2>/dev/null 1>&2; then
-      "$check"
-    else
-      echo "Check \"$check\" doesn't seem to exist."
-      exit 1
-    fi
+    for i in $(echo $check | sed "s/,/ /g")
+    do
+      if command -v "$i" 2>/dev/null 1>&2; then
+        "$i"
+      else
+        echo "Check \"$i\" doesn't seem to exist."
+        continue
+      fi
+    done
   fi
 
   printf "\n"

From 6e0460db5a0ac29ed16d92b632db87b08d1e5d80 Mon Sep 17 00:00:00 2001
From: Mike Ritter <mike.ritter@target.com>
Date: Sat, 24 Feb 2018 00:07:47 -0600
Subject: [PATCH 2/3] fixed shellcheck issues and check_5_29 for excludes

Signed-off-by: Mike Ritter <mike.ritter@target.com>
---
 docker-bench-security.sh     | 10 +++++-----
 tests/5_container_runtime.sh | 11 ++++++++---
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/docker-bench-security.sh b/docker-bench-security.sh
index 14d2e31..6a0a4ba 100755
--- a/docker-bench-security.sh
+++ b/docker-bench-security.sh
@@ -88,10 +88,10 @@ beginjson "1.3.4" "$(date +%s)"
 # Load all the tests from tests/ and run them
 main () {
   # List all running containers
-  if [ -z $exclude ]; then
+  if [ -z "$exclude" ]; then
     containers=$(docker ps | sed '1d' | awk '{print $NF}')
   else
-    pattern=$(echo $exclude | sed 's/,/|/g')
+    pattern=$(echo "$exclude" | sed 's/,/|/g')
     containers=$(docker ps | sed '1d' | grep -Ev '$pattern' | awk '{print $NF}')
   fi
   # If there is a container with label docker_bench_security, memorize it:
@@ -103,10 +103,10 @@ main () {
     fi
   done
   # List all running containers except docker-bench (use names to improve readability in logs)
-  if [ -z $exclude ]; then
+  if [ -z "$exclude" ]; then
     containers=$(docker ps | sed '1d' |  awk '{print $NF}' | grep -v "$benchcont")
   else
-    pattern=$(echo $exclude | sed 's/,/|/g')
+    pattern=$(echo "$exclude" | sed 's/,/|/g')
     containers=$(docker ps | sed '1d' | grep -Ev "$pattern" | awk '{print $NF}' | grep -v "$benchcont")
   fi
 
@@ -124,7 +124,7 @@ main () {
   if [ -z "$check" ]; then
     cis
   else
-    for i in $(echo $check | sed "s/,/ /g")
+    for i in $(echo "$check" | sed "s/,/ /g")
     do
       if command -v "$i" 2>/dev/null 1>&2; then
         "$i"
diff --git a/tests/5_container_runtime.sh b/tests/5_container_runtime.sh
index 1aca0fe..1eec675 100644
--- a/tests/5_container_runtime.sh
+++ b/tests/5_container_runtime.sh
@@ -988,7 +988,8 @@ check_5_29() {
   for net in $networks; do
     if docker network inspect --format '{{ .Options }}' "$net" 2>/dev/null | grep "com.docker.network.bridge.name:docker0" >/dev/null 2>&1; then
       docker0Containers=$(docker network inspect --format='{{ range $k, $v := .Containers }} {{ $k }} {{ end }}' "$net" | \
-       sed -e 's/^ //' -e 's/  /\n/g' 2>/dev/null)
+        sed -e 's/^ //' -e 's/  /\n/g' 2>/dev/null)
+
       if [ -n "$docker0Containers" ]; then
         if [ $fail -eq 0 ]; then
           info "$check_5_29"
@@ -996,7 +997,12 @@ check_5_29() {
           fail=1
         fi
         for c in $docker0Containers; do
-	  cName=$(docker inspect --format '{{.Name}}' "$c" 2>/dev/null | sed 's/\///g')
+          if [ -z "$exclude" ]; then
+            cName=$(docker inspect --format '{{.Name}}' "$c" 2>/dev/null | sed 's/\///g')
+          else
+            pattern=$(echo "$exclude" | sed 's/,/|/g')
+            cName=$(docker inspect --format '{{.Name}}' "$c" 2>/dev/null | sed 's/\///g' | grep -Ev '$pattern' )
+          fi
           info "     * Container in docker0 network: $cName"
           logjson "5.29" "INFO: $c"
         done
@@ -1081,4 +1087,3 @@ check_5_31() {
       currentScore=$((currentScore - 1))
   fi
 }
-

From a1e1a0a50df886d2b20e7f3cb75968e845442f3b Mon Sep 17 00:00:00 2001
From: Mike Ritter <mike.ritter@target.com>
Date: Mon, 26 Feb 2018 16:26:36 -0600
Subject: [PATCH 3/3] fixed variable expansion and added test for container
 exclusion

Signed-off-by: Mike Ritter <mike.ritter@target.com>
---
 docker-bench-security.sh     |  6 +++---
 tests/5_container_runtime.sh | 17 +++++++++++++----
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/docker-bench-security.sh b/docker-bench-security.sh
index 6a0a4ba..ab32924 100755
--- a/docker-bench-security.sh
+++ b/docker-bench-security.sh
@@ -38,7 +38,7 @@ usage () {
   -h           optional  Print this help message
   -l FILE      optional  Log output in FILE
   -c CHECK     optional  Comma delimited list of specific check(s)
-  -x EXCLUDE   optional  Comma delimited list of patterns within a container to exclude from check
+  -x EXCLUDE   optional  Comma delimited list of patterns within a container name to exclude from check
 EOF
 }
 
@@ -92,7 +92,7 @@ main () {
     containers=$(docker ps | sed '1d' | awk '{print $NF}')
   else
     pattern=$(echo "$exclude" | sed 's/,/|/g')
-    containers=$(docker ps | sed '1d' | grep -Ev '$pattern' | awk '{print $NF}')
+    containers=$(docker ps | sed '1d' | grep -Ev "$pattern" | awk '{print $NF}')
   fi
   # If there is a container with label docker_bench_security, memorize it:
   benchcont="nil"
@@ -107,7 +107,7 @@ main () {
     containers=$(docker ps | sed '1d' |  awk '{print $NF}' | grep -v "$benchcont")
   else
     pattern=$(echo "$exclude" | sed 's/,/|/g')
-    containers=$(docker ps | sed '1d' | grep -Ev "$pattern" | awk '{print $NF}' | grep -v "$benchcont")
+    containers=$(docker ps | sed '1d' | awk '{print $NF}' | grep -Ev "$pattern" | grep -v "$benchcont")
   fi
 
   if [ -z "$containers" ]; then
diff --git a/tests/5_container_runtime.sh b/tests/5_container_runtime.sh
index 1eec675..06ec355 100644
--- a/tests/5_container_runtime.sh
+++ b/tests/5_container_runtime.sh
@@ -990,7 +990,14 @@ check_5_29() {
       docker0Containers=$(docker network inspect --format='{{ range $k, $v := .Containers }} {{ $k }} {{ end }}' "$net" | \
         sed -e 's/^ //' -e 's/  /\n/g' 2>/dev/null)
 
-      if [ -n "$docker0Containers" ]; then
+      for c in $docker0Containers; do
+        cName=$(docker inspect --format '{{.Name}}' "$c" 2>/dev/null | sed 's/\///g')
+        if [ -n "$exclude" ]; then
+          pattern=$(echo "$exclude" | sed 's/,/|/g')
+          if echo "$cName" | grep -q "$pattern"; then
+            continue
+          fi
+        fi
         if [ $fail -eq 0 ]; then
           info "$check_5_29"
           logjson "5.29" "INFO"
@@ -1001,10 +1008,12 @@ check_5_29() {
             cName=$(docker inspect --format '{{.Name}}' "$c" 2>/dev/null | sed 's/\///g')
           else
             pattern=$(echo "$exclude" | sed 's/,/|/g')
-            cName=$(docker inspect --format '{{.Name}}' "$c" 2>/dev/null | sed 's/\///g' | grep -Ev '$pattern' )
+            cName=$(docker inspect --format '{{.Name}}' "$c" 2>/dev/null | sed 's/\///g' | grep -Ev "$pattern" )
+          fi
+          if ! [ -z "$cName" ]; then
+            info "     * Container in docker0 network: $cName"
+            logjson "5.29" "INFO: $c"
           fi
-          info "     * Container in docker0 network: $cName"
-          logjson "5.29" "INFO: $c"
         done
       fi
       currentScore=$((currentScore + 0))