diff --git a/.dockerignore b/.dockerignore
index 6b8710a..db3e3b9 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1 +1,5 @@
 .git
+*.md
+*.png
+distros
+
diff --git a/.gitignore b/.gitignore
index 397b4a7..e5ebf25 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-*.log
+*.log*
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 36d2d2f..c1e3d98 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -3,46 +3,62 @@
 Want to hack on Docker Bench? Awesome! Here are instructions to get you
 started.
 
-The Docker Bench for Security is a part of the [Docker](https://www.docker.com) project, and follows
-the same rules and principles. If you're already familiar with the way
-Docker does things, you'll feel right at home.
+The Docker Bench for Security is a part of the [Docker](https://www.docker.com)
+project, and follows the same rules and principles. If you're already familiar
+with the way Docker does things, you'll feel right at home.
 
 Otherwise, go read
 [Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md).
 
-### Development Environment Setup
+## Development Environment Setup
 
-The only thing you need to hack on Docker Bench for Security is a POSIX 2004 compliant shell. We try to keep the project compliant for maximum portability
+The only thing you need to hack on Docker Bench for Security is a POSIX 2004
+compliant shell. We try to keep the project compliant for maximum portability.
 
-#### Start hacking
+### Start hacking
 
 You can build the container that wraps the docker-bench for security:
+
 ```sh
-✗ git clone git@github.com:docker/docker-bench-security.git
-✗ docker build -t diogomonica/docker-bench-security .
+git clone git@github.com:docker/docker-bench-security.git
+cd docker-bench-security
+docker build -t docker-bench-security .
 ```
 
 Or you can simply run the shell script locally:
 
 ```sh
-✗ sh docker-bench-security.sh
+git clone git@github.com:docker/docker-bench-security.git
+cd docker-bench-security
+sudo sh docker-bench-security.sh
 ```
 
-The Docker Bench has the main script called `docker-bench-security.sh`. This is the main script that checks for all the dependencies, deals with command line arguments and loads all the tests.
+The Docker Bench has the main script called `docker-bench-security.sh`.
+This is the main script that checks for all the dependencies, deals with
+command line arguments and loads all the tests.
 
-The tests are split in 6 different files:
+The tests are split into the following files:
 
 ```sh
-✗  docker-bench-security git:(master) ✗ tree tests
-tests
+tests/
 ├── 1_host_configuration.sh
 ├── 2_docker_daemon_configuration.sh
 ├── 3_docker_daemon_configuration_files.sh
 ├── 4_container_images.sh
 ├── 5_container_runtime.sh
-└── 6_docker_security_operations.sh
+├── 6_docker_security_operations.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, make your changes, and then sign off on your commits. After that feel free to send us a pull-request with the changes.
+To modify the Docker Bench for Security you should first clone the repository,
+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 is inspired in the CIS Docker 1.6 Benchmark, feel free to add new tests. We will try to turn dockerbench.com into a list of good community benchmarks for both security and performance, and we would love community contributions.
+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
+contributions.
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
new file mode 100644
index 0000000..ca9fcb6
--- /dev/null
+++ b/CONTRIBUTORS.md
@@ -0,0 +1,58 @@
+The following people, listed in alphabetical order, have contributed to docker-bench-security:
+
+* alberto <alberto@tutum.co>
+* Andreas Stieger <astieger@suse.com>
+* Anthony Roger <aroger@softwaymedical.fr>
+* Aurélien Gasser <aurelien.gasser@gmail.com>
+* binary <binary@webdev.fritz.box>
+* Boris Gorbylev <ekho@ekho.name>
+* Cheng-Li Jerry Ma <chengli.ma@gmail.com>
+* Csaba Palfi <csaba@palfi.me>
+* Daniele Marcocci <daniele.marcocci@par-tec.it>
+* Dhawal Patel <dhawal.patel@nordstrom.com>
+* Diogo Monica <diogo@docker.com>
+* Diogo Mónica <diogo.monica@gmail.com>
+* Ernst de Haan <ernst@ernstdehaan.com>
+* HuKeping <hukeping@huawei.com>
+* Ivan Angelov <iangelov@users.noreply.github.com>
+* J0WI <J0WI@users.noreply.github.com>
+* jammasterj89 <jammasterj89@gmail.com>
+* Jessica Frazelle <princess@docker.com>
+* Joachim Lusiardi <jlusiardi@users.noreply.github.com>
+* Joachim Lusiardi <joachim@lusiardi.de>
+* Joachim Lusiardi <shing19m@dev1.lusiardi.de>
+* Joe Williams <joe.williams@github.com>
+* Julien Garcia Gonzalez <julien@giantswarm.io>
+* Jürgen Hermann <jh@web.de>
+* kakakakakku <y.yoshida22@gmail.com>
+* Karol Babioch <kbabioch@suse.de>
+* Kevin Lim <kevin.lim@sap.com>
+* kevinll <imhael@gmail.com>
+* Liron Levin <liron@twistlock.com>
+* liron-l <levinlir@gmail.com>
+* LorensK <LorensK@users.noreply.github.com>
+* lusitania <lusitania@users.noreply.github.com>
+* Maik Ellerbrock <opensource@frapsoft.com>
+* Mark Stemm <mark.stemm@gmail.com>
+* Matt Fellows <matt.fellows@onegeek.com.au>
+* Michael Crosby <crosbymichael@gmail.com>
+* Michael Stahn <michael.stahn.42@gmail.com>
+* Mike Ritter <mike.ritter@target.com>
+* Mr. Secure <ben.github@mrsecure.org>
+* MrSecure <MrSecure@users.noreply.github.com>
+* Nigel Brown <nigel@windsock.io>
+* Paul Czarkowski <username.taken@gmail.com>
+* Paul Morgan <jumanjiman@gmail.com>
+* Pete Sellars <psellars@gmail.com>
+* Peter <lusitania@users.noreply.github.com>
+* Ravi Kumar Vadapalli <vadapalli.ravikumar@gmail.com>
+* Scott McCarty <scott.mccarty@gmail.com>
+* Sebastiaan van Stijn <github@gone.nl>
+* telepresencebot2 <telepresencebot2@users.noreply.github.com>
+* Thomas Sjögren <konstruktoid@users.noreply.github.com>
+* Tom Partington <tom.partington@cevo.com.au>
+* Werner Buck <wernerbuck@gmail.com>
+* will Farrell <willfarrell@users.noreply.github.com>
+* Zvi "Viz" Effron <zeffron@riotgames.com>
+
+This list was generated Tue Nov  5 09:45:35 UTC 2019.
diff --git a/Dockerfile b/Dockerfile
index a552ef4..0ad1564 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,11 +1,25 @@
-FROM alpine:3.1
+FROM alpine:3.12
 
-RUN apk --update add docker
+LABEL \
+  org.label-schema.name="docker-bench-security" \
+  org.label-schema.url="https://dockerbench.com" \
+  org.label-schema.vcs-url="https://github.com/docker/docker-bench-security.git"
 
-RUN mkdir /docker-bench-security
+# Switch to the HTTPS endpoint for the apk repositories
+# https://github.com/gliderlabs/docker-alpine/issues/184
+RUN set -eux; \
+  sed -i 's!http://dl-cdn.alpinelinux.org/!https://alpine.global.ssl.fastly.net/!g' /etc/apk/repositories && \
+  apk add --no-cache \
+    iproute2 \
+    docker-cli \
+    dumb-init
 
-COPY . /docker-bench-security
+COPY ./*.sh /usr/local/bin/
+COPY ./tests/*.sh /usr/local/bin/tests/
 
-WORKDIR /docker-bench-security
+HEALTHCHECK CMD exit 0
 
-ENTRYPOINT ["/bin/sh", "docker-bench-security.sh"]
+WORKDIR /usr/local/bin
+
+ENTRYPOINT [ "/usr/bin/dumb-init", "docker-bench-security.sh" ]
+CMD [""]
diff --git a/MAINTAINERS b/MAINTAINERS
new file mode 100644
index 0000000..bd38003
--- /dev/null
+++ b/MAINTAINERS
@@ -0,0 +1,34 @@
+# Docker Bench for Security maintainers file
+#
+# This file describes who runs the docker/docker-bench-security project and how.
+# This is a living document - if you see something out of date or missing, speak up!
+#
+# It is structured to be consumable by both humans and programs.
+# To extract its contents programmatically, use any TOML-compliant parser.
+#
+# This file is compiled into the MAINTAINERS file in docker/opensource.
+#
+[Org]
+	[Org."Core maintainers"]
+		people = [
+			"diogomonica",
+			"konstruktoid",
+		]
+
+[people]
+
+# A reference list of all people associated with the project.
+# All other sections should refer to people by their canonical key
+# in the people section.
+
+	# ADD YOURSELF HERE IN ALPHABETICAL ORDER
+
+	[people.diogomonica]
+	Name = "Dr. Diogo Mónica"
+	Email = "diogo@docker.com"
+	GitHub = "diogomonica"
+
+	[people.konstruktoid]
+	Name = "Thomas Sjögren"
+	Email = "thomas.sjogren@protonmail.com"
+	GitHub = "konstruktoid"
diff --git a/README.md b/README.md
index bcedb95..618ca0b 100644
--- a/README.md
+++ b/README.md
@@ -1,45 +1,150 @@
 # Docker Bench for Security
 
-![Docker Bench for Security running](https://github.com/diogomonica/docker-bench-security/raw/master/benchmark_log.png?raw=true "Docker Bench for Security running")
+![Docker Bench for Security running](https://raw.githubusercontent.com/docker/docker-bench-security/master/benchmark_log.png)
 
-The Docker Bench for Security is a script that checks for all the automatable tests included in the [CIS Docker 1.6 Benchmark](https://benchmarks.cisecurity.org/tools2/docker/CIS_Docker_1.6_Benchmark_v1.0.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.
+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 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 this benchmark.
+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
+this benchmark.
 
 ## Running Docker Bench for Security
 
-We packaged docker bench as a small container for your convenience. Note that this container is being run with a *lot* of privilege -- sharing the host's filesystem, pid and network namespaces, due to portions of the benchmark applying to the running host.
+We packaged docker bench as a small container for your convenience. Note that
+this container is being run with a *lot* of privilege -- sharing the host's
+filesystem, pid and network namespaces, due to portions of the benchmark
+applying to the running host.
 
-The easiest way to run your hosts against the CIS Docker 1.6 benchmark is by running our pre-built container:
+The easiest way to run your hosts against the Docker Bench for Security is by
+running our pre-built container:
 
-
-```
-docker run -it --net host --pid host -v /var/run/docker.sock:/var/run/docker.sock \
--v /usr/lib/systemd:/usr/lib/systemd -v /etc:/etc --label docker-bench-security \
-diogomonica/docker-bench-security
+```sh
+docker run --rm --net host --pid host --userns host --cap-add audit_control \
+    -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
+    -v /etc:/etc:ro \
+    -v /usr/bin/containerd:/usr/bin/containerd:ro \
+    -v /usr/bin/runc:/usr/bin/runc:ro \
+    -v /usr/lib/systemd:/usr/lib/systemd:ro \
+    -v /var/lib:/var/lib:ro \
+    -v /var/run/docker.sock:/var/run/docker.sock:ro \
+    --label docker_bench_security \
+    docker/docker-bench-security
 ```
 
-Docker bench requires Docker 1.6.2 or later in order to run, since it depends on the `--label` to exclude the current container from being inspected. If you can't upgrade to 1.6.2, I feel free to remove the `--label` flag or run the shell script locally (see below).
+Don't forget to adjust the shared volumes according to your operating system.
+Some examples are:
 
-Additionally, there was a bug in Docker 1.6.0 that would not allow mounting `-v /dev:/dev`. If you are getting an error while accessing `resolv.conf`, please update your docker to 1.6.2.
+1. `Docker Desktop` on macOS don't have `/usr/lib/systemd` or the above Docker
+    binaries.
+
+```sh
+docker run --rm --net host --pid host --userns host --cap-add audit_control \
+    -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
+    -v /etc:/etc \
+    -v /var/lib:/var/lib:ro \
+    -v /var/run/docker.sock:/var/run/docker.sock:ro \
+    --label docker_bench_security \
+    docker/docker-bench-security
+```
+
+2. On Ubuntu the `docker.service` and `docker.secret` files are located in
+   `/lib/systemd/system` folder by default.
+
+```sh
+docker run --rm --net host --pid host --userns host --cap-add audit_control \
+    -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
+    -v /etc:/etc:ro \
+    -v /lib/systemd/system:/lib/systemd/system:ro \
+    -v /usr/bin/containerd:/usr/bin/containerd:ro \
+    -v /usr/bin/runc:/usr/bin/runc:ro \
+    -v /usr/lib/systemd:/usr/lib/systemd:ro \
+    -v /var/lib:/var/lib:ro \
+    -v /var/run/docker.sock:/var/run/docker.sock:ro \
+    --label docker_bench_security \
+    docker/docker-bench-security
+```
+
+Docker bench requires Docker 1.13.0 or later in order to run.
+
+Note that when distributions doesn't contain `auditctl`, the audit tests will
+check `/etc/audit/audit.rules` to see if a rule is present instead.
+
+Distribution specific Dockerfiles that fixes this issue are available in the
+[distros directory](https://github.com/docker/docker-bench-security/tree/master/distros).
+
+The [distribution specific Dockerfiles](https://github.com/docker/docker-bench-security/tree/master/distros)
+may also help if the distribution you're using haven't yet shipped Docker
+version 1.13.0 or later.
+
+### Docker Bench for Security options
+
+```sh
+  -b           optional  Do not print colors
+  -h           optional  Print this help message
+  -l FILE      optional  Log output in FILE
+  -c CHECK     optional  Comma delimited list of specific check(s)
+  -e CHECK     optional  Comma delimited list of specific check(s) to exclude
+  -i INCLUDE   optional  Comma delimited list of patterns within a container or image name to check
+  -x EXCLUDE   optional  Comma delimited list of patterns within a container or image name to exclude from check
+```
+
+By default the Docker Bench for Security script will run all available CIS tests
+and produce logs in the current directory named `docker-bench-security.sh.log.json`
+and `docker-bench-security.sh.log`.
+The CIS based checks are named `check_<section>_<number>`, e.g. `check_2_6`
+and community contributed checks are named `check_c_<number>`.
+A complete list of checks are present in [functions_lib.sh](functions_lib.sh).
+
+`sh docker-bench-security.sh -l /tmp/docker-bench-security.sh.log -c check_2_2`
+will only run check `2.2 Ensure the logging level is set to 'info'`.
+
+`sh docker-bench-security.sh -l /tmp/docker-bench-security.sh.log -e check_2_2`
+will run all available checks except `2.2 Ensure the logging level is set to 'info'`.
+
+`sh docker-bench-security.sh -l /tmp/docker-bench-security.sh.log -e docker_enterprise_configuration`
+will run all available checks except the docker_enterprise_configuration group
+
+`sh docker-bench-security.sh -l /tmp/docker-bench-security.sh.log -e docker_enterprise_configuration,check_2_2`
+will run all available checks except the docker_enterprise_configuration group
+and `2.2 Ensure the logging level is set to 'info'`
+
+`sh docker-bench-security.sh -l /tmp/docker-bench-security.sh.log -c container_images -e check_4_5`
+will run just the container_images checks except
+`4.5 Ensure Content trust for Docker is Enabled`
+
+Note that when submitting checks, provide information why it is a
+reasonable test to add and please include some kind of official documentation
+verifying that information.
 
 ## Building Docker Bench for Security
 
-If you wish to build and run this container yourself, you can follow the following steps:
+If you wish to build and run this container yourself, you can follow the
+following steps:
 
+```sh
+git clone https://github.com/docker/docker-bench-security.git
+cd docker-bench-security
+docker build --no-cache -t docker-bench-security .
 ```
-git clone https://github.com/diogomonica/docker-bench-security.git
-cd docker-bench-security; docker build -t docker-bench-security .
-docker run -it --net host --pid host -v /var/run/docker.sock:/var/run/docker.sock \
--v /usr/lib/systemd:/usr/lib/systemd -v /etc:/etc --label security-benchmark \
-docker-bench-security
+
+followed by an appropriate `docker run` command as stated above
+or use [Docker Compose](https://docs.docker.com/compose/):
+
+```sh
+git clone https://github.com/docker/docker-bench-security.git
+cd docker-bench-security
+docker-compose run --rm docker-bench-security
 ```
 
 Also, this script can also be simply run from your base host by running:
 
-```
-git clone https://github.com/diogomonica/docker-bench-security.git
-cd docker-bench-security; sh docker-bench-security.sh
+```sh
+git clone https://github.com/docker/docker-bench-security.git
+cd docker-bench-security
+sudo sh docker-bench-security.sh
 ```
 
-This script was build to be POSIX 2004 compliant, so it should be portable across any Unix platform.
+This script was built to be POSIX 2004 compliant, so it should be portable
+across any Unix platform.
diff --git a/benchmark_log.png b/benchmark_log.png
index a9e605e..8399924 100644
Binary files a/benchmark_log.png and b/benchmark_log.png differ
diff --git a/distros/Dockerfile.alpine b/distros/Dockerfile.alpine
new file mode 100644
index 0000000..0ad1564
--- /dev/null
+++ b/distros/Dockerfile.alpine
@@ -0,0 +1,25 @@
+FROM alpine:3.12
+
+LABEL \
+  org.label-schema.name="docker-bench-security" \
+  org.label-schema.url="https://dockerbench.com" \
+  org.label-schema.vcs-url="https://github.com/docker/docker-bench-security.git"
+
+# Switch to the HTTPS endpoint for the apk repositories
+# https://github.com/gliderlabs/docker-alpine/issues/184
+RUN set -eux; \
+  sed -i 's!http://dl-cdn.alpinelinux.org/!https://alpine.global.ssl.fastly.net/!g' /etc/apk/repositories && \
+  apk add --no-cache \
+    iproute2 \
+    docker-cli \
+    dumb-init
+
+COPY ./*.sh /usr/local/bin/
+COPY ./tests/*.sh /usr/local/bin/tests/
+
+HEALTHCHECK CMD exit 0
+
+WORKDIR /usr/local/bin
+
+ENTRYPOINT [ "/usr/bin/dumb-init", "docker-bench-security.sh" ]
+CMD [""]
diff --git a/distros/Dockerfile.centos b/distros/Dockerfile.centos
new file mode 100644
index 0000000..4c0dcfb
--- /dev/null
+++ b/distros/Dockerfile.centos
@@ -0,0 +1,15 @@
+# REPOSITORY https://github.com/fatherlinux/docker-bench-security
+
+FROM centos
+
+MAINTAINER smccarty@redhat.com
+
+RUN yum install -y docker iproute audit procps-ng; yum clean all
+
+RUN mkdir /docker-bench-security
+
+COPY . /docker-bench-security
+
+WORKDIR /docker-bench-security
+
+ENTRYPOINT ["/bin/sh", "docker-bench-security.sh"]
diff --git a/distros/Dockerfile.debian b/distros/Dockerfile.debian
new file mode 100644
index 0000000..4284f54
--- /dev/null
+++ b/distros/Dockerfile.debian
@@ -0,0 +1,24 @@
+FROM debian:sid
+
+LABEL org.label-schema.name="docker-bench-security" \
+      org.label-schema.url="https://github.com/konstruktoid/docker-bench-security" \
+      org.label-schema.vcs-url="https://github.com/konstruktoid/docker-bench-security.git"
+
+RUN \
+    apt-get update && \
+    apt-get -y upgrade && \
+    apt-get -y install auditd ca-certificates docker.io \
+      gawk iproute2 procps --no-install-recommends && \
+    apt-get -y clean && \
+    apt-get -y autoremove && \
+    rm -rf /var/lib/apt/lists/* \
+      /usr/share/doc /usr/share/doc-base \
+      /usr/share/man /usr/share/locale /usr/share/zoneinfo
+
+RUN mkdir /docker-bench-security
+
+COPY . /docker-bench-security
+
+WORKDIR /docker-bench-security
+
+ENTRYPOINT ["/bin/sh", "docker-bench-security.sh"]
diff --git a/distros/Dockerfile.openSUSE b/distros/Dockerfile.openSUSE
new file mode 100644
index 0000000..d5a0add
--- /dev/null
+++ b/distros/Dockerfile.openSUSE
@@ -0,0 +1,13 @@
+# REPOSITORY https://github.com/docker/docker-bench-security
+FROM opensuse/leap:latest
+
+RUN zypper -n in audit docker iproute2 && \
+    mkdir /docker-bench-security && \
+    rm /usr/bin/awk && \
+    cp /usr/bin/gawk /usr/bin/awk
+
+COPY . /docker-bench-security
+
+WORKDIR /docker-bench-security
+
+ENTRYPOINT ["/bin/bash", "docker-bench-security.sh"]
diff --git a/distros/Dockerfile.rhel b/distros/Dockerfile.rhel
new file mode 100644
index 0000000..c1b5618
--- /dev/null
+++ b/distros/Dockerfile.rhel
@@ -0,0 +1,18 @@
+# REPOSITORY https://github.com/fatherlinux/docker-bench-security
+
+FROM rhel7
+
+MAINTAINER smccarty@redhat.com
+
+RUN yum install -y yum-utils; yum clean all
+RUN yum-config-manager --disable "*" &>/dev/null
+RUN yum-config-manager --enable rhel-7-server-rpms --enable rhel-7-server-extras-rpms
+RUN yum install -y docker iproute audit procps-ng; yum clean all
+
+RUN mkdir /docker-bench-security
+
+COPY . /docker-bench-security
+
+WORKDIR /docker-bench-security
+
+ENTRYPOINT ["/bin/sh", "docker-bench-security.sh"]
diff --git a/distros/README.md b/distros/README.md
new file mode 100644
index 0000000..be4de17
--- /dev/null
+++ b/distros/README.md
@@ -0,0 +1,21 @@
+# Distribution specific Dockerfiles
+
+## Requirements
+
+### Dockerfile name
+
+The format should be `Dockerfile.{distribution name}`.
+
+### Keep your images up-to-date
+
+Use the distribution package manager to keep your image up-to-date.
+
+### Labels
+
+Use the following labels in your Dockerfile:
+
+```
+LABEL org.label-schema.name="docker-bench-security" \
+      org.label-schema.url="<YOUR GIT REPOSITORY HTTPS ADDRESS>" \
+      org.label-schema.vcs-url="<YOUR REPOSITORY HTTPS GIT ADDRESS"
+```
diff --git a/docker-bench-security.sh b/docker-bench-security.sh
index d2cb12c..0d5424e 100755
--- a/docker-bench-security.sh
+++ b/docker-bench-security.sh
@@ -1,91 +1,202 @@
 #!/bin/sh
 # ------------------------------------------------------------------------------
-# CIS Docker 1.6 Benchmark v1.0.0 checker
+# Docker Bench for Security
 #
-# Docker, Inc. (c) 2015
-#
-# Provides automated tests for the CIS Docker 1.6 Benchmark:
-# https://benchmarks.cisecurity.org/tools2/docker/CIS_Docker_1.6_Benchmark_v1.0.0.pdf
+# Docker, Inc. (c) 2015-
 #
+# Checks for dozens of common best-practices around deploying Docker containers in production.
 # ------------------------------------------------------------------------------
 
+version='1.3.5'
+
 # Load dependencies
-. ./output_lib.sh
+. ./functions_lib.sh
 . ./helper_lib.sh
 
 # Setup the paths
-this_path=$(abspath "$0")       ## Path of this file including filenamel
+this_path=$(abspath "$0")       ## Path of this file including filename
 myname=$(basename "${this_path}")     ## file name of this script.
 
-export PATH=/bin:/sbin:/usr/bin:/usr/local/bin:/usr/sbin/
-logger="${myname}.log"
+readonly version
+readonly this_path
+readonly myname
+
+export PATH="$PATH:/bin:/sbin:/usr/bin:/usr/local/bin:/usr/sbin/"
 
 # Check for required program(s)
-req_progs='docker netstat grep awk'
+req_progs='awk docker grep stat'
 for p in $req_progs; do
   command -v "$p" >/dev/null 2>&1 || { printf "%s command not found.\n" "$p"; exit 1; }
 done
 
+if command -v ss >/dev/null 2>&1; then
+  netbin=ss
+elif command -v netstat >/dev/null 2>&1; then
+  netbin=netstat
+else
+  echo "ss or netstat command not found."
+  exit 1
+fi
+
 # Ensure we can connect to docker daemon
-docker ps -q >/dev/null 2>&1
-if [ $? -ne 0 ]; then
+if ! docker ps -q >/dev/null 2>&1; then
   printf "Error connecting to docker daemon (does docker ps work?)\n"
   exit 1
 fi
 
 usage () {
-  printf "
-  usage: %s [options]
+  cat <<EOF
+  usage: ${myname} [options]
 
-  -h           optional  Print this help message\n" "$myname"
-  exit 1
+  -b           optional  Do not print colors
+  -h           optional  Print this help message
+  -l FILE      optional  Log output in FILE
+  -c CHECK     optional  Comma delimited list of specific check(s)
+  -e CHECK     optional  Comma delimited list of specific check(s) to exclude
+  -i INCLUDE   optional  Comma delimited list of patterns within a container or image name to check
+  -x EXCLUDE   optional  Comma delimited list of patterns within a container or image name to exclude from check
+  -n LIMIT     optional  In JSON output, when reporting lists of items (containers, images, etc.), limit the number of reported items to LIMIT. Default 0 (no limit).
+EOF
 }
 
-yell "# ------------------------------------------------------------------------------
-# CIS Docker 1.6 Benchmark v1.0.0 checker
-#
-# Docker, Inc. (c) 2015
-#
-# Provides automated tests for the CIS Docker 1.6 Benchmark:
-# https://benchmarks.cisecurity.org/tools2/docker/CIS_Docker_1.6_Benchmark_v1.0.0.pdf
-# ------------------------------------------------------------------------------"
+# Get the flags
+# If you add an option here, please
+# remember to update usage() above.
+while getopts bhl:c:e:i:x:t:n: args
+do
+  case $args in
+  b) nocolor="nocolor";;
+  h) usage; exit 0 ;;
+  l) logger="$OPTARG" ;;
+  c) check="$OPTARG" ;;
+  e) checkexclude="$OPTARG" ;;
+  i) include="$OPTARG" ;;
+  x) exclude="$OPTARG" ;;
+  n) limit="$OPTARG" ;;
+  *) usage; exit 1 ;;
+  esac
+done
 
-logit "Initializing $(date)\n"
+if [ -z "$logger" ]; then
+  logger="${myname}.log"
+fi
+
+if [ -z "$limit" ]; then
+  limit=0
+fi
+
+# Load output formating
+. ./output_lib.sh
+
+yell_info
 
 # Warn if not root
 ID=$(id -u)
 if [ "x$ID" != "x0" ]; then
-    warn "Some tests might require root to run"
-    sleep 3
+  warn "Some tests might require root to run"
+  sleep 3
 fi
 
-# Get the flags
-while getopts :hlfi: args
-do
-  case $args in
-  h) usage ;;
-  l) logger="$OPTARG" ;;
-  *) usage ;;
-  esac
-done
+# Total Score
+# Warn Scored -1, Pass Scored +1, Not Score -0
+
+totalChecks=0
+currentScore=0
+
+logit "Initializing $(date)\n"
+beginjson "$version" "$(date +%s)"
 
 # Load all the tests from tests/ and run them
 main () {
-  # List all running containers
-  containers=$(docker ps -q)
-  # If there is a container with label docker-bench, memorize it:
-  benchcont="nil"
-  for c in $containers; do
-    labels=$(docker inspect --format '{{ .Config.Labels }}' "$c")
-    contains "$labels" "docker-bench" && benchcont="$c"
-  done
-  # List all running containers except docker-bench
-  containers=$(docker ps -q | grep -v "$benchcont")
+  # Get configuration location
+  get_docker_configuration_file
 
-  for test in tests/*.sh
-  do
-     . ./"$test"
+  # If there is a container with label docker_bench_security, memorize it:
+  benchcont="nil"
+  for c in $(docker ps | sed '1d' | awk '{print $NF}'); do
+    if docker inspect --format '{{ .Config.Labels }}' "$c" | \
+     grep -e 'docker.bench.security' >/dev/null 2>&1; then
+      benchcont="$c"
+    fi
   done
+
+  # Get the image id of the docker_bench_security_image, memorize it:
+  benchimagecont="nil"
+  for c in $(docker images | sed '1d' | awk '{print $3}'); do
+    if docker inspect --format '{{ .Config.Labels }}' "$c" | \
+     grep -e 'docker.bench.security' >/dev/null 2>&1; then
+      benchimagecont="$c"
+    fi
+  done
+
+  if [ -n "$include" ]; then
+    pattern=$(echo "$include" | sed 's/,/|/g')
+    containers=$(docker ps | sed '1d' | awk '{print $NF}' | grep -v "$benchcont" | grep -E "$pattern")
+    images=$(docker images | sed '1d' | grep -E "$pattern" | awk '{print $3}' | grep -v "$benchimagecont")
+  elif [ -n "$exclude" ]; then
+    pattern=$(echo "$exclude" | sed 's/,/|/g')
+    containers=$(docker ps | sed '1d' | awk '{print $NF}' | grep -v "$benchcont" | grep -Ev "$pattern")
+    images=$(docker images | sed '1d' | grep -Ev "$pattern" | awk '{print $3}' | grep -v "$benchimagecont")
+  else
+    containers=$(docker ps | sed '1d' | awk '{print $NF}' | grep -v "$benchcont")
+    images=$(docker images -q | grep -v "$benchcont")
+  fi
+
+  if [ -z "$containers" ]; then
+    running_containers=0
+  else
+    running_containers=1
+  fi
+
+  for test in tests/*.sh; do
+    . ./"$test"
+  done
+
+  if [ -z "$check" ] && [ ! "$checkexclude" ]; then
+    # No options just run
+    cis
+  elif [ -z "$check" ]; then
+    # No check defined but excludes defined set to calls in cis() function
+    check=$(sed -ne "/cis() {/,/}/{/{/d; /}/d; p}" functions_lib.sh)
+  fi
+
+  for c in $(echo "$check" | sed "s/,/ /g"); do
+    if ! command -v "$c" 2>/dev/null 1>&2; then
+      echo "Check \"$c\" doesn't seem to exist."
+      continue
+    fi
+    if [ -z "$checkexclude" ]; then
+      # No excludes just run the checks specified
+      "$c"
+    else
+      # Exludes specified and check exists
+      checkexcluded="$(echo ",$checkexclude" | sed -e 's/^/\^/g' -e 's/,/\$|/g' -e 's/$/\$/g')"
+
+      if echo "$c" | grep -E "$checkexcluded" 2>/dev/null 1>&2; then
+        # Excluded
+        continue
+      elif echo "$c" | grep -vE 'check_[0-9]|check_[a-z]' 2>/dev/null 1>&2; then
+        # Function not a check, fill loop_checks with all check from function
+        loop_checks="$(sed -ne "/$c() {/,/}/{/{/d; /}/d; p}" functions_lib.sh)"
+      else
+        # Just one check
+        loop_checks="$c"
+      fi
+
+      for lc in $loop_checks; do
+        if echo "$lc" | grep -vE "$checkexcluded" 2>/dev/null 1>&2; then
+          # Not excluded
+          "$lc"
+        fi
+      done
+    fi
+  done
+
+  printf "\n"
+  info "Checks: $totalChecks"
+  info "Score: $currentScore"
+
+  endjson "$totalChecks" "$currentScore" "$(date +%s)"
 }
 
 main "$@"
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..7a88f50
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,21 @@
+docker-bench-security:
+    # use image if you have a dedicated build step:
+    #   docker build --rm -t docker-bench-security .
+    # image: docker-bench-security
+
+    # use build path to Dockerfile if docker-compose should build the image
+    build: .
+
+    cap_add:
+        - audit_control
+    labels:
+        - docker_bench_security
+    net: host
+    pid: host
+    stdin_open: true
+    tty: true
+    volumes:
+        - /var/lib:/var/lib:ro
+        - /var/run/docker.sock:/var/run/docker.sock:ro
+        - /usr/lib/systemd:/usr/lib/systemd:ro
+        - /etc:/etc:ro
diff --git a/functions_lib.sh b/functions_lib.sh
new file mode 100644
index 0000000..1156986
--- /dev/null
+++ b/functions_lib.sh
@@ -0,0 +1,345 @@
+#!/bin/sh
+
+host_configuration() {
+  check_1
+  check_1_1
+  check_1_1_1
+  check_1_1_2
+  check_1_2
+  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
+}
+
+host_configuration_level1() {
+  check_1
+  check_1_1
+  check_1_1_1
+  check_1_1_2
+  check_1_2
+  check_1_2_1
+  check_1_2_2
+  check_1_2_3
+  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
+}
+
+docker_daemon_configuration() {
+  check_2
+  check_2_1
+  check_2_2
+  check_2_3
+  check_2_4
+  check_2_5
+  check_2_6
+  check_2_7
+  check_2_8
+  check_2_9
+  check_2_10
+  check_2_11
+  check_2_12
+  check_2_13
+  check_2_14
+  check_2_15
+  check_2_16
+  check_2_17
+  check_2_end
+}
+
+docker_daemon_configuration_level1() {
+  check_2
+  check_2_1
+  check_2_2
+  check_2_3
+  check_2_4
+  check_2_5
+  check_2_6
+  check_2_7
+  check_2_13
+  check_2_14
+  check_2_16
+  check_2_17
+  check_2_end
+}
+
+docker_daemon_files() {
+  check_3
+  check_3_1
+  check_3_2
+  check_3_3
+  check_3_4
+  check_3_5
+  check_3_6
+  check_3_7
+  check_3_8
+  check_3_9
+  check_3_10
+  check_3_11
+  check_3_12
+  check_3_13
+  check_3_14
+  check_3_15
+  check_3_16
+  check_3_17
+  check_3_18
+  check_3_19
+  check_3_20
+  check_3_21
+  check_3_22
+  check_3_end
+}
+
+docker_daemon_files_level1() {
+  check_3
+  check_3_1
+  check_3_2
+  check_3_3
+  check_3_4
+  check_3_5
+  check_3_6
+  check_3_7
+  check_3_8
+  check_3_9
+  check_3_10
+  check_3_11
+  check_3_12
+  check_3_13
+  check_3_14
+  check_3_15
+  check_3_16
+  check_3_17
+  check_3_18
+  check_3_19
+  check_3_20
+  check_3_21
+  check_3_22
+  check_3_end
+}
+
+container_images() {
+  check_4
+  check_4_1
+  check_4_2
+  check_4_3
+  check_4_4
+  check_4_5
+  check_4_6
+  check_4_7
+  check_4_8
+  check_4_9
+  check_4_10
+  check_4_11
+  check_4_end
+}
+
+container_images_level1() {
+  check_4
+  check_4_1
+  check_4_2
+  check_4_3
+  check_4_4
+  check_4_6
+  check_4_7
+  check_4_9
+  check_4_10
+  check_4_end
+}
+
+container_runtime() {
+  check_5
+  check_running_containers
+  check_5_1
+  check_5_2
+  check_5_3
+  check_5_4
+  check_5_5
+  check_5_6
+  check_5_7
+  check_5_8
+  check_5_9
+  check_5_10
+  check_5_11
+  check_5_12
+  check_5_13
+  check_5_14
+  check_5_15
+  check_5_16
+  check_5_17
+  check_5_18
+  check_5_19
+  check_5_20
+  check_5_21
+  check_5_22
+  check_5_23
+  check_5_24
+  check_5_25
+  check_5_26
+  check_5_27
+  check_5_28
+  check_5_29
+  check_5_30
+  check_5_31
+  check_5_end
+}
+
+container_runtime_level1() {
+  check_5
+  check_running_containers
+  check_5_1
+  check_5_3
+  check_5_4
+  check_5_5
+  check_5_6
+  check_5_7
+  check_5_8
+  check_5_9
+  check_5_10
+  check_5_11
+  check_5_12
+  check_5_13
+  check_5_14
+  check_5_15
+  check_5_16
+  check_5_17
+  check_5_18
+  check_5_19
+  check_5_20
+  check_5_21
+  check_5_24
+  check_5_25
+  check_5_26
+  check_5_27
+  check_5_28
+  check_5_30
+  check_5_31
+  check_5_end
+}
+
+docker_security_operations() {
+  check_6
+  check_6_1
+  check_6_2
+  check_6_end
+}
+
+docker_security_operations_level1() {
+  check_6
+  check_6_1
+  check_6_2
+  check_6_end
+}
+
+docker_swarm_configuration() {
+  check_7
+  check_7_1
+  check_7_2
+  check_7_3
+  check_7_4
+  check_7_5
+  check_7_6
+  check_7_7
+  check_7_8
+  check_7_9
+  check_7_10
+  check_7_end
+}
+
+docker_swarm_configuration_level1() {
+  check_7
+  check_7_1
+  check_7_2
+  check_7_3
+  check_7_4
+  check_7_7
+  check_7_end
+}
+
+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_2
+  check_8_2_1
+  check_8_end
+}
+
+docker_enterprise_configuration_level1() {
+  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_2
+  check_8_2_1
+  check_8_end
+}
+
+community_checks() {
+  check_c
+  check_c_1
+  check_c_2
+  check_c_end
+}
+
+# CIS
+cis() {
+  host_configuration
+  docker_daemon_configuration
+  docker_daemon_files
+  container_images
+  container_runtime
+  docker_security_operations
+  docker_swarm_configuration
+  docker_enterprise_configuration
+}
+
+cis_level1() {
+  host_configuration_level1
+  docker_daemon_configuration_level1
+  docker_daemon_files_level1
+  container_images_level1
+  container_runtime_level1
+  docker_security_operations_level1
+  docker_swarm_configuration_level1
+  docker_enterprise_configuration_level1
+}
+
+# Community contributed
+community() {
+  community_checks
+}
+
+# All
+all() {
+  cis
+  community
+}
diff --git a/helper_lib.sh b/helper_lib.sh
index ece69c8..bb89aee 100644
--- a/helper_lib.sh
+++ b/helper_lib.sh
@@ -3,36 +3,127 @@
 # Returns the absolute path of a given string
 abspath () { case "$1" in /*)printf "%s\n" "$1";; *)printf "%s\n" "$PWD/$1";; esac; }
 
+# Audit rules default path
+auditrules="/etc/audit/audit.rules"
+
 # Compares versions of software of the format X.Y.Z
 do_version_check() {
-    [ "$1" = "$2" ] && return 10
+  [ "$1" = "$2" ] && return 10
 
-    ver1front=$(printf "%s" "$1" | cut -d "." -f -1)
-    ver1back=$(printf "%s" "$1" | cut -d "." -f 2-)
-    ver2front=$(printf "%s" "$2" | cut -d "." -f -1)
-    ver2back=$(printf "%s" "$2" | cut -d "." -f 2-)
+  ver1front=$(printf "%s" "$1" | cut -d "." -f -1)
+  ver1back=$(printf "%s" "$1" | cut -d "." -f 2-)
+  ver2front=$(printf "%s" "$2" | cut -d "." -f -1)
+  ver2back=$(printf "%s" "$2" | cut -d "." -f 2-)
 
-    if [ "$ver1front" != "$1" ] || [ "$ver2front" != "$2" ]; then
-        [ "$ver1front" -gt "$ver2front" ] && return 11
-        [ "$ver1front" -lt "$ver2front" ] && return 9
+  if [ "$ver1front" != "$1" ] || [ "$ver2front" != "$2" ]; then
+    [ "$ver1front" -gt "$ver2front" ] && return 11
+    [ "$ver1front" -lt "$ver2front" ] && return 9
 
-        [ "$ver1front" = "$1" ] || [ -z "$ver1back" ] && ver1back=0
-        [ "$ver2front" = "$2" ] || [ -z "$ver2back" ] && ver2back=0
-        do_version_check "$ver1back" "$ver2back"
-        return $?
-    else
-        [ "$1" -gt "$2" ] && return 11 || return 9
-    fi
+    [ "$ver1front" = "$1" ] || [ -z "$ver1back" ] && ver1back=0
+    [ "$ver2front" = "$2" ] || [ -z "$ver2back" ] && ver2back=0
+      do_version_check "$ver1back" "$ver2back"
+      return $?
+  else
+    [ "$1" -gt "$2" ] && return 11 || return 9
+  fi
 }
 
-# Compares two strings and returns 0 if the second is a substring of the first
-contains() {
-    string="$1"
-    substring="$2"
-    if [ "${string#*$substring}" != "$string" ]
-    then
-        return 0    # $substring is in $string
-    else
-        return 1    # $substring is not in $string
-    fi
+# Extracts commandline args from the newest running processes named like the first parameter
+get_command_line_args() {
+  PROC="$1"
+
+  for PID in $(pgrep -f -n "$PROC"); do
+    tr "\0" " " < /proc/"$PID"/cmdline
+  done
+}
+
+# Extract the cumulative command line arguments for the docker daemon
+#
+# If specified multiple times, all matches are returned.
+# Accounts for long and short variants, call with short option.
+# Does not account for option defaults or implicit options.
+get_docker_cumulative_command_line_args() {
+  OPTION="$1"
+
+  if ! get_command_line_args "docker daemon" >/dev/null 2>&1 ; then
+    line_arg="docker daemon"
+  else
+    line_arg="dockerd"
+  fi
+
+  get_command_line_args "$line_arg" |
+  # normalize known long options to their short versions
+  sed \
+    -e 's/\-\-debug/-D/g' \
+    -e 's/\-\-host/-H/g' \
+    -e 's/\-\-log-level/-l/g' \
+    -e 's/\-\-version/-v/g' \
+    |
+    # normalize parameters separated by space(s) to -O=VALUE
+    sed \
+      -e 's/\-\([DHlv]\)[= ]\([^- ][^ ]\)/-\1=\2/g' \
+      |
+    # get the last interesting option
+    tr ' ' "\n" |
+    grep "^${OPTION}" |
+    # normalize quoting of values
+    sed \
+      -e 's/"//g' \
+      -e "s/'//g"
+}
+
+# Extract the effective command line arguments for the docker daemon
+#
+# Accounts for multiple specifications, takes the last option.
+# Accounts for long and short variants, call with short option
+# Does not account for option default or implicit options.
+get_docker_effective_command_line_args() {
+  OPTION="$1"
+  get_docker_cumulative_command_line_args "$OPTION" | tail -n1
+}
+
+get_docker_configuration_file() {
+  FILE="$(get_docker_effective_command_line_args '--config-file' | \
+    sed 's/.*=//g')"
+
+  if [ -f "$FILE" ]; then
+    CONFIG_FILE="$FILE"
+  elif [ -f '/etc/docker/daemon.json' ]; then
+    CONFIG_FILE='/etc/docker/daemon.json'
+  else
+    CONFIG_FILE='/dev/null'
+  fi
+}
+
+get_docker_configuration_file_args() {
+  OPTION="$1"
+
+  get_docker_configuration_file
+
+  grep "$OPTION" "$CONFIG_FILE" | sed 's/.*://g' | tr -d '" ',
+}
+
+get_service_file() {
+  SERVICE="$1"
+
+  if [ -f "/etc/systemd/system/$SERVICE" ]; then
+    echo "/etc/systemd/system/$SERVICE"
+  elif [ -f "/lib/systemd/system/$SERVICE" ]; then
+    echo "/lib/systemd/system/$SERVICE"
+  elif systemctl show -p FragmentPath "$SERVICE" 2> /dev/null 1>&2; then
+    systemctl show -p FragmentPath "$SERVICE" | sed 's/.*=//'
+  else
+    echo "/usr/lib/systemd/system/$SERVICE"
+  fi
+}
+
+yell_info() {
+yell "# ------------------------------------------------------------------------------
+# Docker Bench for Security v$version
+#
+# Docker, Inc. (c) 2015-
+#
+# Checks for dozens of common best-practices around deploying Docker containers in production.
+# Inspired by the CIS Docker Benchmark v1.2.0.
+# ------------------------------------------------------------------------------"
 }
diff --git a/output_lib.sh b/output_lib.sh
index f4f61bc..384dfe0 100644
--- a/output_lib.sh
+++ b/output_lib.sh
@@ -1,9 +1,18 @@
 #!/bin/sh
-bldred='\033[1;31m'
-bldgrn='\033[1;32m'
-bldblu='\033[1;34m'
-bldylw='\033[1;33m' # Yellow
-txtrst='\033[0m'
+
+if [ -n "$nocolor" ] && [ "$nocolor" = "nocolor" ]; then
+  bldred=''
+  bldgrn=''
+  bldblu=''
+  bldylw=''
+  txtrst=''
+else
+  bldred='\033[1;31m'
+  bldgrn='\033[1;32m'
+  bldblu='\033[1;34m'
+  bldylw='\033[1;33m' # Yellow
+  txtrst='\033[0m'
+fi
 
 logit () {
   printf "%b\n" "$1" | tee -a "$logger"
@@ -21,6 +30,67 @@ warn () {
   printf "%b\n" "${bldred}[WARN]${txtrst} $1" | tee -a "$logger"
 }
 
+note () {
+  printf "%b\n" "${bldylw}[NOTE]${txtrst} $1" | tee -a "$logger"
+}
+
 yell () {
   printf "%b\n" "${bldylw}$1${txtrst}\n"
 }
+
+beginjson () {
+  printf "{\n  \"dockerbenchsecurity\": \"%s\",\n  \"start\": %s,\n  \"tests\": [" "$1" "$2" | tee "$logger.json" 2>/dev/null 1>&2
+}
+
+endjson (){
+  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
+}
+
+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"
+      # Also limit the number of items to $limit, if $limit is non-zero
+      if [ $limit != 0 ]; then
+        truncItems=""
+        ITEM_COUNT=0
+        for item in $3; do
+          truncItems="$truncItems $item"
+          ITEM_COUNT=$((ITEM_COUNT + 1));
+          if [ "$ITEM_COUNT" == "$limit" ]; then
+            truncItems="$truncItems (truncated)"
+            break;
+          fi
+        done
+      else
+        truncItems=$3
+      fi
+      itemsJson=$(printf "["; ISEP=""; ITEMCOUNT=0; for item in $truncItems; do printf "%s\"%s\"" "$ISEP" "$item"; ISEP=","; done; printf "]")
+      printf "\"result\": \"%s\", \"details\": \"%s: %s\", \"items\": %s}" "$1" "$2" "$truncItems" "$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 6e2b66d..3a2e843 100644
--- a/tests/1_host_configuration.sh
+++ b/tests/1_host_configuration.sh
@@ -1,210 +1,478 @@
 #!/bin/sh
 
-logit ""
-info "1 - Host Configuration"
+check_1() {
+  logit ""
+  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="1.1  - Create a separate partition for containers"
-grep /var/lib/docker /etc/fstab >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  pass "$check_1_1"
-else
-  warn "$check_1_1"
-fi
+check_1_1() {
+  logit ""
+  id_1_1="1.1"
+  desc_1_1="General Configuration"
+  check_1_1="$id_1_1 - $desc_1_1"
+  info "$check_1_1"
+}
 
-# 1.2
-check_1_2="1.2  - Use an updated Linux Kernel"
-kernel_version=$(uname -r | cut -d "-" -f 1)
-do_version_check 3.10 "$kernel_version"
-if [ $? -eq 11 ]; then
-  warn "$check_1_2"
-else
-  pass "$check_1_2"
-fi
+# 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 (Not Scored)"
+  check_1_1_1="$id_1_1_1  - $desc_1_1_1"
+  starttestjson "$id_1_1_1" "$desc_1_1_1"
 
-# 1.5
-check_1_5="1.5  - Remove all non-essential services from the host - Network"
-# Check for listening network services.
-listening_services=$(netstat -na | grep -v tcp6 | grep -v unix | grep -c LISTEN)
-if [ "$listening_services" -eq 0 ]; then
-  warn "1.5  - Failed to get listening services for check: $check_1_5"
-else
-  if [ "$listening_services" -gt 5 ]; then
-    warn "$check_1_5"
-    warn "     * Host listening on: $listening_services ports"
+  totalChecks=$((totalChecks + 1))
+  note "$check_1_1_1"
+  resulttestjson "INFO"
+  currentScore=$((currentScore + 0))
+}
+
+# 1.1.2
+check_1_1_2() {
+  id_1_1_2="1.1.2"
+  desc_1_1_2="Ensure that the version of Docker is up to date (Not Scored)"
+  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:' \
+    | awk '{print $NF; exit}' | tr -d '[:alpha:]-,')
+  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_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_5"
+    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"
+    currentScore=$((currentScore + 0))
   fi
-fi
+}
 
-# 1.6
-check_1_6="1.6  - Keep Docker up to date"
-docker_version=$(docker version | grep 'Server version' | awk '{print $3}')
-do_version_check 1.6.2 $docker_version
-if [ $? -eq 11 ]; then
-  warn "$check_1_6"
-else
-  pass "$check_1_6"
-fi
+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"
+}
 
-# 1.7
-check_1_7="1.7  - Only allow trusted users to control Docker daemon"
-docker_users=$(grep docker /etc/group)
-info "$check_1_7"
-for u in $docker_users; do
-  info "     * $u"
-done
+# 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 (Scored)"
+  check_1_2_1="$id_1_2_1 - $desc_1_2_1"
+  starttestjson "$id_1_2_1" "$desc_1_2_1"
 
-# 1.8
-check_1_8="1.8  - Audit docker daemon"
-command -v auditctl >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  auditctl -l | grep /usr/bin/docker >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_1_8"
+  totalChecks=$((totalChecks + 1))
+  docker_root_dir=$(docker info -f '{{ .DockerRootDir }}')
+  if docker info | grep -q userns ; then
+    docker_root_dir=$(readlink -f "$docker_root_dir/..")
+  fi
+
+  if mountpoint -q -- "$docker_root_dir" >/dev/null 2>&1; then
+    pass "$check_1_2_1"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
   else
-    warn "$check_1_8"
+    warn "$check_1_2_1"
+    resulttestjson "WARN"
+    currentScore=$((currentScore - 1))
   fi
-else
-  warn "1.8  - Failed to inspect: auditctl command not found."
-fi
+}
 
-# 1.9
-check_1_9="1.9  - Audit Docker files and directories - /var/lib/docker"
-command -v auditctl >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  auditctl -l | grep /var/lib/docker >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_1_9"
-  else
-    warn "$check_1_9"
-  fi
-else
-  warn "1.9  - Failed to inspect: auditctl command not found."
-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 (Scored)"
+  check_1_2_2="$id_1_2_2  - $desc_1_2_2"
+  starttestjson "$id_1_2_2" "$desc_1_2_2"
 
-# 1.10
-check_1_10="1.10 - Audit Docker files and directories - /etc/docker"
-command -v auditctl >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  auditctl -l | grep /etc/docker >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_1_10"
+  totalChecks=$((totalChecks + 1))
+  if command -v getent >/dev/null 2>&1; then
+    docker_users=$(getent group docker)
   else
-    warn "$check_1_10"
+    docker_users=$(grep 'docker' /etc/group)
   fi
-else
-  warn "1.10 - Failed to inspect: auditctl command not found."
-fi
+  info "$check_1_2_2"
+  for u in $docker_users; do
+    info "       * $u"
+  done
+  resulttestjson "INFO" "users" "$docker_users"
+  currentScore=$((currentScore + 0))
+}
 
-# 1.11
-check_1_11="1.11 - Audit Docker files and directories - docker-registry.service"
-command -v auditctl >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  auditctl -l | grep /usr/lib/systemd/system/docker-registry.service >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_1_11"
-  else
-    warn "$check_1_11"
-  fi
-else
-  warn "1.11 - Failed to inspect: auditctl command not found."
-fi
+# 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 (Scored)"
+  check_1_2_3="$id_1_2_3  - $desc_1_2_3"
+  starttestjson "$id_1_2_3" "$desc_1_2_3"
 
-# 1.12
-check_1_12="1.12 - Audit Docker files and directories - docker.service"
-command -v auditctl >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  auditctl -l | grep /usr/lib/systemd/system/docker.service >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_1_12"
+  totalChecks=$((totalChecks + 1))
+  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_2_3"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      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_2_3"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
   else
-    warn "$check_1_12"
+    warn "$check_1_2_3"
+    resulttestjson "WARN"
+    currentScore=$((currentScore - 1))
   fi
-else
-  warn "1.12 - Failed to inspect: auditctl command not found."
-fi
+}
 
-# 1.13
-check_1_13="1.13 - Audit Docker files and directories - /var/run/docker.sock"
-command -v auditctl >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  auditctl -l | grep /var/run/docker.sock >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_1_13"
-  else
-    warn "$check_1_13"
-  fi
-else
-  warn "1.13 - Failed to inspect: auditctl command not found."
-fi
+# 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 (Scored)"
+  check_1_2_4="$id_1_2_4  - $desc_1_2_4"
+  starttestjson "$id_1_2_4" "$desc_1_2_4"
 
-# 1.14
-check_1_14="1.14 - Audit Docker files and directories - /etc/sysconfig/docker"
-command -v auditctl >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  auditctl -l | grep /etc/sysconfig/docker >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_1_14"
+  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_2_4"
+        resulttestjson "PASS"
+        currentScore=$((currentScore + 1))
+      else
+        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_2_4"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_1_2_4"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    fi
   else
-    warn "$check_1_14"
+    info "$check_1_2_4"
+    info "       * Directory not found"
+    resulttestjson "INFO" "Directory not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  warn "1.14 - Failed to inspect: auditctl command not found."
-fi
+}
 
-# 1.15
-check_1_15="1.15 - Audit Docker files and directories - /etc/sysconfig/docker-network"
-command -v auditctl >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  auditctl -l | grep /etc/sysconfig/docker-network >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_1_15"
-  else
-    warn "$check_1_15"
-  fi
-else
-  warn "1.15 - Failed to inspect: auditctl command not found."
-fi
+# 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 (Scored)"
+  check_1_2_5="$id_1_2_5  - $desc_1_2_5"
+  starttestjson "$id_1_2_5" "$desc_1_2_5"
 
-# 1.16
-check_1_16="1.16 - Audit Docker files and directories - /etc/sysconfig/docker-registry"
-command -v auditctl >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  auditctl -l | grep /etc/sysconfig/docker-registry >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_1_16"
+  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_2_5"
+        resulttestjson "PASS"
+        currentScore=$((currentScore + 1))
+      else
+        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_2_5"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_1_2_5"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    fi
   else
-    warn "$check_1_16"
-  fi
-else
-  warn "1.16 - Failed to inspect: auditctl command not found."
+    info "$check_1_2_5"
+    info "       * Directory not found"
+    resulttestjson "INFO" "Directory not found"
+    currentScore=$((currentScore + 0))
 fi
+}
 
-# 1.17
-check_1_17="1.17 - Audit Docker files and directories - /etc/sysconfig/docker-storage"
-command -v auditctl >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  auditctl -l | grep /etc/sysconfig/docker-storage >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_1_17"
-  else
-    warn "$check_1_17"
-  fi
-else
-  warn "1.17 - Failed to inspect: auditctl command not found."
-fi
+# 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 (Scored)"
+  check_1_2_6="$id_1_2_6  - $desc_1_2_6"
+  starttestjson "$id_1_2_6" "$desc_1_2_6"
 
-# 1.18
-check_1_18="1.18 - Audit Docker files and directories - /etc/default/docker"
-command -v auditctl >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  auditctl -l | grep /etc/default/docker >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_1_18"
+  totalChecks=$((totalChecks + 1))
+  file="$(get_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_2_6"
+        resulttestjson "PASS"
+        currentScore=$((currentScore + 1))
+      else
+        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_2_6"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_1_2_6"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    fi
   else
-    warn "$check_1_18"
+    info "$check_1_2_6"
+    info "       * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  warn "1.18 - Failed to inspect: auditctl command not found."
-fi
+}
+
+# 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 (Scored)"
+  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_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_2_7"
+        resulttestjson "PASS"
+        currentScore=$((currentScore + 1))
+      else
+        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_2_7"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_1_2_7"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    fi
+  else
+    info "$check_1_2_7"
+    info "       * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
+  fi
+}
+
+# 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 (Scored)"
+  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_2_8"
+        resulttestjson "PASS"
+        currentScore=$((currentScore + 1))
+      else
+        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_2_8"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_1_2_8"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    fi
+  else
+    info "$check_1_2_8"
+    info "       * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
+  fi
+}
+
+# 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 (Scored)"
+  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() {
+  id_1_2_10="1.2.10"
+  desc_1_2_10="Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json (Scored)"
+  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_2_10"
+        resulttestjson "PASS"
+        currentScore=$((currentScore + 1))
+      else
+        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_2_10"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_1_2_10"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    fi
+  else
+    info "$check_1_2_10"
+    info "        * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
+  fi
+}
+
+# 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 (Scored)"
+  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/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_2_11"
+        resulttestjson "PASS"
+        currentScore=$((currentScore + 1))
+      else
+        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_2_11"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_1_2_11"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    fi
+  else
+    info "$check_1_2_11"
+    info "        * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
+  fi
+}
+
+# 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 (Scored)"
+  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/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_2_12"
+        resulttestjson "PASS"
+        currentScore=$((currentScore + 1))
+      else
+        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_2_12"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_1_2_12"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    fi
+  else
+    info "$check_1_2_12"
+    info "        * File not found"
+    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 ed94926..83cc8eb 100644
--- a/tests/2_docker_daemon_configuration.sh
+++ b/tests/2_docker_daemon_configuration.sh
@@ -1,105 +1,442 @@
 #!/bin/sh
 
-logit "\n"
-info "2 - Docker Daemon Configuration"
+check_2() {
+  logit "\n"
+  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="2.1  - Do not use lxc execution driver"
-pgrep -lf docker | grep lxc >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  warn "$check_2_1"
-else
-  pass "$check_2_1"
-fi
+check_2_1() {
+  id_2_1="2.1"
+  desc_2_1="Ensure network traffic is restricted between containers on the default bridge (Scored)"
+  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"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  elif get_docker_configuration_file_args 'icc' | grep "false" >/dev/null 2>&1; then
+    pass "$check_2_1"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  else
+    warn "$check_2_1"
+    resulttestjson "WARN"
+    currentScore=$((currentScore - 1))
+  fi
+}
 
 # 2.2
-check_2_2="2.2  - Restrict network traffic between containers"
-pgrep -lf docker | grep "icc=false" >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  pass "$check_2_2"
-else
-  warn "$check_2_2"
-fi
+check_2_2() {
+  id_2_2="2.2"
+  desc_2_2="Ensure the logging level is set to 'info' (Scored)"
+  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"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    elif [ -z "$(get_docker_configuration_file_args 'log-level')" ]; then
+      pass "$check_2_2"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_2_2"
+      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"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_2_2"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    fi
+  else
+    pass "$check_2_2"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  fi
+}
 
 # 2.3
-check_2_3="2.3  - Set the logging level"
-pgrep -lf docker | grep "log-level=\"debug\"" >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  warn "$check_2_3"
-else
-  pass "$check_2_3"
-fi
+check_2_3() {
+  id_2_3="2.3"
+  desc_2_3="Ensure Docker is allowed to make changes to iptables (Scored)"
+  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"
+    resulttestjson "WARN"
+    currentScore=$((currentScore - 1))
+  elif get_docker_configuration_file_args 'iptables' | grep "false" >/dev/null 2>&1; then
+    warn "$check_2_3"
+    resulttestjson "WARN"
+    currentScore=$((currentScore - 1))
+  else
+    pass "$check_2_3"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  fi
+}
 
 # 2.4
-check_2_4="2.4  - Allow Docker to make changes to iptables"
-pgrep -lf docker | grep "iptables=false" >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  warn "$check_2_4"
-else
-  pass "$check_2_4"
-fi
+check_2_4() {
+  id_2_4="2.4"
+  desc_2_4="Ensure insecure registries are not used (Scored)"
+  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"
+    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"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_2_4"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    fi
+  else
+    pass "$check_2_4"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  fi
+}
 
 # 2.5
-check_2_5="2.5  - Do not use insecure registries"
-pgrep -lf docker | grep "insecure-registry" >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  warn "$check_2_5"
-else
-  pass "$check_2_5"
-fi
+check_2_5() {
+  id_2_5="2.5"
+  desc_2_5="Ensure aufs storage driver is not used (Scored)"
+  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 "^\sStorage Driver:\s*aufs\s*$" >/dev/null 2>&1; then
+    warn "$check_2_5"
+    resulttestjson "WARN"
+    currentScore=$((currentScore - 1))
+  else
+    pass "$check_2_5"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  fi
+}
 
 # 2.6
-check_2_6="2.6  - Setup a local registry mirror"
-pgrep -lf docker | grep "registry-mirror" >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  pass "$check_2_6"
-else
-  info "$check_2_6"
-  info "     * No local registry currently configured"
-fi
+check_2_6() {
+  id_2_6="2.6"
+  desc_2_6="Ensure TLS authentication for Docker daemon is configured (Scored)"
+  check_2_6="$id_2_6  - $desc_2_6"
+  starttestjson "$id_2_6" "$desc_2_6"
+
+  totalChecks=$((totalChecks + 1))
+  if [ $(get_docker_configuration_file_args 'tcp://') ] || \
+    [ $(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"
+      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"
+      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"
+      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"
+    resulttestjson "INFO" "Docker daemon not listening on TCP"
+    currentScore=$((currentScore + 0))
+  fi
+}
 
 # 2.7
-check_2_7="2.7  - Do not use the aufs storage driver"
-docker info 2>/dev/null | grep -e "^Storage Driver:\s*aufs\s*$" >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  warn "$check_2_7"
-else
-  pass "$check_2_7"
-fi
+check_2_7() {
+  id_2_7="2.7"
+  desc_2_7="Ensure the default ulimit is configured appropriately (Not Scored)"
+  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"
+    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"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  else
+    info "$check_2_7"
+    info "     * Default ulimit doesn't appear to be set"
+    resulttestjson "INFO" "Default ulimit doesn't appear to be set"
+    currentScore=$((currentScore + 0))
+  fi
+}
 
 # 2.8
-check_2_8="2.8  - Do not bind Docker to another IP/Port or a Unix socket"
-pgrep -lf docker | grep "\-H" >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  info "$check_2_8"
-  info "     * Docker daemon running with -H"
-else
-  pass "$check_2_8"
-fi
+check_2_8() {
+  id_2_8="2.8"
+  desc_2_8="Enable user namespace support (Scored)"
+  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"
+    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"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  else
+    warn "$check_2_8"
+    resulttestjson "WARN"
+    currentScore=$((currentScore - 1))
+  fi
+}
 
 # 2.9
-check_2_9="2.9  - Configure TLS authentication for Docker daemon"
-pgrep -lf docker | grep "tcp://" >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  pgrep -lf docker | grep "tlsverify" | grep "tlskey" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_2_9"
-    info "     * Docker daemon currently listening on TCP"
-  else
+check_2_9() {
+  id_2_9="2.9"
+  desc_2_9="Ensure the default cgroup usage has been confirmed (Scored)"
+  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"
-    warn "     * Docker daemon currently listening on TCP without --tlsverify"
+    info "     * Confirm cgroup usage"
+    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"
+    resulttestjson "WARN" "Confirm cgroup usage"
+    currentScore=$((currentScore + 0))
+  else
+    pass "$check_2_9"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
   fi
-else
-  info "$check_2_9"
-  info "     * Docker daemon not listening on TCP"
-fi
+}
 
 # 2.10
-check_2_10="2.10 - Set default ulimit as appropriate"
-pgrep -lf docker | grep "default-ulimit" >/dev/null 2>&1
-if [ $? -eq 0 ]; then
-  pass "$check_2_10"
-else
-  info "$check_2_10"
-  info "     * Default ulimit doesn't appear to be set"
-fi
+check_2_10() {
+  id_2_10="2.10"
+  desc_2_10="Ensure base device size is not changed until needed (Scored)"
+  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"
+    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"
+    resulttestjson "WARN"
+    currentScore=$((currentScore - 1))
+  else
+    pass "$check_2_10"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  fi
+}
+
+# 2.11
+check_2_11() {
+  id_2_11="2.11"
+  desc_2_11="Ensure that authorization for Docker client commands is enabled (Scored)"
+  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"
+    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"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  else
+    warn "$check_2_11"
+    resulttestjson "WARN"
+    currentScore=$((currentScore - 1))
+  fi
+}
+
+# 2.12
+check_2_12() {
+  id_2_12="2.12"
+  desc_2_12="Ensure centralized and remote logging is configured (Scored)"
+  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"
+    resulttestjson "WARN"
+    currentScore=$((currentScore - 1))
+  else
+    pass "$check_2_12"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  fi
+}
+
+# 2.13
+check_2_13() {
+  id_2_13="2.13"
+  desc_2_13="Ensure live restore is enabled (Scored)"
+  check_2_13="$id_2_13  - $desc_2_13"
+  starttestjson "$id_2_13" "$desc_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 '--live-restore' | grep "live-restore" >/dev/null 2>&1; then
+      pass "$check_2_13"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_2_13"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    fi
+  fi
+}
+
+# 2.14
+check_2_14() {
+  id_2_14="2.14"
+  desc_2_14="Ensure Userland Proxy is Disabled (Scored)"
+  check_2_14="$id_2_14  - $desc_2_14"
+  starttestjson "$id_2_14" "$desc_2_14"
+
+  totalChecks=$((totalChecks + 1))
+  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
+    warn "$check_2_14"
+    resulttestjson "WARN"
+    currentScore=$((currentScore - 1))
+  fi
+}
+
+# 2.15
+check_2_15() {
+  id_2_15="2.15"
+  desc_2_15="Ensure that a daemon-wide custom seccomp profile is applied if appropriate (Not Scored)"
+  check_2_15="$id_2_15  - $desc_2_15"
+  starttestjson "$id_2_15" "$desc_2_15"
+
+  totalChecks=$((totalChecks + 1))
+  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
+    info "$check_2_15"
+    resulttestjson "INFO"
+    currentScore=$((currentScore + 0))
+  fi
+}
+
+# 2.16
+check_2_16() {
+  docker_version=$(docker version | grep -i -A2 '^server' | grep ' Version:' \
+    | awk '{print $NF; exit}' | tr -d '[:alpha:]-,.' | cut -c 1-4)
+
+  id_2_16="2.16"
+  desc_2_16="Ensure that experimental features are not implemented in production (Scored)"
+  check_2_16="$id_2_16  - $desc_2_16"
+  starttestjson "$id_2_16" "$desc_2_16"
+
+  totalChecks=$((totalChecks + 1))
+  if [ "$docker_version" -le 1903 ]; 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
+      warn "$check_2_16"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    fi
+  else
+    desc_2_16="$desc_2_16 (Deprecated)"
+    check_2_16="$id_2_16  - $desc_2_16"
+    info "$desc_2_16"
+    resulttestjson "INFO"
+  fi
+}
+
+# 2.17
+check_2_17() {
+  id_2_17="2.17"
+  desc_2_17="Ensure containers are restricted from acquiring new privileges (Scored)"
+  check_2_17="$id_2_17  - $desc_2_17"
+  starttestjson "$id_2_17" "$desc_2_17"
+
+  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_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))
+  else
+    warn "$check_2_17"
+    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 36e49ab..3d29598 100644
--- a/tests/3_docker_daemon_configuration_files.sh
+++ b/tests/3_docker_daemon_configuration_files.sh
@@ -1,435 +1,668 @@
 #!/bin/sh
 
-logit "\n"
-info "3 - Docker Daemon Configuration Files"
+check_3() {
+  logit "\n"
+  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="3.1  - Verify that docker.service file ownership is set to root:root"
-file="/usr/lib/systemd/system/docker.service"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $3, $4}' | grep "root root" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_1"
+check_3_1() {
+  id_3_1="3.1"
+  desc_3_1="Ensure that the docker.service file ownership is set to root:root (Scored)"
+  check_3_1="$id_3_1  - $desc_3_1"
+  starttestjson "$id_3_1" "$desc_3_1"
+
+  totalChecks=$((totalChecks + 1))
+  file="$(get_service_file docker.service)"
+  if [ -f "$file" ]; then
+    if [ "$(stat -c %u%g $file)" -eq 00 ]; then
+      pass "$check_3_1"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_1"
+      warn "     * Wrong ownership for $file"
+      resulttestjson "WARN" "Wrong ownership for $file"
+      currentScore=$((currentScore - 1))
+    fi
   else
-    warn "$check_3_1"
-    warn "     * Wrong ownership for $file"
+    info "$check_3_1"
+    info "     * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_1"
-  info "     * File not found"
-fi
+}
 
 # 3.2
-check_3_2="3.2  - Verify that docker.service file permissions are set to 644"
-file="/usr/lib/systemd/system/docker.service"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $1}' | grep "rw-r--r--" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_2"
+check_3_2() {
+  id_3_2="3.2"
+  desc_3_2="Ensure that docker.service file permissions are appropriately set (Scored)"
+  check_3_2="$id_3_2  - $desc_3_2"
+  starttestjson "$id_3_2" "$desc_3_2"
+
+  totalChecks=$((totalChecks + 1))
+  file="$(get_service_file docker.service)"
+  if [ -f "$file" ]; then
+    if [ "$(stat -c %a $file)" -eq 644 ] || [ "$(stat -c %a $file)" -eq 600 ]; then
+      pass "$check_3_2"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_2"
+      warn "     * Wrong permissions for $file"
+      resulttestjson "WARN" "Wrong permissions for $file"
+      currentScore=$((currentScore - 1))
+    fi
   else
-    warn "$check_3_2"
-    warn "     * Wrong permissions for $file"
+    info "$check_3_2"
+    info "     * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_2"
-  info "     * File not found"
-fi
+}
 
 # 3.3
-check_3_3="3.3  - Verify that docker-registry.service file ownership is set to root:root"
-file="/usr/lib/systemd/system/docker-registry.service"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $3, $4}' | grep "root root" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_3"
+check_3_3() {
+  id_3_3="3.3"
+  desc_3_3="Ensure that docker.socket file ownership is set to root:root (Scored)"
+  check_3_3="$id_3_3  - $desc_3_3"
+  starttestjson "$id_3_3" "$desc_3_3"
+
+  totalChecks=$((totalChecks + 1))
+  file="$(get_service_file docker.socket)"
+  if [ -f "$file" ]; then
+    if [ "$(stat -c %u%g $file)" -eq 00 ]; then
+      pass "$check_3_3"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_3"
+      warn "     * Wrong ownership for $file"
+      resulttestjson "WARN" "Wrong ownership for $file"
+      currentScore=$((currentScore - 1))
+    fi
   else
-    warn "$check_3_3"
-    warn "     * Wrong ownership for $file"
+    info "$check_3_3"
+    info "     * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_3"
-  info "     * File not found"
-fi
+}
 
 # 3.4
-check_3_4="3.4  - Verify that docker-registry.service file permissions are set to 644"
-file="/usr/lib/systemd/system/docker-registry.service"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $1}' | grep "rw-r--r--" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_4"
+check_3_4() {
+  id_3_4="3.4"
+  desc_3_4="Ensure that docker.socket file permissions are set to 644 or more restrictive (Scored)"
+  check_3_4="$id_3_4  - $desc_3_4"
+  starttestjson "$id_3_4" "$desc_3_4"
+
+  totalChecks=$((totalChecks + 1))
+  file="$(get_service_file docker.socket)"
+  if [ -f "$file" ]; then
+    if [ "$(stat -c %a $file)" -eq 644 ] || [ "$(stat -c %a $file)" -eq 600 ]; then
+      pass "$check_3_4"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_4"
+      warn "     * Wrong permissions for $file"
+      resulttestjson "WARN" "Wrong permissions for $file"
+      currentScore=$((currentScore - 1))
+    fi
   else
-    warn "$check_3_4"
-    warn "     * Wrong permissions for $file"
+    info "$check_3_4"
+    info "     * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_4"
-  info "     * File not found"
-fi
+}
 
 # 3.5
-check_3_5="3.5  - Verify that docker.socket file ownership is set to root:root"
-file="/usr/lib/systemd/system/docker.socket"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $3, $4}' | grep "root root" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_5"
+check_3_5() {
+  id_3_5="3.5"
+  desc_3_5="Ensure that the /etc/docker directory ownership is set to root:root (Scored)"
+  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"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_5"
+      warn "     * Wrong ownership for $directory"
+      resulttestjson "WARN" "Wrong ownership for $directory"
+      currentScore=$((currentScore - 1))
+    fi
   else
-    warn "$check_3_5"
-    warn "     * Wrong ownership for $file"
+    info "$check_3_5"
+    info "     * Directory not found"
+    resulttestjson "INFO" "Directory not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_5"
-  info "     * File not found"
-fi
+}
 
 # 3.6
-check_3_6="3.6  - Verify that docker.socket file permissions are set to 644"
-file="/usr/lib/systemd/system/docker.socket"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $1}' | grep "rw-r--r--" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_6"
+check_3_6() {
+  id_3_6="3.6"
+  desc_3_6="Ensure that /etc/docker directory permissions are set to 755 or more restrictively (Scored)"
+  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 ] || [ "$(stat -c %a $directory)" -eq 700 ]; then
+      pass "$check_3_6"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_6"
+      warn "     * Wrong permissions for $directory"
+      resulttestjson "WARN" "Wrong permissions for $directory"
+      currentScore=$((currentScore - 1))
+    fi
   else
-    warn "$check_3_6"
-    warn "     * Wrong permissions for $file"
+    info "$check_3_6"
+    info "     * Directory not found"
+    resulttestjson "INFO" "Directory not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_6"
-  info "     * File not found"
-fi
+}
 
 # 3.7
-check_3_7="3.7  - Verify that Docker environment file ownership is set to root:root "
-file="/etc/sysconfig/docker"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $3, $4}' | grep "root root" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_7"
+check_3_7() {
+  id_3_7="3.7"
+  desc_3_7="Ensure that registry certificate file ownership is set to root:root (Scored)"
+  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
+    fail=0
+    owners=$(find "$directory" -type f -name '*.crt')
+    for p in $owners; do
+      if [ "$(stat -c %u $p)" -ne 0 ]; then
+        fail=1
+      fi
+    done
+    if [ $fail -eq 1 ]; then
+      warn "$check_3_7"
+      warn "     * Wrong ownership for $directory"
+      resulttestjson "WARN" "Wrong ownership for $directory"
+      currentScore=$((currentScore - 1))
+    else
+      pass "$check_3_7"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    fi
   else
-    warn "$check_3_7"
-    warn "     * Wrong ownership for $file"
+    info "$check_3_7"
+    info "     * Directory not found"
+    resulttestjson "INFO" "Directory not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_7"
-  info "     * File not found"
-fi
+}
 
 # 3.8
-check_3_8="3.8  - Verify that Docker environment file permissions are set to 644"
-file="/etc/sysconfig/docker"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $1}' | grep "rw-r--r--" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_8"
+check_3_8() {
+  id_3_8="3.8"
+  desc_3_8="Ensure that registry certificate file permissions are set to 444 or more restrictively (Scored)"
+  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
+    fail=0
+    perms=$(find "$directory" -type f -name '*.crt')
+    for p in $perms; do
+      if [ "$(stat -c %a $p)" -ne 444 ] && [ "$(stat -c %a $p)" -ne 400 ]; then
+        fail=1
+      fi
+    done
+    if [ $fail -eq 1 ]; then
+      warn "$check_3_8"
+      warn "     * Wrong permissions for $directory"
+      resulttestjson "WARN" "Wrong permissions for $directory"
+      currentScore=$((currentScore - 1))
+    else
+      pass "$check_3_8"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    fi
   else
-    warn "$check_3_8"
-    warn "     * Wrong permissions for $file"
+    info "$check_3_8"
+    info "     * Directory not found"
+    resulttestjson "INFO" "Directory not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_8"
-  info "     * File not found"
-fi
+}
 
 # 3.9
-check_3_9="3.9  - Verify that docker-network environment file ownership is set to root:root"
-file="/etc/sysconfig/docker-network"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $3, $4}' | grep "root root" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_9"
+check_3_9() {
+  id_3_9="3.9"
+  desc_3_9="Ensure that TLS CA certificate file ownership is set to root:root (Scored)"
+  check_3_9="$id_3_9  - $desc_3_9"
+  starttestjson "$id_3_9" "$desc_3_9"
+
+  totalChecks=$((totalChecks + 1))
+  if [ -n "$(get_docker_configuration_file_args 'tlscacert')" ]; then
+    tlscacert=$(get_docker_configuration_file_args 'tlscacert')
   else
-    warn "$check_3_9"
-    warn "     * Wrong ownership for $file"
+    tlscacert=$(get_docker_effective_command_line_args '--tlscacert' | sed -n 's/.*tlscacert=\([^s]\)/\1/p' | sed 's/--/ --/g' | cut -d " " -f 1)
   fi
-else
-  info "$check_3_9"
-  info "     * File not found"
-fi
+  if [ -f "$tlscacert" ]; then
+    if [ "$(stat -c %u%g "$tlscacert")" -eq 00 ]; then
+      pass "$check_3_9"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_9"
+      warn "     * Wrong ownership for $tlscacert"
+      resulttestjson "WARN" "Wrong ownership for $tlscacert"
+      currentScore=$((currentScore - 1))
+    fi
+  else
+    info "$check_3_9"
+    info "     * No TLS CA certificate found"
+    resulttestjson "INFO" "No TLS CA certificate found"
+    currentScore=$((currentScore + 0))
+  fi
+}
 
 # 3.10
-check_3_10="3.10 - Verify that docker-network environment file permissions are set to 644"
-file="/etc/sysconfig/docker-network"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $1}' | grep "rw-r--r--" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_10"
+check_3_10() {
+  id_3_10="3.10"
+  desc_3_10="Ensure that TLS CA certificate file permissions are set to 444 or more restrictively (Scored)"
+  check_3_10="$id_3_10  - $desc_3_10"
+  starttestjson "$id_3_10" "$desc_3_10"
+
+  totalChecks=$((totalChecks + 1))
+  if [ -n "$(get_docker_configuration_file_args 'tlscacert')" ]; then
+    tlscacert=$(get_docker_configuration_file_args 'tlscacert')
   else
-    warn "$check_3_10"
-    warn "     * Wrong permissions for $file"
+    tlscacert=$(get_docker_effective_command_line_args '--tlscacert' | sed -n 's/.*tlscacert=\([^s]\)/\1/p' | sed 's/--/ --/g' | cut -d " " -f 1)
   fi
-else
-  info "$check_3_10"
-  info "     * File not found"
-fi
+  if [ -f "$tlscacert" ]; then
+    if [ "$(stat -c %a $tlscacert)" -eq 444 ] || [ "$(stat -c %a $tlscacert)" -eq 400 ]; then
+      pass "$check_3_10"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_10"
+      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"
+    resulttestjson "INFO" "No TLS CA certificate found"
+    currentScore=$((currentScore + 0))
+  fi
+}
 
 # 3.11
-check_3_11="3.11 - Verify that docker-registry environment file ownership is set to root:root"
-file="/etc/sysconfig/docker-registry"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $3, $4}' | grep "root root" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_11"
+check_3_11() {
+  id_3_11="3.11"
+  desc_3_11="Ensure that Docker server certificate file ownership is set to root:root (Scored)"
+  check_3_11="$id_3_11  - $desc_3_11"
+  starttestjson "$id_3_11" "$desc_3_11"
+
+  totalChecks=$((totalChecks + 1))
+  if [ -n "$(get_docker_configuration_file_args 'tlscert')" ]; then
+    tlscert=$(get_docker_configuration_file_args 'tlscert')
   else
-    warn "$check_3_11"
-    warn "     * Wrong ownership for $file"
+    tlscert=$(get_docker_effective_command_line_args '--tlscert' | sed -n 's/.*tlscert=\([^s]\)/\1/p' | sed 's/--/ --/g' | cut -d " " -f 1)
   fi
-else
-  info "$check_3_11"
-  info "     * File not found"
-fi
+  if [ -f "$tlscert" ]; then
+    if [ "$(stat -c %u%g "$tlscert")" -eq 00 ]; then
+      pass "$check_3_11"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_11"
+      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"
+    resulttestjson "INFO" "No TLS Server certificate found"
+    currentScore=$((currentScore + 0))
+  fi
+}
 
 # 3.12
-check_3_12="3.12 - Verify that docker-registry environment file permissions are set to 644"
-file="/etc/sysconfig/docker-registry"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $1}' | grep "rw-r--r--" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_12"
+check_3_12() {
+  id_3_12="3.12"
+  desc_3_12="Ensure that the Docker server certificate file permissions are set to 444 or more restrictively (Scored)"
+  check_3_12="$id_3_12  - $desc_3_12"
+  starttestjson "$id_3_12" "$desc_3_12"
+
+  totalChecks=$((totalChecks + 1))
+  if [ -n "$(get_docker_configuration_file_args 'tlscert')" ]; then
+    tlscert=$(get_docker_configuration_file_args 'tlscert')
   else
-    warn "$check_3_12"
-    warn "     * Wrong permissions for $file"
+    tlscert=$(get_docker_effective_command_line_args '--tlscert' | sed -n 's/.*tlscert=\([^s]\)/\1/p' | sed 's/--/ --/g' | cut -d " " -f 1)
   fi
-else
-  info "$check_3_12"
-  info "     * File not found"
-fi
+  if [ -f "$tlscert" ]; then
+    if [ "$(stat -c %a $tlscert)" -eq 444 ] || [ "$(stat -c %a $tlscert)" -eq 400 ]; then
+      pass "$check_3_12"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_12"
+      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"
+    resulttestjson "INFO" "No TLS Server certificate found"
+    currentScore=$((currentScore + 0))
+  fi
+}
 
 # 3.13
-check_3_13="3.13 - Verify that docker-storage environment file ownership is set to root:root"
-file="/etc/sysconfig/docker-storage"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $3, $4}' | grep "root root" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_13"
+check_3_13() {
+  id_3_13="3.13"
+  desc_3_13="Ensure that the Docker server certificate key file ownership is set to root:root (Scored)"
+  check_3_13="$id_3_13  - $desc_3_13"
+  starttestjson "$id_3_13" "$desc_3_13"
+
+  totalChecks=$((totalChecks + 1))
+  if [ -n "$(get_docker_configuration_file_args 'tlskey')" ]; then
+    tlskey=$(get_docker_configuration_file_args 'tlskey')
   else
-    warn "$check_3_13"
-    warn "     * Wrong ownership for $file"
+    tlskey=$(get_docker_effective_command_line_args '--tlskey' | sed -n 's/.*tlskey=\([^s]\)/\1/p' | sed 's/--/ --/g' | cut -d " " -f 1)
   fi
-else
-  info "$check_3_13"
-  info "     * File not found"
-fi
+  if [ -f "$tlskey" ]; then
+    if [ "$(stat -c %u%g "$tlskey")" -eq 00 ]; then
+      pass "$check_3_13"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_13"
+      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"
+    resulttestjson "INFO" "No TLS Key found"
+    currentScore=$((currentScore + 0))
+  fi
+}
 
 # 3.14
-check_3_14="3.14 - Verify that docker-storage environment file permissions are set to 644"
-file="/etc/sysconfig/docker-storage"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $1}' | grep "rw-r--r--" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_14"
+check_3_14() {
+  id_3_14="3.14"
+  desc_3_14="Ensure that the Docker server certificate key file permissions are set to 400 (Scored)"
+  check_3_14="$id_3_14  - $desc_3_14"
+  starttestjson "$id_3_14" "$desc_3_14"
+
+  totalChecks=$((totalChecks + 1))
+  if [ -n "$(get_docker_configuration_file_args 'tlskey')" ]; then
+    tlskey=$(get_docker_configuration_file_args 'tlskey')
   else
-    warn "$check_3_14"
-    warn "     * Wrong permissions for $file"
+    tlskey=$(get_docker_effective_command_line_args '--tlskey' | sed -n 's/.*tlskey=\([^s]\)/\1/p' | sed 's/--/ --/g' | cut -d " " -f 1)
   fi
-else
-  info "$check_3_14"
-  info "     * File not found"
-fi
+  if [ -f "$tlskey" ]; then
+    if [ "$(stat -c %a $tlskey)" -eq 400 ]; then
+      pass "$check_3_14"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_14"
+      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"
+    resulttestjson "INFO" "No TLS Key found"
+    currentScore=$((currentScore + 0))
+  fi
+}
 
 # 3.15
-check_3_15="3.15 - Verify that /etc/docker directory ownership is set to root:root"
-directory="/etc/docker"
-if [ -d "$directory" ]; then
-  ls -ld "$directory" | awk '{print $3, $4}' | grep "root root" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_15"
+check_3_15() {
+  id_3_15="3.15"
+  desc_3_15="Ensure that the Docker socket file ownership is set to root:docker (Scored)"
+  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"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_15"
+      warn "      * Wrong ownership for $file"
+      resulttestjson "WARN" "Wrong ownership for $file"
+      currentScore=$((currentScore - 1))
+    fi
   else
-    warn "$check_3_15"
-    warn "     * Wrong ownership for $directory"
+    info "$check_3_15"
+    info "      * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_15"
-  info "     * Directory not found"
-fi
+}
 
 # 3.16
-check_3_16="3.16 - Verify that /etc/docker directory permissions are set to 755"
-directory="/etc/docker"
-if [ -d "$directory" ]; then
-  perms=$(ls -ld $directory | awk '{print $1}')
-  if [ "$perms" = "drwxr-xr-x." ]; then
-    pass "$check_3_16"
-  elif [ "$perms" = "drwx------" ]; then
-    pass "$check_3_16"
+check_3_16() {
+  id_3_16="3.16"
+  desc_3_16="Ensure that the Docker socket file permissions are set to 660 or more restrictively (Scored)"
+  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 ] || [  "$(stat -c %a $file)" -eq 600 ]; then
+      pass "$check_3_16"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_16"
+      warn "      * Wrong permissions for $file"
+      resulttestjson "WARN" "Wrong permissions for $file"
+      currentScore=$((currentScore - 1))
+    fi
   else
-    warn "$check_3_16"
-    warn "     * Wrong permissions for $directory"
+    info "$check_3_16"
+    info "      * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_16"
-  info "     * Directory not found"
-fi
+}
 
 # 3.17
-check_3_17="3.17 - Verify that registry certificate file ownership is set to root:root"
-directory="/etc/docker/certs.d/"
-if [ -d "$directory" ]; then
-  fail=0
-  owners=$(ls -lL "$directory"/*.crt | awk '{print "$3", "$4"}')
-  for p in $owners; do
-    printf "%s" "$p" | grep "root" >/dev/null 2>&1
-    if [ $? -ne 0 ]; then
-      fail=1
+check_3_17() {
+  id_3_17="3.17"
+  desc_3_17="Ensure that the daemon.json file ownership is set to root:root (Scored)"
+  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"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_17"
+      warn "      * Wrong ownership for $file"
+      resulttestjson "WARN" "Wrong ownership for $file"
+      currentScore=$((currentScore - 1))
     fi
-  done
-  if [ $fail -eq 1 ]; then
-    warn "$check_3_17"
-    warn "     * Wrong ownership for $directory"
   else
-    pass "$check_3_17"
+    info "$check_3_17"
+    info "      * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_17"
-  info "     * Directory not found"
-fi
+}
 
 # 3.18
-check_3_18="3.18 - Verify that registry certificate file permissions are set to 444"
-directory="/etc/docker/certs.d/"
-if [ -d "$directory" ]; then
-  fail=0
-  perms=$(ls -lL "$directory"/*.crt | awk '{print $1}')
-  for p in $perms; do
-    if [ "$p" != "-rw-r--r--." -a "$p" = "-rw-------." ]; then
-      fail=1
+check_3_18() {
+  id_3_18="3.18"
+  desc_3_18="Ensure that daemon.json file permissions are set to 644 or more restrictive (Scored)"
+  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 ] || [  "$(stat -c %a $file)" -eq 640 ] || [ "$(stat -c %a $file)" -eq 600 ]; then
+      pass "$check_3_18"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_18"
+      warn "      * Wrong permissions for $file"
+      resulttestjson "WARN" "Wrong permissions for $file"
+      currentScore=$((currentScore - 1))
     fi
-  done
-  if [ $fail -eq 1 ]; then
-    warn "$check_3_18"
-    warn "     * Wrong permissions for $directory"
   else
-    pass "$check_3_18"
+    info "$check_3_18"
+    info "      * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_18"
-  info "     * Directory not found"
-fi
+}
 
 # 3.19
-check_3_19="3.19 - Verify that TLS CA certificate file ownership is set to root:root"
-tlscacert=$(pgrep -lf docker | sed -n 's/.*tlscacert=\([^s]\)/\1/p' | cut -d " " -f 1)
-if [ -f "$tlscacert" ]; then
-  ls -ld "$tlscacert" | awk '{print $3, $4}' | grep "root root" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_19"
+check_3_19() {
+  id_3_19="3.19"
+  desc_3_19="Ensure that the /etc/default/docker file ownership is set to root:root (Scored)"
+  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"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_3_19"
+      warn "      * Wrong ownership for $file"
+      resulttestjson "WARN" "Wrong ownership for $file"
+      currentScore=$((currentScore - 1))
+    fi
   else
-    warn "$check_3_19"
-    warn "     * Wrong ownership for $tlscacert"
+    info "$check_3_19"
+    info "      * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_19"
-  info "     * No TLS CA certificate found"
-fi
+}
 
 # 3.20
-check_3_20="3.20 - Verify that TLS CA certificate file permissions are set to 444"
-tlscacert=$(pgrep -lf docker | sed -n 's/.*tlscacert=\([^s]\)/\1/p' | cut -d " " -f 1)
-if [ -f "$tlscacert" ]; then
-  perms=$(ls -ld "$tlscacert" | awk '{print $1}')
-  if [ "$perms" = "-rw-r--r--" ]; then
-    pass "$check_3_20"
+check_3_20() {
+  id_3_20="3.20"
+  desc_3_20="Ensure that the /etc/sysconfig/docker file ownership is set to root:root (Scored)"
+  check_3_20="$id_3_20  - $desc_3_20"
+  starttestjson "$id_3_20" "$desc_3_20"
+
+  totalChecks=$((totalChecks + 1))
+  file="/etc/sysconfig/docker"
+  if [ -f "$file" ]; 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 ownership for $file"
+      resulttestjson "WARN" "Wrong ownership for $file"
+      currentScore=$((currentScore - 1))
+    fi
   else
-    warn "$check_3_20"
-    warn "     * Wrong permissions for $tlscacert"
+    info "$check_3_20"
+    info "      * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_20"
-  info "     * No TLS CA certificate found"
-fi
+}
 
 # 3.21
-check_3_21="3.21 - Verify that Docker server certificate file ownership is set to root:root"
-tlscert=$(pgrep -lf docker | sed -n 's/.*tlscert=\([^s]\)/\1/p' | cut -d " " -f 1)
-if [ -f "$tlscert" ]; then
-  ls -ld "$tlscert" | awk '{print $3, $4}' | grep "root root" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_21"
+check_3_21() {
+  id_3_21="3.21"
+  desc_3_21="Ensure that the /etc/sysconfig/docker file permissions are set to 644 or more restrictively (Scored)"
+  check_3_21="$id_3_21  - $desc_3_21"
+  starttestjson "$id_3_21" "$desc_3_21"
+
+  totalChecks=$((totalChecks + 1))
+  file="/etc/sysconfig/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
-    warn "$check_3_21"
-    warn "     * Wrong ownership for $tlscert"
+    info "$check_3_21"
+    info "      * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_21"
-  info "     * No TLS Server certificate found"
-fi
+}
 
 # 3.22
-check_3_22="3.22 - Verify that Docker server certificate file permissions are set to 444"
-tlscacert=$(pgrep -lf docker | sed -n 's/.*tlscert=\([^s]\)/\1/p' | cut -d " " -f 1)
-if [ -f "$tlscert" ]; then
-  perms=$(ls -ld "$tlscert" | awk '{print $1}')
-  if [ "$perms" = "-rw-r--r--" ]; then
-    pass "$check_3_22"
-  else
-    warn "$check_3_22"
-    warn "     * Wrong permissions for $tlscert"
-  fi
-else
-  info "$check_3_22"
-  info "     * No TLS Server certificate found"
-fi
+check_3_22() {
+  id_3_22="3.22"
+  desc_3_22="Ensure that the /etc/default/docker file permissions are set to 644 or more restrictively (Scored)"
+  check_3_22="$id_3_22  - $desc_3_22"
+  starttestjson "$id_3_22" "$desc_3_22"
 
-# 3.23
-check_3_23="3.23 - Verify that Docker server key file ownership is set to root:root"
-tlskey=$(pgrep -lf docker | sed -n 's/.*tlskey=\([^s]\)/\1/p' | cut -d " " -f 1)
-if [ -f "$tlskey" ]; then
-  ls -ld "$tlskey" | awk '{print $3, $4}' | grep "root root" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_23"
+  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
-    warn "$check_3_23"
-    warn "     * Wrong ownership for $tlskey"
+    info "$check_3_22"
+    info "      * File not found"
+    resulttestjson "INFO" "File not found"
+    currentScore=$((currentScore + 0))
   fi
-else
-  info "$check_3_23"
-  info "     * No TLS Key found"
-fi
+}
 
-# 3.24
-check_3_24="3.24 - Verify that Docker server key file permissions are set to 400"
-tlskey=$(pgrep -lf docker | sed -n 's/.*tlskey=\([^s]\)/\1/p' | cut -d " " -f 1)
-if [ -f "$tlskey" ]; then
-  perms=$(ls -ld "$tlskey" | awk '{print $1}')
-  if [ "$perms" = "-r--------" ]; then
-    pass "$check_3_24"
-  else
-    warn "$check_3_24"
-    warn "     * Wrong permissions for $tlskey"
-  fi
-else
-  info "$check_3_24"
-  info "     * No TLS Key found"
-fi
-
-# 3.25
-check_3_25="3.25 - Verify that Docker socket file ownership is set to root:docker"
-file="/var/run/docker.sock"
-if [ -f "$file" ]; then
-  ls -ld "$file" | awk '{print $3, $4}' | grep "root docker" >/dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    pass "$check_3_25"
-  else
-    warn "$check_3_25"
-    warn "     * Wrong ownership for $file"
-  fi
-else
-  info "$check_3_25"
-  info "     * File not found"
-fi
-
-# 3.26
-check_3_26="3.26 - Verify that Docker socket file permissions are set to 660"
-file="/var/run/docker.sock"
-if [ -f "$file" ]; then
-  perms=$(ls -ld "$file" | awk '{print $1}')
-  if [ "$perms" = "srw-rw----" ]; then
-    pass "$check_3_26"
-  else
-    warn "$check_3_26"
-    warn "     * Wrong permissions for $file"
-  fi
-else
-  info "$check_3_26"
-  info "     * File not found"
-fi
+check_3_end() {
+  endsectionjson
+}
diff --git a/tests/4_container_images.sh b/tests/4_container_images.sh
index 6cf9f66..2e3ce69 100644
--- a/tests/4_container_images.sh
+++ b/tests/4_container_images.sh
@@ -1,39 +1,266 @@
 #!/bin/sh
 
-logit "\n"
-info "4 - Container Images and Build Files"
+check_4() {
+  logit "\n"
+  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="4.1  - Create a user for the container"
+check_4_1() {
+  id_4_1="4.1"
+  desc_4_1="Ensure that a user for the container has been created (Scored)"
+  check_4_1="$id_4_1  - $desc_4_1"
+  starttestjson "$id_4_1" "$desc_4_1"
 
-# If container_users is empty, there are no running containers
-if [ -z "$containers" ]; then
-  info "$check_4_1"
-  info "     * No containers running"
-else
-  # We have some containers running, set failure flag to 0. Check for Users.
+  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"
+    resulttestjson "INFO" "No containers running"
+    currentScore=$((currentScore + 0))
+  else
+    # We have some containers running, set failure flag to 0. Check for Users.
+    fail=0
+    # 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")
+
+      if [ "$user" = "User=0" ] || [ "$user" = "User=root" ] || [ "$user" = "User=" ] || [ "$user" = "User=[]" ] || [ "$user" = "User=<no value>" ]; then
+        # If it's the first container, fail the test
+        if [ $fail -eq 0 ]; then
+          warn "$check_4_1"
+          warn "     * Running as root: $c"
+          root_containers="$root_containers $c"
+          fail=1
+        else
+          warn "     * Running as root: $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"
+        resulttestjson "PASS"
+        currentScore=$((currentScore + 1))
+    else
+        resulttestjson "WARN" "running as root" "$root_containers"
+        currentScore=$((currentScore - 1))
+    fi
+  fi
+  # Make the loop separator go back to space
+  set +f; unset IFS
+}
+
+# 4.2
+check_4_2() {
+  id_4_2="4.2"
+  desc_4_2="Ensure that containers use only trusted base images (Not Scored)"
+  check_4_2="$id_4_2  - $desc_4_2"
+  starttestjson "$id_4_2" "$desc_4_2"
+
+  totalChecks=$((totalChecks + 1))
+  note "$check_4_2"
+  resulttestjson "NOTE"
+  currentScore=$((currentScore + 0))
+}
+
+# 4.3
+check_4_3() {
+  id_4_3="4.3"
+  desc_4_3="Ensure that unnecessary packages are not installed in the container (Not Scored)"
+  check_4_3="$id_4_3  - $desc_4_3"
+  starttestjson "$id_4_3" "$desc_4_3"
+
+  totalChecks=$((totalChecks + 1))
+  note "$check_4_3"
+  resulttestjson "NOTE"
+  currentScore=$((currentScore + 0))
+}
+
+# 4.4
+check_4_4() {
+  id_4_4="4.4"
+  desc_4_4="Ensure images are scanned and rebuilt to include security patches (Not Scored)"
+  check_4_4="$id_4_4  - $desc_4_4"
+  starttestjson "$id_4_4" "$desc_4_4"
+
+  totalChecks=$((totalChecks + 1))
+  note "$check_4_4"
+  resulttestjson "NOTE"
+  currentScore=$((currentScore + 0))
+}
+
+# 4.5
+check_4_5() {
+  id_4_5="4.5"
+  desc_4_5="Ensure Content trust for Docker is Enabled (Scored)"
+  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"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  else
+    warn "$check_4_5"
+    resulttestjson "WARN"
+    currentScore=$((currentScore - 1))
+  fi
+}
+
+# 4.6
+check_4_6() {
+  id_4_6="4.6"
+  desc_4_6="Ensure that HEALTHCHECK instructions have been added to container images (Scored)"
+  check_4_6="$id_4_6  - $desc_4_6"
+  starttestjson "$id_4_6" "$desc_4_6"
+
+  totalChecks=$((totalChecks + 1))
   fail=0
-  # Make the loop separator be a new-line in POSIX compliant fashion
-  set -f; IFS=$'
-'
-  for c in $containers; do
-    user=$(docker inspect --format 'User={{.Config.User}}' "$c")
-
-    if [ "$user" = "User=" -o "$user" = "User=[]" -o "$user" = "User=<no value>" ]; then
-      # If it's the first container, fail the test
+  no_health_images=""
+  for img in $images; do
+    if docker inspect --format='{{.Config.Healthcheck}}' "$img" 2>/dev/null | grep -e "<nil>" >/dev/null 2>&1; then
       if [ $fail -eq 0 ]; then
-        warn "$check_4_1"
-        warn "     * Running as root: $c"
         fail=1
+        warn "$check_4_6"
+      fi
+      imgName=$(docker inspect --format='{{.RepoTags}}' "$img" 2>/dev/null)
+      if ! [ "$imgName" = '[]' ]; then
+        warn "     * No Healthcheck found: $imgName"
+        no_health_images="$no_health_images $imgName"
       else
-        warn "     * Running as root: $c"
+        warn "     * No Healthcheck found: $img"
+        no_health_images="$no_health_images $img"
       fi
     fi
   done
-  # We went through all the containers and found none running as root
   if [ $fail -eq 0 ]; then
-      pass "$check_4_1"
+    pass "$check_4_6"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  else
+    resulttestjson "WARN" "Images w/o HEALTHCHECK" "$no_health_images"
+    currentScore=$((currentScore - 1))
   fi
-fi
-# Make the loop separator go back to space
-set +f; unset IFS
+}
+
+# 4.7
+check_4_7() {
+  id_4_7="4.7"
+  desc_4_7="Ensure update instructions are not use alone in the Dockerfile (Not Scored)"
+  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"
+      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"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 0))
+  else
+    resulttestjson "INFO" "Update instructions found" "$update_images"
+    currentScore=$((currentScore + 0))
+  fi
+}
+
+# 4.8
+check_4_8() {
+  id_4_8="4.8"
+  desc_4_8="Ensure setuid and setgid permissions are removed (Not Scored)"
+  check_4_8="$id_4_8  - $desc_4_8"
+  starttestjson "$id_4_8" "$desc_4_8"
+
+  totalChecks=$((totalChecks + 1))
+  note "$check_4_8"
+  resulttestjson "NOTE"
+  currentScore=$((currentScore + 0))
+}
+
+# 4.9
+check_4_9() {
+  id_4_9="4.9"
+  desc_4_9="Ensure that COPY is used instead of ADD in Dockerfiles (Not Scored)"
+  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
+    if docker history --format "{{ .CreatedBy }}" --no-trunc "$img" | \
+      sed '$d' | grep -q 'ADD'; then
+      if [ $fail -eq 0 ]; then
+        fail=1
+        info "$check_4_9"
+      fi
+      imgName=$(docker inspect --format='{{.RepoTags}}' "$img" 2>/dev/null)
+      if ! [ "$imgName" = '[]' ]; then
+        info "     * ADD in image history: $imgName"
+        add_images="$add_images $imgName"
+      fi
+      currentScore=$((currentScore + 0))
+    fi
+  done
+  if [ $fail -eq 0 ]; then
+    pass "$check_4_9"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 0))
+  else
+    resulttestjson "INFO" "Images using ADD" "$add_images"
+  fi
+}
+
+# 4.10
+check_4_10() {
+  id_4_10="4.10"
+  desc_4_10="Ensure secrets are not stored in Dockerfiles (Not Scored)"
+  check_4_10="$id_4_10  - $desc_4_10"
+  starttestjson "$id_4_10" "$desc_4_10"
+
+  totalChecks=$((totalChecks + 1))
+  note "$check_4_10"
+  resulttestjson "NOTE"
+  currentScore=$((currentScore + 0))
+}
+
+# 4.11
+check_4_11() {
+  id_4_11="4.11"
+  desc_4_11="Ensure only verified packages are are installed (Not Scored)"
+  check_4_11="$id_4_11  - $desc_4_11"
+  starttestjson "$id_4_11" "$desc_4_11"
+
+  totalChecks=$((totalChecks + 1))
+  note "$check_4_11"
+  resulttestjson "NOTE"
+  currentScore=$((currentScore + 0))
+}
+
+check_4_end() {
+  endsectionjson
+}
diff --git a/tests/5_container_runtime.sh b/tests/5_container_runtime.sh
index 7133b9e..a42be93 100644
--- a/tests/5_container_runtime.sh
+++ b/tests/5_container_runtime.sh
@@ -1,142 +1,215 @@
 #!/bin/sh
 
-logit "\n"
-info "5  - Container Runtime"
+check_5() {
+  logit "\n"
+  id_5="5"
+  desc_5="Container Runtime"
+  check_5="$id_5 - $desc_5"
+  info "$check_5"
+  startsectionjson "$id_5" "$desc_5"
+}
 
-# If containers is empty, there are no running containers
-if [ -z "$containers" ]; then
-  info "     * No containers running, skipping Section 5"
-else
-  # Make the loop separator be a new-line in POSIX compliant fashion
-  set -f; IFS=$'
-'
-  # 5.1
-  check_5_1="5.1  - Verify AppArmor Profile, if applicable"
+check_running_containers() {
+  # If containers is empty, there are no running containers
+  if [ -z "$containers" ]; then
+    info "  * No containers running, skipping Section 5"
+    running_containers=0
+  else
+    running_containers=1
+    # Make the loop separator be a new-line in POSIX compliant fashion
+    set -f; IFS=$'
+  '
+  fi
+}
+
+# 5.1
+check_5_1() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+
+  id_5_1="5.1"
+  desc_5_1="Ensure that, if applicable, an AppArmor Profile is enabled (Scored)"
+  check_5_1="$id_5_1  - $desc_5_1"
+  starttestjson "$id_5_1" "$desc_5_1"
+
+  totalChecks=$((totalChecks + 1))
 
   fail=0
+  no_apparmor_containers=""
   for c in $containers; do
     policy=$(docker inspect --format 'AppArmorProfile={{ .AppArmorProfile }}' "$c")
 
-    if [ "$policy" = "AppArmorProfile=" -o "$policy" = "AppArmorProfile=[]" -o "$policy" = "AppArmorProfile=<no value>" ]; then
+    if [ "$policy" = "AppArmorProfile=" ] || [ "$policy" = "AppArmorProfile=[]" ] || [ "$policy" = "AppArmorProfile=<no value>" ] || [ "$policy" = "AppArmorProfile=unconfined" ]; then
       # If it's the first container, fail the test
       if [ $fail -eq 0 ]; then
         warn "$check_5_1"
         warn "     * No AppArmorProfile Found: $c"
+	no_apparmor_containers="$no_apparmor_containers $c"
         fail=1
       else
         warn "     * No AppArmorProfile Found: $c"
+	no_apparmor_containers="$no_apparmor_containers $c"
       fi
     fi
   done
   # We went through all the containers and found none without AppArmor
   if [ $fail -eq 0 ]; then
       pass "$check_5_1"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers with no AppArmorProfile" "$no_apparmor_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.2
+check_5_2() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.2
-  check_5_2="5.2  - Verify SELinux security options, if applicable"
+  id_5_2="5.2"
+  desc_5_2="Ensure that, if applicable, SELinux security options are set (Scored)"
+  check_5_2="$id_5_2  - $desc_5_2"
+  starttestjson "$id_5_2" "$desc_5_2"
+
+  totalChecks=$((totalChecks + 1))
 
   fail=0
+  no_securityoptions_containers=""
   for c in $containers; do
     policy=$(docker inspect --format 'SecurityOpt={{ .HostConfig.SecurityOpt }}' "$c")
 
-    if [ "$policy" = "SecurityOpt=" -o "$policy" = "SecurityOpt=[]" -o "$policy" = "SecurityOpt=<no value>" ]; then
+    if [ "$policy" = "SecurityOpt=" ] || [ "$policy" = "SecurityOpt=[]" ] || [ "$policy" = "SecurityOpt=<no value>" ]; then
       # If it's the first container, fail the test
       if [ $fail -eq 0 ]; then
         warn "$check_5_2"
         warn "     * No SecurityOptions Found: $c"
+	no_securityoptions_containers="$no_securityoptions_containers $c"
         fail=1
       else
         warn "     * No SecurityOptions Found: $c"
+	no_securityoptions_containers="$no_securityoptions_containers $c"
       fi
     fi
   done
   # We went through all the containers and found none without SELinux
   if [ $fail -eq 0 ]; then
       pass "$check_5_2"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers with no SecurityOptions" "$no_securityoptions_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.3
+check_5_3() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.3
-  check_5_3="5.3  - Verify that containers are running only a single main process"
+  id_5_3="5.3"
+  desc_5_3="Ensure that Linux kernel capabilities are restricted within containers (Scored)"
+  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
-    exec_check=$(docker exec "$c" ps -el 2>/dev/null)
-    if [ $? -eq 255 ]; then
-      warn "$check_5_3"
-      warn "     * Docker exec fails: $c"
-      fail=1
-    fi
+    container_caps=$(docker inspect --format 'CapAdd={{ .HostConfig.CapAdd}}' "$c")
+    caps=$(echo "$container_caps" | tr "[:lower:]" "[:upper:]" | \
+      sed 's/CAPADD/CapAdd/' | \
+      sed -r "s/AUDIT_WRITE|CHOWN|DAC_OVERRIDE|FOWNER|FSETID|KILL|MKNOD|NET_BIND_SERVICE|NET_RAW|SETFCAP|SETGID|SETPCAP|SETUID|SYS_CHROOT|\s//g")
 
-    processes=$(docker exec "$c" ps -el 2>/dev/null | wc -l | awk '{print $1}')
-    if [ "$processes" -gt 5 ]; then
+    if [ "$caps" != 'CapAdd=' ] && [ "$caps" != 'CapAdd=[]' ] && [ "$caps" != 'CapAdd=<no value>' ] && [ "$caps" != 'CapAdd=<nil>' ]; then
       # If it's the first container, fail the test
       if [ $fail -eq 0 ]; then
         warn "$check_5_3"
-        warn "     * Too many proccesses running: $c"
-        fail=1
-      else
-        warn "     * Too many proccesses running: $c"
-      fi
-    fi
-  done
-  # We went through all the containers and found none with toom any processes
-  if [ $fail -eq 0 ]; then
-      pass "$check_5_3"
-  fi
-
-  # 5.4
-  check_5_4="5.4  - Restrict Linux Kernel Capabilities within containers"
-
-  fail=0
-  for c in $containers; do
-    caps=$(docker inspect --format 'CapAdd={{ .HostConfig.CapAdd}}' "$c")
-
-    if [ "$caps" != "CapAdd=" -a "$caps" != "CapAdd=[]" -a "$caps" != "CapAdd=<no value>" ]; then
-      # If it's the first container, fail the test
-      if [ $fail -eq 0 ]; then
-        warn "$check_5_4"
         warn "     * Capabilities added: $caps to $c"
+	caps_containers="$caps_containers $c"
         fail=1
       else
         warn "     * Capabilities added: $caps to $c"
+	caps_containers="$caps_containers $c"
       fi
     fi
   done
   # We went through all the containers and found none with extra capabilities
   if [ $fail -eq 0 ]; then
-      pass "$check_5_4"
+      pass "$check_5_3"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Capabilities added for containers" "$caps_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.4
+check_5_4() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.5
-  check_5_5="5.5  - Do not use privileged containers"
+  id_5_4="5.4"
+  desc_5_4="Ensure that privileged containers are not used (Scored)"
+  check_5_4="$id_5_4  - $desc_5_4"
+  starttestjson "$id_5_4" "$desc_5_4"
+
+  totalChecks=$((totalChecks + 1))
 
   fail=0
+  privileged_containers=""
   for c in $containers; do
     privileged=$(docker inspect --format '{{ .HostConfig.Privileged }}' "$c")
 
     if [ "$privileged" = "true" ]; then
       # If it's the first container, fail the test
       if [ $fail -eq 0 ]; then
-        warn "$check_5_5"
+        warn "$check_5_4"
         warn "     * Container running in Privileged mode: $c"
+	privileged_containers="$privileged_containers $c"
         fail=1
       else
         warn "     * Container running in Privileged mode: $c"
+	privileged_containers="$privileged_containers $c"
       fi
     fi
   done
   # We went through all the containers and found no privileged containers
   if [ $fail -eq 0 ]; then
-      pass "$check_5_5"
+      pass "$check_5_4"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers running in privileged mode" "$privileged_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.5
+check_5_5() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.6
-  check_5_6="5.6  - Do not mount sensitive host system directories on containers"
+  id_5_5="5.5"
+  desc_5_5="Ensure sensitive host system directories are not mounted on containers (Scored)"
+  check_5_5="$id_5_5  - $desc_5_5"
+  starttestjson "$id_5_5" "$desc_5_5"
+
+  totalChecks=$((totalChecks + 1))
 
   # List of sensitive directories to test for. Script uses new-lines as a separator.
   # Note the lack of identation. It needs it for the substring comparison.
-  sensitive_dirs='/boot
+  sensitive_dirs='/
+/boot
 /dev
 /etc
 /lib
@@ -144,311 +217,1060 @@ else
 /sys
 /usr'
   fail=0
+  sensitive_mount_containers=""
   for c in $containers; do
-    volumes=$(docker inspect --format '{{ .VolumesRW }}' "$c")
+    if docker inspect --format '{{ .VolumesRW }}' "$c" 2>/dev/null 1>&2; then
+      volumes=$(docker inspect --format '{{ .VolumesRW }}' "$c")
+    else
+      volumes=$(docker inspect --format '{{ .Mounts }}' "$c")
+    fi
     # Go over each directory in sensitive dir and see if they exist in the volumes
     for v in $sensitive_dirs; do
       sensitive=0
-      contains "$volumes" "$v:" && sensitive=1
+      if echo "$volumes" | grep -e "{.*\s$v\s.*true\s.*}" 2>/tmp/null 1>&2; then
+        sensitive=1
+      fi
       if [ $sensitive -eq 1 ]; then
         # If it's the first container, fail the test
         if [ $fail -eq 0 ]; then
-          warn "$check_5_6"
+          warn "$check_5_5"
           warn "     * Sensitive directory $v mounted in: $c"
+	  sensitive_mount_containers="$sensitive_mount_containers $c:$v"
           fail=1
         else
           warn "     * Sensitive directory $v mounted in: $c"
+	  sensitive_mount_containers="$sensitive_mount_containers $c:$v"
         fi
       fi
     done
   done
   # We went through all the containers and found none with sensitive mounts
   if [ $fail -eq 0 ]; then
-      pass "$check_5_6"
+      pass "$check_5_5"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers with sensitive directories mounted" "$sensitive_mount_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.6
+check_5_6() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.7
-  check_5_7="5.7  - Do not run ssh within containers"
+  id_5_6="5.6"
+  desc_5_6="Ensure sshd is not run within containers (Scored)"
+  check_5_6="$id_5_6  - $desc_5_6"
+  starttestjson "$id_5_6" "$desc_5_6"
+
+  totalChecks=$((totalChecks + 1))
 
   fail=0
+  ssh_exec_containers=""
+  printcheck=0
   for c in $containers; do
+
+    processes=$(docker exec "$c" ps -el 2>/dev/null | grep -c sshd | awk '{print $1}')
+    if [ "$processes" -ge 1 ]; then
+      # If it's the first container, fail the test
+      if [ $fail -eq 0 ]; then
+        warn "$check_5_6"
+        warn "     * Container running sshd: $c"
+	ssh_exec_containers="$ssh_exec_containers $c"
+        fail=1
+        printcheck=1
+      else
+        warn "     * Container running sshd: $c"
+	ssh_exec_containers="$ssh_exec_containers $c"
+      fi
+    fi
+
     exec_check=$(docker exec "$c" ps -el 2>/dev/null)
     if [ $? -eq 255 ]; then
-      warn "$check_5_7"
+        if [ $printcheck -eq 0 ]; then
+          warn "$check_5_6"
+          printcheck=1
+        fi
       warn "     * Docker exec fails: $c"
+      ssh_exec_containers="$ssh_exec_containers $c"
       fail=1
     fi
 
-    processes=$(docker exec "$c" ps -el 2>/dev/null | grep -c sshd | awk '{print $1}')
-    if [ $processes -gt 1 ]; then
-      # If it's the first container, fail the test
-      if [ $fail -eq 0 ]; then
-        warn "$check_5_7"
-        warn "     * Container running sshd: $c"
-        fail=1
-      else
-        warn "     * Container running sshd: $c"
-      fi
-    fi
   done
   # We went through all the containers and found none with sshd
   if [ $fail -eq 0 ]; then
-      pass "$check_5_7"
+      pass "$check_5_6"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers with sshd/docker exec failures" "$ssh_exec_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.7
+check_5_7() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.8
-  check_5_8="5.8  - Do not map privileged ports within containers"
+  id_5_7="5.7"
+  desc_5_7="Ensure privileged ports are not mapped within containers (Scored)"
+  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
-    ports=$(docker port "$c" | awk '{print $1}' | cut -d '/' -f1)
+    # Port format is private port -> ip: public port
+    ports=$(docker port "$c" | awk '{print $0}' | cut -d ':' -f2)
 
     # iterate through port range (line delimited)
     for port in $ports; do
-    if [ ! -z "$port" ] && [ "0$port" -lt 1025 ]; then
+    if [ -n "$port" ] && [ "$port" -lt 1024 ]; then
         # If it's the first container, fail the test
         if [ $fail -eq 0 ]; then
-          warn "$check_5_8"
+          warn "$check_5_7"
           warn "     * Privileged Port in use: $port in $c"
+	  privileged_port_containers="$privileged_port_containers $c:$port"
           fail=1
         else
           warn "     * Privileged Port in use: $port in $c"
+	  privileged_port_containers="$privileged_port_containers $c:$port"
         fi
       fi
     done
   done
   # We went through all the containers and found no privileged ports
   if [ $fail -eq 0 ]; then
-      pass "$check_5_8"
+      pass "$check_5_7"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers using privileged ports" "$privileged_port_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.8
+check_5_8() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.10
-  check_5_10="5.10 - Do not use host network mode on container"
+  id_5_8="5.8"
+  desc_5_8="Ensure that only needed ports are open on the container (Not Scored)"
+  check_5_8="$id_5_8  - $desc_5_8"
+  starttestjson "$id_5_8" "$desc_5_8"
+
+  totalChecks=$((totalChecks + 1))
+  note "$check_5_8"
+  resulttestjson "NOTE"
+  currentScore=$((currentScore + 0))
+}
+
+# 5.9
+check_5_9() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+
+  id_5_9="5.9"
+  desc_5_9="Ensure that the host's network namespace is not shared (Scored)"
+  check_5_9="$id_5_9  - $desc_5_9"
+  starttestjson "$id_5_9" "$desc_5_9"
+
+  totalChecks=$((totalChecks + 1))
 
   fail=0
+  net_host_containers=""
   for c in $containers; do
     mode=$(docker inspect --format 'NetworkMode={{ .HostConfig.NetworkMode }}' "$c")
 
     if [ "$mode" = "NetworkMode=host" ]; then
       # If it's the first container, fail the test
       if [ $fail -eq 0 ]; then
-        warn "$check_5_10"
+        warn "$check_5_9"
         warn "     * Container running with networking mode 'host': $c"
+	net_host_containers="$net_host_containers $c"
         fail=1
       else
         warn "     * Container running with networking mode 'host': $c"
+	net_host_containers="$net_host_containers $c"
       fi
     fi
   done
   # We went through all the containers and found no Network Mode host
   if [ $fail -eq 0 ]; then
-      pass "$check_5_10"
+      pass "$check_5_9"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 0))
+  else
+      resulttestjson "WARN" "Containers running with networking mode 'host'" "$net_host_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.10
+check_5_10() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.11
-  check_5_11="5.11 - Limit memory usage for container"
+  id_5_10="5.10"
+  desc_5_10="Ensure that the memory usage for containers is limited (Scored)"
+  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
-    memory=$(docker inspect --format '{{ .Config.Memory }}' "$c")
+    if docker inspect --format '{{ .Config.Memory }}' "$c" 2> /dev/null 1>&2; then
+      memory=$(docker inspect --format '{{ .Config.Memory }}' "$c")
+    else
+      memory=$(docker inspect --format '{{ .HostConfig.Memory }}' "$c")
+    fi
 
     if [ "$memory" = "0" ]; then
       # If it's the first container, fail the test
       if [ $fail -eq 0 ]; then
-        warn "$check_5_11"
+        warn "$check_5_10"
         warn "     * Container running without memory restrictions: $c"
+	mem_unlimited_containers="$mem_unlimited_containers $c"
         fail=1
       else
         warn "     * Container running without memory restrictions: $c"
+	mem_unlimited_containers="$mem_unlimited_containers $c"
       fi
     fi
   done
   # We went through all the containers and found no lack of Memory restrictions
   if [ $fail -eq 0 ]; then
-      pass "$check_5_11"
+      pass "$check_5_10"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Container running without memory restrictions" "$mem_unlimited_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.11
+check_5_11() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.12
-  check_5_12="5.12 - Set container CPU priority appropriately"
+  id_5_11="5.11"
+  desc_5_11="Ensure that CPU priority is set appropriately on containers (Scored)"
+  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
-    shares=$(docker inspect --format '{{ .Config.CpuShares }}' "$c")
+    if docker inspect --format '{{ .Config.CpuShares }}' "$c" 2> /dev/null 1>&2; then
+      shares=$(docker inspect --format '{{ .Config.CpuShares }}' "$c")
+    else
+      shares=$(docker inspect --format '{{ .HostConfig.CpuShares }}' "$c")
+    fi
 
     if [ "$shares" = "0" ]; then
       # If it's the first container, fail the test
       if [ $fail -eq 0 ]; then
-        warn "$check_5_12"
+        warn "$check_5_11"
         warn "     * Container running without CPU restrictions: $c"
+        cpu_unlimited_containers="$cpu_unlimited_containers $c"
         fail=1
       else
         warn "     * Container running without CPU restrictions: $c"
+        cpu_unlimited_containers="$cpu_unlimited_containers $c"
       fi
     fi
   done
   # We went through all the containers and found no lack of CPUShare restrictions
   if [ $fail -eq 0 ]; then
-      pass "$check_5_12"
+      pass "$check_5_11"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers running without CPU restrictions" "$cpu_unlimited_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.12
+check_5_12() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.13
-  check_5_13="5.13 - Mount container's root filesystem as read only"
+  id_5_12="5.12"
+  desc_5_12="Ensure that the container's root filesystem is mounted as read only (Scored)"
+  check_5_12="$id_5_12  - $desc_5_12"
+  starttestjson "$id_5_12" "$desc_5_12"
+
+  totalChecks=$((totalChecks + 1))
 
   fail=0
+  fsroot_mount_containers=""
   for c in $containers; do
    read_status=$(docker inspect --format '{{ .HostConfig.ReadonlyRootfs }}' "$c")
 
     if [ "$read_status" = "false" ]; then
       # If it's the first container, fail the test
       if [ $fail -eq 0 ]; then
-        warn "$check_5_13"
+        warn "$check_5_12"
         warn "     * Container running with root FS mounted R/W: $c"
+	fsroot_mount_containers="$fsroot_mount_containers $c"
         fail=1
       else
         warn "     * Container running with root FS mounted R/W: $c"
+	fsroot_mount_containers="$fsroot_mount_containers $c"
       fi
     fi
   done
   # We went through all the containers and found no R/W FS mounts
   if [ $fail -eq 0 ]; then
-      pass "$check_5_13"
+      pass "$check_5_12"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers running with root FS mounted R/W" "$fsroot_mount_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.13
+check_5_13() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.14
-  check_5_14="5.14 - Bind incoming container traffic to a specific host interface"
+  id_5_13="5.13"
+  desc_5_13="Ensure that incoming container traffic is bound to a specific host interface (Scored)"
+  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
-    ip=$(docker port "$c" | awk '{print $3}' | cut -d ':' -f1)
-    if [ "$ip" = "0.0.0.0" ]; then
-      # If it's the first container, fail the test
-      if [ $fail -eq 0 ]; then
-        warn "$check_5_14"
-        warn "     * Port being bound to wildcard IP: $ip in $c"
-        fail=1
-      else
-        warn "     * Port being bound to wildcard IP: $ip in $c"
+    for ip in $(docker port "$c" | awk '{print $3}' | cut -d ':' -f1); do
+      if [ "$ip" = "0.0.0.0" ]; then
+        # If it's the first container, fail the test
+        if [ $fail -eq 0 ]; then
+          warn "$check_5_13"
+          warn "     * Port being bound to wildcard IP: $ip in $c"
+          incoming_unbound_containers="$incoming_unbound_containers $c:$ip"
+          fail=1
+        else
+          warn "     * Port being bound to wildcard IP: $ip in $c"
+          incoming_unbound_containers="$incoming_unbound_containers $c:$ip"
+        fi
       fi
-    fi
+    done
   done
   # We went through all the containers and found no ports bound to 0.0.0.0
   if [ $fail -eq 0 ]; then
-      pass "$check_5_14"
+      pass "$check_5_13"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers with port bound to wildcard IP" "$incoming_unbound_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.14
+check_5_14() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.15
-  check_5_15="5.15 - Do not set the 'on-failure' container restart policy to always"
+  id_5_14="5.14"
+  desc_5_14="Ensure that the 'on-failure' container restart policy is set to '5' (Scored)"
+  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 'RestartPolicyName={{ .HostConfig.RestartPolicy.Name }}' "$c")
+    policy=$(docker inspect --format MaximumRetryCount='{{ .HostConfig.RestartPolicy.MaximumRetryCount }}' "$c")
 
-    if [ "$policy" = "RestartPolicyName=always" ]; then
+    if [ "$policy" != "MaximumRetryCount=5" ]; then
       # If it's the first container, fail the test
       if [ $fail -eq 0 ]; then
-        warn "$check_5_15"
-        warn "     * Restart Policy set to always: $c"
+        warn "$check_5_14"
+        warn "     * MaximumRetryCount is not set to 5: $c"
+	maxretry_unset_containers="$maxretry_unset_containers $c"
         fail=1
       else
-        warn "     * Restart Policy set to always: $c"
+        warn "     * MaximumRetryCount is not set to 5: $c"
+	maxretry_unset_containers="$maxretry_unset_containers $c"
       fi
     fi
   done
-  # We went through all the containers and found none with restart policy always
+  # We went through all the containers and they all had MaximumRetryCount=5
   if [ $fail -eq 0 ]; then
-      pass "$check_5_15"
+      pass "$check_5_14"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers with MaximumRetryCount not set to 5" "$maxretry_unset_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.15
+check_5_15() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.16
-  check_5_16="5.16 - Do not share the host's process namespace"
+  id_5_15="5.15"
+  desc_5_15="Ensure that the host's process namespace is not shared (Scored)"
+  check_5_15="$id_5_15  - $desc_5_15"
+  starttestjson "$id_5_15" "$desc_5_15"
+
+  totalChecks=$((totalChecks + 1))
 
   fail=0
+  pidns_shared_containers=""
   for c in $containers; do
     mode=$(docker inspect --format 'PidMode={{.HostConfig.PidMode }}' "$c")
 
     if [ "$mode" = "PidMode=host" ]; then
       # If it's the first container, fail the test
       if [ $fail -eq 0 ]; then
-        warn "$check_5_16"
+        warn "$check_5_15"
         warn "     * Host PID namespace being shared with: $c"
+        pidns_shared_containers="$pidns_shared_containers $c"
         fail=1
       else
         warn "     * Host PID namespace being shared with: $c"
+        pidns_shared_containers="$pidns_shared_containers $c"
       fi
     fi
   done
   # We went through all the containers and found none with PidMode as host
   if [ $fail -eq 0 ]; then
-      pass "$check_5_16"
+      pass "$check_5_15"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers sharing host PID namespace" "$pidns_shared_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.16
+check_5_16() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.17
-  check_5_17="5.17 - Do not share the host's IPC namespace"
+  id_5_16="5.16"
+  desc_5_16="Ensure that the host's IPC namespace is not shared (Scored)"
+  check_5_16="$id_5_16  - $desc_5_16"
+  starttestjson "$id_5_16" "$desc_5_16"
+
+  totalChecks=$((totalChecks + 1))
 
   fail=0
+  ipcns_shared_containers=""
   for c in $containers; do
     mode=$(docker inspect --format 'IpcMode={{.HostConfig.IpcMode }}' "$c")
 
     if [ "$mode" = "IpcMode=host" ]; then
       # If it's the first container, fail the test
       if [ $fail -eq 0 ]; then
-        warn "$check_5_17"
+        warn "$check_5_16"
         warn "     * Host IPC namespace being shared with: $c"
+        ipcns_shared_containers="$ipcns_shared_containers $c"
         fail=1
       else
         warn "     * Host IPC namespace being shared with: $c"
+        ipcns_shared_containers="$ipcns_shared_containers $c"
       fi
     fi
   done
   # We went through all the containers and found none with IPCMode as host
   if [ $fail -eq 0 ]; then
-      pass "$check_5_17"
+      pass "$check_5_16"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers sharing host IPC namespace" "$ipcns_shared_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.17
+check_5_17() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.18
-  check_5_18="5.18 - Do not directly expose host devices to containers"
+  id_5_17="5.17"
+  desc_5_17="Ensure that host devices are not directly exposed to containers (Not Scored)"
+  check_5_17="$id_5_17  - $desc_5_17"
+  starttestjson "$id_5_17" "$desc_5_17"
+
+  totalChecks=$((totalChecks + 1))
 
   fail=0
+  hostdev_exposed_containers=""
   for c in $containers; do
     devices=$(docker inspect --format 'Devices={{ .HostConfig.Devices }}' "$c")
 
-    if [ "$devices" != "Devices=" -a "$devices" != "Devices=[]" -a "$devices" != "Devices=<no value>" ]; then
+    if [ "$devices" != "Devices=" ] && [ "$devices" != "Devices=[]" ] && [ "$devices" != "Devices=<no value>" ]; then
       # If it's the first container, fail the test
       if [ $fail -eq 0 ]; then
-        info "$check_5_18"
+        info "$check_5_17"
         info "     * Container has devices exposed directly: $c"
+        hostdev_exposed_containers="$hostdev_exposed_containers $c"
         fail=1
       else
         info "     * Container has devices exposed directly: $c"
+        hostdev_exposed_containers="$hostdev_exposed_containers $c"
       fi
     fi
   done
   # We went through all the containers and found none with devices
   if [ $fail -eq 0 ]; then
-      pass "$check_5_18"
+      pass "$check_5_17"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "INFO" "Containers with host devices exposed directly" "$hostdev_exposed_containers"
+      currentScore=$((currentScore + 0))
+  fi
+}
+
+# 5.18
+check_5_18() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
   fi
 
-  # 5.19
-  check_5_19="5.19 - Override default ulimit at runtime only if needed"
+  id_5_18="5.18"
+  desc_5_18="Ensure that the default ulimit is overwritten at runtime if needed (Not Scored)"
+  check_5_18="$id_5_18  - $desc_5_18"
+  starttestjson "$id_5_18" "$desc_5_18"
+
+  totalChecks=$((totalChecks + 1))
 
-  # List all the running containers, ouput their ID and host devices
   fail=0
+  no_ulimit_containers=""
   for c in $containers; do
     ulimits=$(docker inspect --format 'Ulimits={{ .HostConfig.Ulimits }}' "$c")
 
-    if [ "$ulimits" = "Ulimits=" -o "$ulimits" = "Ulimits=[]" -o "$ulimits" = "Ulimits=<no value>" ]; then
+    if [ "$ulimits" = "Ulimits=" ] || [ "$ulimits" = "Ulimits=[]" ] || [ "$ulimits" = "Ulimits=<no value>" ]; then
       # If it's the first container, fail the test
       if [ $fail -eq 0 ]; then
-        info "$check_5_19"
+        info "$check_5_18"
         info "     * Container no default ulimit override: $c"
+        no_ulimit_containers="$no_ulimit_containers $c"
         fail=1
       else
         info "     * Container no default ulimit override: $c"
+        no_ulimit_containers="$no_ulimit_containers $c"
       fi
     fi
   done
   # We went through all the containers and found none without Ulimits
   if [ $fail -eq 0 ]; then
-      pass "$check_5_19"
+      pass "$check_5_18"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "INFO" "Containers with no default ulimit override" "$no_ulimit_containers"
+      currentScore=$((currentScore + 0))
   fi
-fi
+}
+
+# 5.19
+check_5_19() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+
+  id_5_19="5.19"
+  desc_5_19="Ensure mount propagation mode is not set to shared (Scored)"
+  check_5_19="$id_5_19  - $desc_5_19"
+  starttestjson "$id_5_19" "$desc_5_19"
+
+  totalChecks=$((totalChecks + 1))
+
+  fail=0
+  mountprop_shared_containers=""
+  for c in $containers; do
+    if docker inspect --format 'Propagation={{range $mnt := .Mounts}} {{json $mnt.Propagation}} {{end}}' "$c" | \
+     grep shared 2>/dev/null 1>&2; then
+      # If it's the first container, fail the test
+      if [ $fail -eq 0 ]; then
+        warn "$check_5_19"
+        warn "     * Mount propagation mode is shared: $c"
+        mountprop_shared_containers="$mountprop_shared_containers $c"
+        fail=1
+      else
+        warn "     * Mount propagation mode is shared: $c"
+        mountprop_shared_containers="$mountprop_shared_containers $c"
+      fi
+    fi
+  done
+  # We went through all the containers and found none with shared propagation mode
+  if [ $fail -eq 0 ]; then
+      pass "$check_5_19"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+    resulttestjson "WARN" "Containers with shared mount propagation" "$mountprop_shared_containers"
+    currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.20
+check_5_20() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+
+  id_5_20="5.20"
+  desc_5_20="Ensure that the host's UTS namespace is not shared (Scored)"
+  check_5_20="$id_5_20  - $desc_5_20"
+  starttestjson "$id_5_20" "$desc_5_20"
+
+  totalChecks=$((totalChecks + 1))
+
+  fail=0
+  utcns_shared_containers=""
+  for c in $containers; do
+    mode=$(docker inspect --format 'UTSMode={{.HostConfig.UTSMode }}' "$c")
+
+    if [ "$mode" = "UTSMode=host" ]; then
+      # If it's the first container, fail the test
+      if [ $fail -eq 0 ]; then
+        warn "$check_5_20"
+        warn "     * Host UTS namespace being shared with: $c"
+        utcns_shared_containers="$utcns_shared_containers $c"
+        fail=1
+      else
+        warn "     * Host UTS namespace being shared with: $c"
+        utcns_shared_containers="$utcns_shared_containers $c"
+      fi
+    fi
+  done
+  # We went through all the containers and found none with UTSMode as host
+  if [ $fail -eq 0 ]; then
+      pass "$check_5_20"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers sharing host UTS namespace" "$utcns_shared_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.21
+check_5_21() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+
+  id_5_21="5.21"
+  desc_5_21="Ensurethe default seccomp profile is not Disabled (Scored)"
+  check_5_21="$id_5_21  - $desc_5_21"
+  starttestjson "$id_5_21" "$desc_5_21"
+
+  totalChecks=$((totalChecks + 1))
+
+  fail=0
+  seccomp_disabled_containers=""
+  for c in $containers; do
+    if docker inspect --format 'SecurityOpt={{.HostConfig.SecurityOpt }}' "$c" | \
+      grep -E 'seccomp:unconfined|seccomp=unconfined' 2>/dev/null 1>&2; then
+      # If it's the first container, fail the test
+      if [ $fail -eq 0 ]; then
+        warn "$check_5_21"
+        warn "     * Default seccomp profile disabled: $c"
+        seccomp_disabled_containers="$seccomp_disabled_containers $c"
+        fail=1
+      else
+        warn "     * Default seccomp profile disabled: $c"
+        seccomp_disabled_containers="$seccomp_disabled_containers $c"
+      fi
+    fi
+  done
+  # We went through all the containers and found none with default secomp profile disabled
+  if [ $fail -eq 0 ]; then
+      pass "$check_5_21"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers with default seccomp profile disabled" "$seccomp_disabled_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.22
+check_5_22() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+
+  id_5_22="5.22"
+  desc_5_22="Ensure that docker exec commands are not used with the privileged option (Scored)"
+  check_5_22="$id_5_22  - $desc_5_22"
+  starttestjson "$id_5_22" "$desc_5_22"
+
+  totalChecks=$((totalChecks + 1))
+  note "$check_5_22"
+  resulttestjson "NOTE"
+  currentScore=$((currentScore + 0))
+}
+
+# 5.23
+check_5_23() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+
+  id_5_23="5.23"
+  desc_5_23="Ensure that docker exec commands are not used with the user=root option (Not Scored)"
+  check_5_23="$id_5_23  - $desc_5_23"
+  starttestjson "$id_5_23" "$desc_5_23"
+
+  totalChecks=$((totalChecks + 1))
+  note "$check_5_23"
+  resulttestjson "NOTE"
+  currentScore=$((currentScore + 0))
+}
+
+# 5.24
+check_5_24() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+
+  id_5_24="5.24"
+  desc_5_24="Ensure that cgroup usage is confirmed (Scored)"
+  check_5_24="$id_5_24  - $desc_5_24"
+  starttestjson "$id_5_24" "$desc_5_24"
+
+  totalChecks=$((totalChecks + 1))
+
+  fail=0
+  unexpected_cgroup_containers=""
+  for c in $containers; do
+    mode=$(docker inspect --format 'CgroupParent={{.HostConfig.CgroupParent }}x' "$c")
+
+    if [ "$mode" != "CgroupParent=x" ]; then
+      # If it's the first container, fail the test
+      if [ $fail -eq 0 ]; then
+        warn "$check_5_24"
+        warn "     * Confirm cgroup usage: $c"
+        unexpected_cgroup_containers="$unexpected_cgroup_containers $c"
+        fail=1
+      else
+        warn "     * Confirm cgroup usage: $c"
+        unexpected_cgroup_containers="$unexpected_cgroup_containers $c"
+      fi
+    fi
+  done
+  # We went through all the containers and found none with UTSMode as host
+  if [ $fail -eq 0 ]; then
+      pass "$check_5_24"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers using unexpected cgroup" "$unexpected_cgroup_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.25
+check_5_25() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+  id_5_25="5.25"
+  desc_5_25="Ensure that the container is restricted from acquiring additional privileges (Scored)"
+  check_5_25="$id_5_25  - $desc_5_25"
+  starttestjson "$id_5_25" "$desc_5_25"
+
+  totalChecks=$((totalChecks + 1))
+
+  fail=0
+  addprivs_containers=""
+  for c in $containers; do
+    if ! docker inspect --format 'SecurityOpt={{.HostConfig.SecurityOpt }}' "$c" | grep 'no-new-privileges' 2>/dev/null 1>&2; then
+      # If it's the first container, fail the test
+      if [ $fail -eq 0 ]; then
+        warn "$check_5_25"
+        warn "     * Privileges not restricted: $c"
+        addprivs_containers="$addprivs_containers $c"
+        fail=1
+      else
+        warn "     * Privileges not restricted: $c"
+        addprivs_containers="$addprivs_containers $c"
+      fi
+    fi
+  done
+  # We went through all the containers and found none with capability to acquire additional privileges
+  if [ $fail -eq 0 ]; then
+      pass "$check_5_25"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers without restricted privileges" "$addprivs_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.26
+check_5_26() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+
+  id_5_26="5.26"
+  desc_5_26="Ensure that container health is checked at runtime (Scored)"
+  check_5_26="$id_5_26  - $desc_5_26"
+  starttestjson "$id_5_26" "$desc_5_26"
+
+  totalChecks=$((totalChecks + 1))
+
+  fail=0
+  nohealthcheck_containers=""
+  for c in $containers; do
+    if ! docker inspect --format '{{ .Id }}: Health={{ .State.Health.Status }}' "$c" 2>/dev/null 1>&2; then
+      if [ $fail -eq 0 ]; then
+        warn "$check_5_26"
+        warn "     * Health check not set: $c"
+        nohealthcheck_containers="$nohealthcheck_containers $c"
+        fail=1
+      else
+        warn "     * Health check not set: $c"
+        nohealthcheck_containers="$nohealthcheck_containers $c"
+      fi
+    fi
+  done
+  if [ $fail -eq 0 ]; then
+      pass "$check_5_26"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers without health check" "$nohealthcheck_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.27
+check_5_27() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+
+  id_5_27="5.27"
+  desc_5_27="Ensure that Docker commands always make use of the latest version of their image (Not Scored)"
+  check_5_27="$id_5_27  - $desc_5_27"
+  starttestjson "$id_5_27" "$desc_5_27"
+
+  totalChecks=$((totalChecks + 1))
+  info "$check_5_27"
+  resulttestjson "INFO"
+  currentScore=$((currentScore + 0))
+}
+
+# 5.28
+check_5_28() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+
+  id_5_28="5.28"
+  desc_5_28="Ensure that the PIDs cgroup limit is used (Scored)"
+  check_5_28="$id_5_28  - $desc_5_28"
+  starttestjson "$id_5_28" "$desc_5_28"
+
+  totalChecks=$((totalChecks + 1))
+
+  fail=0
+  nopids_limit_containers=""
+  for c in $containers; do
+    pidslimit="$(docker inspect --format '{{.HostConfig.PidsLimit }}' "$c")"
+
+    if [ "$pidslimit" = "0" ] || [  "$pidslimit" = "<nil>" ] || [  "$pidslimit" = "-1" ]; then
+      # If it's the first container, fail the test
+      if [ $fail -eq 0 ]; then
+        warn "$check_5_28"
+        warn "     * PIDs limit not set: $c"
+        nopids_limit_containers="$nopids_limit_containers $c"
+        fail=1
+      else
+        warn "     * PIDs limit not set: $c"
+        nopids_limit_containers="$nopids_limit_containers $c"
+      fi
+    fi
+  done
+  # We went through all the containers and found all with PIDs limit
+  if [ $fail -eq 0 ]; then
+      pass "$check_5_28"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers without PIDs cgroup limit" "$nopids_limit_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.29
+check_5_29() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+
+  id_5_29="5.29"
+  desc_5_29="Ensure that Docker's default bridge "docker0" is not used (Not Scored)"
+  check_5_29="$id_5_29  - $desc_5_29"
+  starttestjson "$id_5_29" "$desc_5_29"
+
+  totalChecks=$((totalChecks + 1))
+
+  fail=0
+  docker_network_containers=""
+  networks=$(docker network ls -q 2>/dev/null)
+  for net in $networks; do
+    if docker network inspect --format '{{ .Options }}' "$net" 2>/dev/null | grep "com.docker.network.bridge.name:docker0" >/dev/null 2>&1; then
+      docker0Containers=$(docker network inspect --format='{{ range $k, $v := .Containers }} {{ $k }} {{ end }}' "$net" | \
+        sed -e 's/^ //' -e 's/  /\n/g' 2>/dev/null)
+
+        if [ -n "$docker0Containers" ]; then
+          if [ $fail -eq 0 ]; then
+            info "$check_5_29"
+            fail=1
+          fi
+          for c in $docker0Containers; do
+            if [ -z "$exclude" ]; then
+              cName=$(docker inspect --format '{{.Name}}' "$c" 2>/dev/null | sed 's/\///g')
+            else
+              pattern=$(echo "$exclude" | sed 's/,/|/g')
+              cName=$(docker inspect --format '{{.Name}}' "$c" 2>/dev/null | sed 's/\///g' | grep -Ev "$pattern" )
+            fi
+            if [ -n "$cName" ]; then
+              info "     * Container in docker0 network: $cName"
+              docker_network_containers="$docker_network_containers $c:$cName"
+            fi
+          done
+        fi
+      currentScore=$((currentScore + 0))
+    fi
+  done
+  # We went through all the containers and found none in docker0 network
+  if [ $fail -eq 0 ]; then
+      pass "$check_5_29"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "INFO" "Containers using docker0 network" "$docker_network_containers"
+      currentScore=$((currentScore + 0))
+  fi
+}
+
+# 5.30
+check_5_30() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+
+  id_5_30="5.30"
+  desc_5_30="Ensure that the host's user namespaces are not shared (Scored)"
+  check_5_30="$id_5_30  - $desc_5_30"
+  starttestjson "$id_5_30" "$desc_5_30"
+
+  totalChecks=$((totalChecks + 1))
+
+  fail=0
+  hostns_shared_containers=""
+  for c in $containers; do
+    if docker inspect --format '{{ .HostConfig.UsernsMode }}' "$c" 2>/dev/null | grep -i 'host' >/dev/null 2>&1; then
+      # If it's the first container, fail the test
+      if [ $fail -eq 0 ]; then
+        warn "$check_5_30"
+        warn "     * Namespace shared: $c"
+        hostns_shared_containers="$hostns_shared_containers $c"
+        fail=1
+      else
+        warn "     * Namespace shared: $c"
+        hostns_shared_containers="$hostns_shared_containers $c"
+      fi
+    fi
+  done
+  # We went through all the containers and found none with host's user namespace shared
+  if [ $fail -eq 0 ]; then
+      pass "$check_5_30"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers sharing host user namespace" "$hostns_shared_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 5.31
+check_5_31() {
+  if [ "$running_containers" -ne 1 ]; then
+    return
+  fi
+
+  id_5_31="5.31"
+  desc_5_31="Ensure that the Docker socket is not mounted inside any containers (Scored)"
+  check_5_31="$id_5_31  - $desc_5_31"
+  starttestjson "$id_5_31" "$desc_5_31"
+
+  totalChecks=$((totalChecks + 1))
+
+  fail=0
+  docker_sock_containers=""
+  for c in $containers; do
+    if docker inspect --format '{{ .Mounts }}' "$c" 2>/dev/null | grep 'docker.sock' >/dev/null 2>&1; then
+      # If it's the first container, fail the test
+      if [ $fail -eq 0 ]; then
+        warn "$check_5_31"
+        warn "     * Docker socket shared: $c"
+        docker_sock_containers="$docker_sock_containers $c"
+        fail=1
+      else
+        warn "     * Docker socket shared: $c"
+        docker_sock_containers="$docker_sock_containers $c"
+      fi
+    fi
+  done
+  # We went through all the containers and found none with docker.sock shared
+  if [ $fail -eq 0 ]; then
+      pass "$check_5_31"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Containers sharing docker socket" "$docker_sock_containers"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+check_5_end() {
+  endsectionjson
+}
diff --git a/tests/6_docker_security_operations.sh b/tests/6_docker_security_operations.sh
index 3165986..ce9b257 100644
--- a/tests/6_docker_security_operations.sh
+++ b/tests/6_docker_security_operations.sh
@@ -1,71 +1,64 @@
 #!/bin/sh
 
-logit "\n"
-info "6  - Docker Security Operations"
+check_6() {
+  logit "\n"
+  id_6="6"
+  desc_6="Docker Security Operations"
+  check_6="$id_6 - $desc_6"
+  info "$check_6"
+  startsectionjson "$id_6" "$desc_6"
+}
 
-# 6.5
-check_6_5="6.5 - Use a centralized and remote log collection service"
+# 6.1
+check_6_1() {
+  id_6_1="6.1"
+  desc_6_1="Ensure that image sprawl is avoided (Not Scored)"
+  check_6_1="$id_6_1  - $desc_6_1"
+  starttestjson "$id_6_1" "$desc_6_1"
 
-# If containers is empty, there are no running containers
-if [ -z "$containers" ]; then
-  info "$check_6_5"
-  info "     * No containers running"
-else
-  fail=0
-  set -f; IFS=$'
-'
-  for c in $containers; do
-    volumes=$(docker inspect --format '{{ .Volumes }}' "$c")
+  totalChecks=$((totalChecks + 1))
+  images=$(docker images -q | sort -u | wc -l | awk '{print $1}')
+  active_images=0
 
-    if [ "$volumes" = "map[]" ]; then
-      # If it's the first container, fail the test
-      if [ $fail -eq 0 ]; then
-        info "$check_6_5"
-        info "     * Container has no volumes, ensure centralized logging is enabled : $c"
-        fail=1
-      else
-        info "     * Container has no volumes, ensure centralized logging is enabled : $c"
-      fi
+  for c in $(docker inspect --format "{{.Image}}" $(docker ps -qa) 2>/dev/null); do
+    if docker images --no-trunc -a | grep "$c" > /dev/null ; then
+      active_images=$(( active_images += 1 ))
     fi
   done
-  # Only alert if there are no volumes. If there are volumes, can't know if they
-  # are used for logs
-fi
-# Make the loop separator go back to space
-set +f; unset IFS
 
-# 6.6
-check_6_6="6.6 - Avoid image sprawl"
-images=$(docker images -q | wc -l | awk '{print $1}')
-active_images=0
+    info "$check_6_1"
+    info "     * There are currently: $images images"
 
-for c in $(docker inspect -f "{{.Image}}" $(docker ps -qa)); do
-  if docker images --no-trunc -a | grep $c > /dev/null ; then
-    active_images=$(( active_images += 1 ))
+  if [ "$active_images" -lt "$((images / 2))" ]; then
+    info "     * Only $active_images out of $images are in use"
   fi
-done
+  resulttestjson "INFO" "$active_images active/$images in use"
+  currentScore=$((currentScore + 0))
+}
 
-if [ "$images" -gt 100 ]; then
-  warn "$check_6_6"
-  warn "     * There are currently: $images images"
-else
-  info "$check_6_6"
-  info "     * There are currently: $images images"
-fi
+# 6.2
+check_6_2() {
+  id_6_2="6.2"
+  desc_6_2="Ensure that container sprawl is avoided (Not Scored)"
+  check_6_2="$id_6_2  - $desc_6_2"
+  starttestjson "$id_6_2" "$desc_6_2"
 
-if [ "$active_images" -lt "$((images / 2))" ]; then
-  warn "     * Only $active_images out of $images are in use"
-fi
+  totalChecks=$((totalChecks + 1))
+  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"
+    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"
+    resulttestjson "INFO" "$total_containers total/$running_containers running"
+  fi
+  currentScore=$((currentScore + 0))
+}
 
-# 6.7
-check_6_7="6.7 - Avoid container sprawl"
-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
-  warn "$check_6_7"
-  warn "     * There are currently a total of $total_containers containers, with only $running_containers of them currently running"
-else
-  info "$check_6_7"
-  info "     * There are currently a total of $total_containers containers, with $running_containers of them currently running"
-fi
+check_6_end() {
+  endsectionjson
+}
diff --git a/tests/7_docker_swarm_configuration.sh b/tests/7_docker_swarm_configuration.sh
new file mode 100644
index 0000000..c3b9187
--- /dev/null
+++ b/tests/7_docker_swarm_configuration.sh
@@ -0,0 +1,250 @@
+#!/bin/sh
+
+check_7() {
+  logit "\n"
+  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() {
+  id_7_1="7.1"
+  desc_7_1="Ensure swarm mode is not Enabled, if not needed (Scored)"
+  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"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  else
+    warn "$check_7_1"
+    resulttestjson "WARN"
+    currentScore=$((currentScore - 1))
+  fi
+}
+
+# 7.2
+check_7_2() {
+  id_7_2="7.2"
+  desc_7_2="Ensure that the minimum number of manager nodes have been created in a swarm (Scored)"
+  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" -eq 1 ]; then
+      pass "$check_7_2"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_7_2"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    fi
+  else
+    pass "$check_7_2 (Swarm mode not enabled)"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  fi
+}
+
+# 7.3
+check_7_3() {
+  id_7_3="7.3"
+  desc_7_3="Ensure that swarm services are bound to a specific host interface (Scored)"
+  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
+    $netbin -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"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      warn "$check_7_3"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    fi
+  else
+    pass "$check_7_3 (Swarm mode not enabled)"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  fi
+}
+
+# 7.4
+check_7_4() {
+  id_7_4="7.4"
+  desc_7_4="Ensure that all Docker swarm overlay networks are encrypted (Scored)"
+  check_7_4="$id_7_4  - $desc_7_4"
+  starttestjson "$id_7_4" "$desc_7_4"
+
+  totalChecks=$((totalChecks + 1))
+  fail=0
+  unencrypted_networks=""
+  for encnet in $(docker network ls --filter driver=overlay --quiet); do
+    if docker network inspect --format '{{.Name}} {{ .Options }}' "$encnet" | \
+      grep -v 'encrypted:' 2>/dev/null 1>&2; then
+      # If it's the first container, fail the test
+      if [ $fail -eq 0 ]; then
+        warn "$check_7_4"
+        fail=1
+      fi
+      warn "     * Unencrypted overlay network: $(docker network inspect --format '{{ .Name }} ({{ .Scope }})' "$encnet")"
+      unencrypted_networks="$unencrypted_networks $(docker network inspect --format '{{ .Name }} ({{ .Scope }})' "$encnet")"
+    fi
+  done
+  # We went through all the networks and found none that are unencrypted
+  if [ $fail -eq 0 ]; then
+      pass "$check_7_4"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+  else
+      resulttestjson "WARN" "Unencrypted overlay networks:" "$unencrypted_networks"
+      currentScore=$((currentScore - 1))
+  fi
+}
+
+# 7.5
+check_7_5() {
+  id_7_5="7.5"
+  desc_7_5="Ensure that Docker's secret management commands are used for managing secrets in a swarm cluster (Not Scored)"
+  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"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      info "$check_7_5"
+      resulttestjson "INFO"
+      currentScore=$((currentScore + 0))
+    fi
+  else
+    pass "$check_7_5 (Swarm mode not enabled)"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  fi
+}
+
+# 7.6
+check_7_6() {
+  id_7_6="7.6"
+  desc_7_6="Ensure that swarm manager is run in auto-lock mode (Scored)"
+  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"
+      resulttestjson "WARN"
+      currentScore=$((currentScore - 1))
+    else
+      pass "$check_7_6"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    fi
+  else
+    pass "$check_7_6 (Swarm mode not enabled)"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  fi
+}
+
+# 7.7
+check_7_7() {
+  id_7_7="7.7"
+  desc_7_7="Ensure that the swarm manager auto-lock key is rotated periodically (Not Scored)"
+  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"
+    resulttestjson "NOTE"
+    currentScore=$((currentScore + 0))
+  else
+    pass "$check_7_7 (Swarm mode not enabled)"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  fi
+}
+
+# 7.8
+check_7_8() {
+  id_7_8="7.8"
+  desc_7_8="Ensure that node certificates are rotated as appropriate (Not Scored)"
+  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"
+      resulttestjson "PASS"
+      currentScore=$((currentScore + 1))
+    else
+      info "$check_7_8"
+      resulttestjson "INFO"
+      currentScore=$((currentScore + 0))
+    fi
+  else
+    pass "$check_7_8 (Swarm mode not enabled)"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  fi
+}
+
+# 7.9
+check_7_9() {
+  id_7_9="7.9"
+  desc_7_9="Ensure that CA certificates are rotated as appropriate (Not Scored)"
+  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"
+    resulttestjson "INFO"
+    currentScore=$((currentScore + 0))
+  else
+    pass "$check_7_9 (Swarm mode not enabled)"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  fi
+}
+
+# 7.10
+check_7_10() {
+  id_7_10="7.10"
+  desc_7_10="Ensure that management plane traffic is separated from data plane traffic (Not Scored)"
+  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"
+    resulttestjson "INFO"
+    currentScore=$((currentScore + 0))
+  else
+    pass "$check_7_10 (Swarm mode not enabled)"
+    resulttestjson "PASS"
+    currentScore=$((currentScore + 1))
+  fi
+}
+
+check_7_end() {
+  endsectionjson
+}
diff --git a/tests/8_docker_enterprise_configuration.sh b/tests/8_docker_enterprise_configuration.sh
new file mode 100644
index 0000000..9fce978
--- /dev/null
+++ b/tests/8_docker_enterprise_configuration.sh
@@ -0,0 +1,181 @@
+#!/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_product_license() {
+  if docker version | grep -Eqi '^Server.*Community$|Version.*-ce$'; 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
+
+  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"
+}
+
+# 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 (Scored)"
+  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 (Scored)"
+  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 (Not Scored)"
+  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 (Not Scored)"
+  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 (Scored)"
+  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 (Scored)"
+  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 (Scored)"
+  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_2() {
+  if [ "$enterprise_license" -ne 1 ]; then
+    return
+  fi
+
+  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"
+}
+
+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 (Scored)"
+  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_end() {
+  endsectionjson
+}
diff --git a/tests/99_community_checks.sh b/tests/99_community_checks.sh
new file mode 100644
index 0000000..9ad1774
--- /dev/null
+++ b/tests/99_community_checks.sh
@@ -0,0 +1,59 @@
+#!/bin/sh
+check_c() {
+  logit "\n"
+  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
+check_c_1() {
+  check_c_1="C.1  - This is a example check"
+  totalChecks=$((totalChecks + 1))
+  if docker info --format='{{ .Architecture }}' | grep 'x86_64' 2>/dev/null 1>&2; then
+    pass "$check_c_1"
+    resulttestjson "PASS"
+  else
+    warn "$check_c_1"
+    resulttestjson "WARN"
+  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
+}