Merge pull request #248 from konstruktoid/cisDockerCE

CIS Docker CE
This commit is contained in:
Thomas Sjögren 2017-07-10 15:17:16 +02:00 committed by GitHub
commit 5d8f34954f
11 changed files with 251 additions and 217 deletions

View file

@ -20,34 +20,34 @@ compliant shell. We try to keep the project compliant for maximum portability.
You can build the container that wraps the docker-bench for security: You can build the container that wraps the docker-bench for security:
```sh ```sh
git clone git@github.com:docker/docker-bench-security.git git clone git@github.com:docker/docker-bench-security.git
cd docker-bench-security cd docker-bench-security
docker build -t docker-bench-security . docker build -t docker-bench-security .
``` ```
Or you can simply run the shell script locally: Or you can simply run the shell script locally:
```sh ```sh
git clone git@github.com:docker/docker-bench-security.git git clone git@github.com:docker/docker-bench-security.git
cd docker-bench-security cd docker-bench-security
sh docker-bench-security.sh sudo sh docker-bench-security.sh
``` ```
The Docker Bench has the main script called `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 This is the main script that checks for all the dependencies, deals with
command line arguments and loads all the tests. 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 ```sh
✗ tree tests/
tests/ tests/
├── 1_host_configuration.sh ├── 1_host_configuration.sh
├── 2_docker_daemon_configuration.sh ├── 2_docker_daemon_configuration.sh
├── 3_docker_daemon_configuration_files.sh ├── 3_docker_daemon_configuration_files.sh
├── 4_container_images.sh ├── 4_container_images.sh
├── 5_container_runtime.sh ├── 5_container_runtime.sh
└── 6_docker_security_operations.sh ├── 6_docker_security_operations.sh
└── 7_docker_swarm_configuration.sh
``` ```
To modify the Docker Bench for Security you should first clone the repository, To modify the Docker Bench for Security you should first clone the repository,
@ -55,7 +55,8 @@ 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 tools, and then sign off on your commits. After that feel free to send us a
pull request with the changes. pull request with the changes.
While this tool was inspired by the [CIS Docker 1.11.0 benchmark](https://benchmarks.cisecurity.org/downloads/show-single/index.cfm?file=docker16.110), While this tool was inspired by the [CIS Docker 1.11.0 benchmark](https://benchmarks.cisecurity.org/downloads/show-single/index.cfm?file=docker16.110)
feel free to add new tests. We will try to turn [dockerbench.com](https://dockerbench.com) and its successors, feel free to add new tests. We will try to turn
into a list of good community benchmarks for both security and performance, [dockerbench.com](https://dockerbench.com) into a list of good community
and we would love community contributions. benchmarks for both security and performance, and we would love community
contributions.

View file

@ -4,7 +4,7 @@
The Docker Bench for Security is a script that checks for dozens of common 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 best-practices around deploying Docker containers in production. The tests are
all automated, and are inspired by the [CIS Docker 1.13 Benchmark](https://benchmarks.cisecurity.org/tools2/docker/CIS_Docker_1.13.0_Benchmark_v1.0.0.pdf). all automated, and are inspired by the [CIS Docker Community Edition Benchmark v1.1.0](https://benchmarks.cisecurity.org/tools2/docker/CIS_Docker_Community_Edition_Benchmark_v1.1.0.pdf).
We are releasing this as a follow-up to our [Understanding Docker Security and Best Practices](https://blog.docker.com/2015/05/understanding-docker-security-and-best-practices/) 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. blog post.
@ -76,7 +76,7 @@ Also, this script can also be simply run from your base host by running:
```sh ```sh
git clone https://github.com/docker/docker-bench-security.git git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security cd docker-bench-security
sh docker-bench-security.sh sudo sh docker-bench-security.sh
``` ```
This script was build to be POSIX 2004 compliant, so it should be portable This script was build to be POSIX 2004 compliant, so it should be portable

Binary file not shown.

Before

Width:  |  Height:  |  Size: 391 KiB

After

Width:  |  Height:  |  Size: 386 KiB

View file

@ -1,11 +1,11 @@
#!/bin/sh #!/bin/sh
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Docker Bench for Security v1.3.2 # Docker Bench for Security v1.3.3
# #
# Docker, Inc. (c) 2015- # Docker, Inc. (c) 2015-
# #
# Checks for dozens of common best-practices around deploying Docker containers in production. # Checks for dozens of common best-practices around deploying Docker containers in production.
# Inspired by the CIS Docker 1.13 Benchmark. # Inspired by the CIS Docker Community Edition Benchmark v1.1.0.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Load dependencies # Load dependencies
@ -56,12 +56,12 @@ if [ -z "$logger" ]; then
fi fi
yell "# ------------------------------------------------------------------------------ yell "# ------------------------------------------------------------------------------
# Docker Bench for Security v1.3.2 # Docker Bench for Security v1.3.3
# #
# Docker, Inc. (c) 2015- # Docker, Inc. (c) 2015-
# #
# Checks for dozens of common best-practices around deploying Docker containers in production. # Checks for dozens of common best-practices around deploying Docker containers in production.
# Inspired by the CIS Docker 1.13 Benchmark. # Inspired by the CIS Docker Community Edition Benchmark v1.1.0.
# ------------------------------------------------------------------------------" # ------------------------------------------------------------------------------"
# Warn if not root # Warn if not root

View file

@ -5,7 +5,7 @@ info "1 - Host Configuration"
auditrules="/etc/audit/audit.rules" auditrules="/etc/audit/audit.rules"
# 1.1 # 1.1
check_1_1="1.1 - Create a separate partition for containers" check_1_1="1.1 - Ensure a separate partition for containers has been created"
if grep /var/lib/docker /etc/fstab >/dev/null 2>&1; then if grep /var/lib/docker /etc/fstab >/dev/null 2>&1; then
pass "$check_1_1" pass "$check_1_1"
else else
@ -13,28 +13,27 @@ else
fi fi
# 1.2 # 1.2
check_1_2="1.2 - Harden the container host" check_1_2="1.2 - Ensure the container host has been Hardened"
note "$check_1_2" note "$check_1_2"
# 1.3 # 1.3
check_1_3="1.3 - Keep Docker up to date" check_1_3="1.3 - Ensure Docker is up to date"
docker_version=$(docker version | grep -i -A1 '^server' | grep -i 'version:' \ docker_version=$(docker version | grep -i -A1 '^server' | grep -i 'version:' \
| awk '{print $NF; exit}' | tr -d '[:alpha:]-,') | awk '{print $NF; exit}' | tr -d '[:alpha:]-,')
docker_current_version="$(date +%y.%m.0)" docker_current_version="$(date --date="$(date +%y-%m-1) -1 month" +%y.%m.0)"
docker_current_date="$(date +%Y-%m-01)"
do_version_check "$docker_current_version" "$docker_version" do_version_check "$docker_current_version" "$docker_version"
if [ $? -eq 11 ]; then if [ $? -eq 11 ]; then
info "$check_1_3" info "$check_1_3"
info " * Using $docker_version, when $docker_current_version is current as of $docker_current_date" info " * Using $docker_version, verify is it up to date as deemed necessary"
info " * Your operating system vendor may provide support and security maintenance for Docker" info " * Your operating system vendor may provide support and security maintenance for Docker"
else else
pass "$check_1_3" pass "$check_1_3"
info " * Using $docker_version which is current as of $docker_current_date" info " * Using $docker_version which is current"
info " * Check with your operating system vendor for support and security maintenance for Docker" info " * Check with your operating system vendor for support and security maintenance for Docker"
fi fi
# 1.4 # 1.4
check_1_4="1.4 - Only allow trusted users to control Docker daemon" check_1_4="1.4 - Ensure only trusted users are allowed to control Docker daemon"
docker_users=$(getent group docker) docker_users=$(getent group docker)
info "$check_1_4" info "$check_1_4"
for u in $docker_users; do for u in $docker_users; do
@ -42,7 +41,7 @@ for u in $docker_users; do
done done
# 1.5 # 1.5
check_1_5="1.5 - Audit docker daemon - /usr/bin/docker" check_1_5="1.5 - Ensure auditing is configured for the Docker daemon"
file="/usr/bin/docker " file="/usr/bin/docker "
if command -v auditctl >/dev/null 2>&1; then if command -v auditctl >/dev/null 2>&1; then
if auditctl -l | grep "$file" >/dev/null 2>&1; then if auditctl -l | grep "$file" >/dev/null 2>&1; then
@ -57,7 +56,7 @@ else
fi fi
# 1.6 # 1.6
check_1_6="1.6 - Audit Docker files and directories - /var/lib/docker" check_1_6="1.6 - Ensure auditing is configured for Docker files and directories - /var/lib/docker"
directory="/var/lib/docker" directory="/var/lib/docker"
if [ -d "$directory" ]; then if [ -d "$directory" ]; then
if command -v auditctl >/dev/null 2>&1; then if command -v auditctl >/dev/null 2>&1; then
@ -77,7 +76,7 @@ else
fi fi
# 1.7 # 1.7
check_1_7="1.7 - Audit Docker files and directories - /etc/docker" check_1_7="1.7 - Ensure auditing is configured for Docker files and directories - /etc/docker"
directory="/etc/docker" directory="/etc/docker"
if [ -d "$directory" ]; then if [ -d "$directory" ]; then
if command -v auditctl >/dev/null 2>&1; then if command -v auditctl >/dev/null 2>&1; then
@ -97,7 +96,7 @@ else
fi fi
# 1.8 # 1.8
check_1_8="1.8 - Audit Docker files and directories - docker.service" check_1_8="1.8 - Ensure auditing is configured for Docker files and directories - docker.service"
file="$(get_systemd_service_file docker.service)" file="$(get_systemd_service_file docker.service)"
if [ -f "$file" ]; then if [ -f "$file" ]; then
if command -v auditctl >/dev/null 2>&1; then if command -v auditctl >/dev/null 2>&1; then
@ -117,7 +116,7 @@ else
fi fi
# 1.9 # 1.9
check_1_9="1.9 - Audit Docker files and directories - docker.socket" check_1_9="1.9 - Ensure auditing is configured for Docker files and directories - docker.socket"
file="$(get_systemd_service_file docker.socket)" file="$(get_systemd_service_file docker.socket)"
if [ -e "$file" ]; then if [ -e "$file" ]; then
if command -v auditctl >/dev/null 2>&1; then if command -v auditctl >/dev/null 2>&1; then
@ -137,7 +136,7 @@ else
fi fi
# 1.10 # 1.10
check_1_10="1.10 - Audit Docker files and directories - /etc/default/docker" check_1_10="1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker"
file="/etc/default/docker" file="/etc/default/docker"
if [ -f "$file" ]; then if [ -f "$file" ]; then
if command -v auditctl >/dev/null 2>&1; then if command -v auditctl >/dev/null 2>&1; then
@ -157,7 +156,7 @@ else
fi fi
# 1.11 # 1.11
check_1_11="1.11 - Audit Docker files and directories - /etc/docker/daemon.json" check_1_11="1.11 - Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json"
file="/etc/docker/daemon.json" file="/etc/docker/daemon.json"
if [ -f "$file" ]; then if [ -f "$file" ]; then
if command -v auditctl >/dev/null 2>&1; then if command -v auditctl >/dev/null 2>&1; then
@ -177,7 +176,7 @@ else
fi fi
# 1.12 # 1.12
check_1_12="1.12 - Audit Docker files and directories - /usr/bin/docker-containerd" check_1_12="1.12 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-containerd"
file="/usr/bin/docker-containerd" file="/usr/bin/docker-containerd"
if [ -f "$file" ]; then if [ -f "$file" ]; then
if command -v auditctl >/dev/null 2>&1; then if command -v auditctl >/dev/null 2>&1; then
@ -197,7 +196,7 @@ else
fi fi
# 1.13 # 1.13
check_1_13="1.13 - Audit Docker files and directories - /usr/bin/docker-runc" check_1_13="1.13 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-runc"
file="/usr/bin/docker-runc" file="/usr/bin/docker-runc"
if [ -f "$file" ]; then if [ -f "$file" ]; then
if command -v auditctl >/dev/null 2>&1; then if command -v auditctl >/dev/null 2>&1; then

View file

@ -1,10 +1,10 @@
#!/bin/sh #!/bin/sh
logit "\n" logit "\n"
info "2 - Docker Daemon Configuration" info "2 - Docker daemon configuration"
# 2.1 # 2.1
check_2_1="2.1 - Restrict network traffic between containers" check_2_1="2.1 - Ensure network traffic is restricted between containers on the default bridge"
if get_docker_effective_command_line_args '--icc' | grep false >/dev/null 2>&1; then if get_docker_effective_command_line_args '--icc' | grep false >/dev/null 2>&1; then
pass "$check_2_1" pass "$check_2_1"
elif get_docker_configuration_file_args 'icc' | grep "false" >/dev/null 2>&1; then elif get_docker_configuration_file_args 'icc' | grep "false" >/dev/null 2>&1; then
@ -14,7 +14,7 @@ else
fi fi
# 2.2 # 2.2
check_2_2="2.2 - Set the logging level" check_2_2="2.2 - Ensure the logging level is set to 'info'"
if get_docker_configuration_file_args 'log-level' >/dev/null 2>&1; then 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 if get_docker_configuration_file_args 'log-level' | grep info >/dev/null 2>&1; then
pass "$check_2_2" pass "$check_2_2"
@ -34,7 +34,7 @@ else
fi fi
# 2.3 # 2.3
check_2_3="2.3 - Allow Docker to make changes to iptables" check_2_3="2.3 - Ensure Docker is allowed to make changes to iptables"
if get_docker_effective_command_line_args '--iptables' | grep "false" >/dev/null 2>&1; then if get_docker_effective_command_line_args '--iptables' | grep "false" >/dev/null 2>&1; then
warn "$check_2_3" warn "$check_2_3"
elif get_docker_configuration_file_args 'iptables' | grep "false" >/dev/null 2>&1; then elif get_docker_configuration_file_args 'iptables' | grep "false" >/dev/null 2>&1; then
@ -44,7 +44,7 @@ else
fi fi
# 2.4 # 2.4
check_2_4="2.4 - Do not use insecure registries" check_2_4="2.4 - Ensure insecure registries are not used"
if get_docker_effective_command_line_args '--insecure-registry' | grep "insecure-registry" >/dev/null 2>&1; then if get_docker_effective_command_line_args '--insecure-registry' | grep "insecure-registry" >/dev/null 2>&1; then
warn "$check_2_4" warn "$check_2_4"
elif ! [ -z "$(get_docker_configuration_file_args 'insecure-registries')" ]; then elif ! [ -z "$(get_docker_configuration_file_args 'insecure-registries')" ]; then
@ -58,7 +58,7 @@ else
fi fi
# 2.5 # 2.5
check_2_5="2.5 - Do not use the aufs storage driver" check_2_5="2.5 - Ensure aufs storage driver is not used"
if docker info 2>/dev/null | grep -e "^Storage Driver:\s*aufs\s*$" >/dev/null 2>&1; then if docker info 2>/dev/null | grep -e "^Storage Driver:\s*aufs\s*$" >/dev/null 2>&1; then
warn "$check_2_5" warn "$check_2_5"
else else
@ -66,7 +66,7 @@ else
fi fi
# 2.6 # 2.6
check_2_6="2.6 - Configure TLS authentication for Docker daemon" check_2_6="2.6 - Ensure TLS authentication for Docker daemon is configured"
if grep -i 'tcp://' "$CONFIG_FILE" 2>/dev/null 1>&2; then if grep -i 'tcp://' "$CONFIG_FILE" 2>/dev/null 1>&2; then
if [ $(get_docker_configuration_file_args '"tls":' | grep 'true') ] || \ if [ $(get_docker_configuration_file_args '"tls":' | grep 'true') ] || \
[ $(get_docker_configuration_file_args '"tlsverify' | grep 'true') ] ; then [ $(get_docker_configuration_file_args '"tlsverify' | grep 'true') ] ; then
@ -101,7 +101,7 @@ fi
# 2.7 # 2.7
check_2_7="2.7 - Set default ulimit as appropriate" check_2_7="2.7 - Ensure the default ulimit is configured appropriately"
if get_docker_configuration_file_args 'default-ulimit' | grep -v '{}' >/dev/null 2>&1; then if get_docker_configuration_file_args 'default-ulimit' | grep -v '{}' >/dev/null 2>&1; then
pass "$check_2_7" pass "$check_2_7"
elif get_docker_effective_command_line_args '--default-ulimit' | grep "default-ulimit" >/dev/null 2>&1; then elif get_docker_effective_command_line_args '--default-ulimit' | grep "default-ulimit" >/dev/null 2>&1; then
@ -122,7 +122,7 @@ else
fi fi
# 2.9 # 2.9
check_2_9="2.9 - Confirm default cgroup usage" check_2_9="2.9 - Ensure the default cgroup usage has been confirmed"
if get_docker_configuration_file_args 'cgroup-parent' | grep -v '""'; then if get_docker_configuration_file_args 'cgroup-parent' | grep -v '""'; then
warn "$check_2_9" warn "$check_2_9"
info " * Confirm cgroup usage" info " * Confirm cgroup usage"
@ -134,7 +134,7 @@ else
fi fi
# 2.10 # 2.10
check_2_10="2.10 - Do not change base device size until needed" check_2_10="2.10 - Ensure base device size is not changed until needed"
if get_docker_configuration_file_args 'storage-opts' | grep "dm.basesize" >/dev/null 2>&1; then if get_docker_configuration_file_args 'storage-opts' | grep "dm.basesize" >/dev/null 2>&1; then
warn "$check_2_10" warn "$check_2_10"
elif get_docker_effective_command_line_args '--storage-opt' | grep "dm.basesize" >/dev/null 2>&1; then elif get_docker_effective_command_line_args '--storage-opt' | grep "dm.basesize" >/dev/null 2>&1; then
@ -144,7 +144,7 @@ else
fi fi
# 2.11 # 2.11
check_2_11="2.11 - Use authorization plugin" check_2_11="2.11 - Ensure that authorization for Docker client commands is enabled"
if get_docker_configuration_file_args 'authorization-plugins' | grep -v '\[]'; then if get_docker_configuration_file_args 'authorization-plugins' | grep -v '\[]'; then
pass "$check_2_11" pass "$check_2_11"
elif get_docker_effective_command_line_args '--authorization-plugin' | grep "authorization-plugin" >/dev/null 2>&1; then elif get_docker_effective_command_line_args '--authorization-plugin' | grep "authorization-plugin" >/dev/null 2>&1; then
@ -154,7 +154,7 @@ else
fi fi
# 2.12 # 2.12
check_2_12="2.12 - Configure centralized and remote logging" check_2_12="2.12 - Ensure centralized and remote logging is configured"
if docker info --format '{{ .LoggingDriver }}' | grep 'json-file' >/dev/null 2>&1; then if docker info --format '{{ .LoggingDriver }}' | grep 'json-file' >/dev/null 2>&1; then
warn "$check_2_12" warn "$check_2_12"
else else
@ -162,7 +162,7 @@ else
fi fi
# 2.13 # 2.13
check_2_13="2.13 - Disable operations on legacy registry (v1)" check_2_13="2.13 - Ensure operations on legacy registry (v1) are Disabled"
if get_docker_configuration_file_args 'disable-legacy-registry' | grep 'true' >/dev/null 2>&1; then if get_docker_configuration_file_args 'disable-legacy-registry' | grep 'true' >/dev/null 2>&1; then
pass "$check_2_13" pass "$check_2_13"
elif get_docker_effective_command_line_args '--disable-legacy-registry' | grep "disable-legacy-registry" >/dev/null 2>&1; then elif get_docker_effective_command_line_args '--disable-legacy-registry' | grep "disable-legacy-registry" >/dev/null 2>&1; then
@ -172,7 +172,7 @@ else
fi fi
# 2.14 # 2.14
check_2_14="2.14 - Enable live restore" check_2_14="2.14 - Ensure live restore is Enabled"
if docker info 2>/dev/null | grep -e "Live Restore Enabled:\s*true\s*" >/dev/null 2>&1; then if docker info 2>/dev/null | grep -e "Live Restore Enabled:\s*true\s*" >/dev/null 2>&1; then
pass "$check_2_14" pass "$check_2_14"
else else
@ -184,105 +184,37 @@ else
fi fi
# 2.15 # 2.15
check_2_15="2.15 - Do not enable swarm mode, if not needed" check_2_15="2.15 - Ensure Userland Proxy is Disabled"
if docker info 2>/dev/null | grep -e "Swarm:*\sinactive\s*" >/dev/null 2>&1; then if get_docker_configuration_file_args 'userland-proxy' | grep false >/dev/null 2>&1; then
pass "$check_2_15"
elif get_docker_effective_command_line_args '--userland-proxy=false' 2>/dev/null | grep "userland-proxy=false" >/dev/null 2>&1; then
pass "$check_2_15" pass "$check_2_15"
else else
warn "$check_2_15" warn "$check_2_15"
fi fi
# 2.16 # 2.16
check_2_16="2.16 - Control the number of manager nodes in a swarm" check_2_16="2.16 - Ensure daemon-wide custom seccomp profile is applied, if needed"
if docker info 2>/dev/null | grep -e "Swarm:*\sactive\s*" >/dev/null 2>&1; then if docker info --format '{{ .SecurityOptions }}' | grep 'name=seccomp,profile=default' 2>/dev/null 1>&2; then
managernodes=$(docker node ls | grep -c "Leader") pass "$check_2_16"
if [ "$managernodes" -le 1 ]; then
pass "$check_2_16"
else
warn "$check_2_16"
fi
else else
pass "$check_2_16 (Swarm mode not enabled)" info "$check_2_16"
fi fi
# 2.17 # 2.17
check_2_17="2.17 - Bind swarm services to a specific host interface" check_2_17="2.17 - Ensure experimental features are avoided in production"
if docker info 2>/dev/null | grep -e "Swarm:*\sactive\s*" >/dev/null 2>&1; then if docker version -f '{{.Server.Experimental}}' | grep false 2>/dev/null 1>&2; then
netstat -lnt | grep -e '\[::]:2377 ' -e ':::2377' -e '*:2377 ' -e ' 0\.0\.0\.0:2377 ' >/dev/null 2>&1 pass "$check_2_17"
if [ $? -eq 1 ]; then
pass "$check_2_17"
else
warn "$check_2_17"
fi
else else
pass "$check_2_17 (Swarm mode not enabled)" warn "$check_2_17"
fi fi
# 2.18 # 2.18
check_2_18="2.18 - Disable Userland Proxy" check_2_18="2.18 - Ensure containers are restricted from acquiring new privileges"
if get_docker_configuration_file_args 'userland-proxy' | grep false >/dev/null 2>&1; then if get_docker_effective_command_line_args '--no-new-privileges' >/dev/null 2>&1; then
pass "$check_2_18" pass "$check_2_18"
elif get_docker_effective_command_line_args '--userland-proxy=false' 2>/dev/null | grep "userland-proxy=false" >/dev/null 2>&1; then elif get_docker_configuration_file_args 'no-new-privileges' >/dev/null 2>&1; then
pass "$check_2_18" pass "$check_2_18"
else else
warn "$check_2_18" warn "$check_2_18"
fi fi
# 2.19
check_2_19="2.19 - Encrypt data exchanged between containers on different nodes on the overlay network"
if docker network ls --filter driver=overlay --quiet | \
xargs docker network inspect --format '{{.Name}} {{ .Options }}' 2>/dev/null | \
grep -v 'encrypted:' 2>/dev/null 1>&2; then
warn "$check_2_19"
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
warn " * Unencrypted overlay network: $(docker network inspect --format '{{ .Name }} ({{ .Scope }})' "$encnet")"
fi
done
else
pass "$check_2_19"
fi
# 2.20
check_2_20="2.20 - Apply a daemon-wide custom seccomp profile, if needed"
if docker info --format '{{ .SecurityOptions }}' | grep 'name=seccomp,profile=default' 2>/dev/null 1>&2; then
pass "$check_2_20"
else
info "$check_2_20"
fi
# 2.21
check_2_21="2.21 - Avoid experimental features in production"
if docker version -f '{{.Server.Experimental}}' | grep false 2>/dev/null 1>&2; then
pass "$check_2_21"
else
warn "$check_2_21"
fi
# 2.22
check_2_22="2.22 - Use Docker's secret management commands for managing secrets in a Swarm cluster"
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_2_22"
else
info "$check_2_22"
fi
else
pass "$check_2_22 (Swarm mode not enabled)"
fi
# 2.23
check_2_23="2.23 - Run swarm manager in auto-lock mode"
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_2_23"
else
pass "$check_2_23"
fi
else
pass "$check_2_23 (Swarm mode not enabled)"
fi
# 2.24
check_2_24="2.24 - Rotate swarm manager auto-lock key periodically"
note "$check_2_24"

View file

@ -1,10 +1,10 @@
#!/bin/sh #!/bin/sh
logit "\n" logit "\n"
info "3 - Docker Daemon Configuration Files" info "3 - Docker daemon configuration files"
# 3.1 # 3.1
check_3_1="3.1 - Verify that docker.service file ownership is set to root:root" check_3_1="3.1 - Ensure that docker.service file ownership is set to root:root"
file="$(get_systemd_service_file docker.service)" file="$(get_systemd_service_file docker.service)"
if [ -f "$file" ]; then if [ -f "$file" ]; then
if [ "$(stat -c %u%g $file)" -eq 00 ]; then if [ "$(stat -c %u%g $file)" -eq 00 ]; then
@ -19,7 +19,7 @@ else
fi fi
# 3.2 # 3.2
check_3_2="3.2 - Verify that docker.service file permissions are set to 644 or more restrictive" check_3_2="3.2 - Ensure that docker.service file permissions are set to 644 or more restrictive"
file="$(get_systemd_service_file docker.service)" file="$(get_systemd_service_file docker.service)"
if [ -f "$file" ]; then if [ -f "$file" ]; then
if [ "$(stat -c %a $file)" -eq 644 -o "$(stat -c %a $file)" -eq 600 ]; then if [ "$(stat -c %a $file)" -eq 644 -o "$(stat -c %a $file)" -eq 600 ]; then
@ -34,7 +34,7 @@ else
fi fi
# 3.3 # 3.3
check_3_3="3.3 - Verify that docker.socket file ownership is set to root:root" check_3_3="3.3 - Ensure that docker.socket file ownership is set to root:root"
file="$(get_systemd_service_file docker.socket)" file="$(get_systemd_service_file docker.socket)"
if [ -f "$file" ]; then if [ -f "$file" ]; then
if [ "$(stat -c %u%g $file)" -eq 00 ]; then if [ "$(stat -c %u%g $file)" -eq 00 ]; then
@ -49,7 +49,7 @@ else
fi fi
# 3.4 # 3.4
check_3_4="3.4 - Verify that docker.socket file permissions are set to 644 or more restrictive" check_3_4="3.4 - Ensure that docker.socket file permissions are set to 644 or more restrictive"
file="$(get_systemd_service_file docker.socket)" file="$(get_systemd_service_file docker.socket)"
if [ -f "$file" ]; then if [ -f "$file" ]; then
if [ "$(stat -c %a $file)" -eq 644 -o "$(stat -c %a $file)" -eq 600 ]; then if [ "$(stat -c %a $file)" -eq 644 -o "$(stat -c %a $file)" -eq 600 ]; then
@ -64,7 +64,7 @@ else
fi fi
# 3.5 # 3.5
check_3_5="3.5 - Verify that /etc/docker directory ownership is set to root:root" check_3_5="3.5 - Ensure that /etc/docker directory ownership is set to root:root"
directory="/etc/docker" directory="/etc/docker"
if [ -d "$directory" ]; then if [ -d "$directory" ]; then
if [ "$(stat -c %u%g $directory)" -eq 00 ]; then if [ "$(stat -c %u%g $directory)" -eq 00 ]; then
@ -79,7 +79,7 @@ else
fi fi
# 3.6 # 3.6
check_3_6="3.6 - Verify that /etc/docker directory permissions are set to 755 or more restrictive" check_3_6="3.6 - Ensure that /etc/docker directory permissions are set to 755 or more restrictive"
directory="/etc/docker" directory="/etc/docker"
if [ -d "$directory" ]; then if [ -d "$directory" ]; then
if [ "$(stat -c %a $directory)" -eq 755 -o "$(stat -c %a $directory)" -eq 700 ]; then if [ "$(stat -c %a $directory)" -eq 755 -o "$(stat -c %a $directory)" -eq 700 ]; then
@ -94,7 +94,7 @@ else
fi fi
# 3.7 # 3.7
check_3_7="3.7 - Verify that registry certificate file ownership is set to root:root" check_3_7="3.7 - Ensure that registry certificate file ownership is set to root:root"
directory="/etc/docker/certs.d/" directory="/etc/docker/certs.d/"
if [ -d "$directory" ]; then if [ -d "$directory" ]; then
fail=0 fail=0
@ -116,7 +116,7 @@ else
fi fi
# 3.8 # 3.8
check_3_8="3.8 - Verify that registry certificate file permissions are set to 444 or more restrictive" check_3_8="3.8 - Ensure that registry certificate file permissions are set to 444 or more restrictive"
directory="/etc/docker/certs.d/" directory="/etc/docker/certs.d/"
if [ -d "$directory" ]; then if [ -d "$directory" ]; then
fail=0 fail=0
@ -138,7 +138,7 @@ else
fi fi
# 3.9 # 3.9
check_3_9="3.9 - Verify that TLS CA certificate file ownership is set to root:root" check_3_9="3.9 - Ensure that TLS CA certificate file ownership is set to root:root"
if ! [ -z $(get_docker_configuration_file_args 'tlscacert') ]; then if ! [ -z $(get_docker_configuration_file_args 'tlscacert') ]; then
tlscacert=$(get_docker_configuration_file_args 'tlscacert') tlscacert=$(get_docker_configuration_file_args 'tlscacert')
else else
@ -157,7 +157,7 @@ else
fi fi
# 3.10 # 3.10
check_3_10="3.10 - Verify that TLS CA certificate file permissions are set to 444 or more restrictive" check_3_10="3.10 - Ensure that TLS CA certificate file permissions are set to 444 or more restrictive"
if ! [ -z $(get_docker_configuration_file_args 'tlscacert') ]; then if ! [ -z $(get_docker_configuration_file_args 'tlscacert') ]; then
tlscacert=$(get_docker_configuration_file_args 'tlscacert') tlscacert=$(get_docker_configuration_file_args 'tlscacert')
else else
@ -176,7 +176,7 @@ else
fi fi
# 3.11 # 3.11
check_3_11="3.11 - Verify that Docker server certificate file ownership is set to root:root" check_3_11="3.11 - Ensure that Docker server certificate file ownership is set to root:root"
if ! [ -z $(get_docker_configuration_file_args 'tlscert') ]; then if ! [ -z $(get_docker_configuration_file_args 'tlscert') ]; then
tlscert=$(get_docker_configuration_file_args 'tlscert') tlscert=$(get_docker_configuration_file_args 'tlscert')
else else
@ -195,7 +195,7 @@ else
fi fi
# 3.12 # 3.12
check_3_12="3.12 - Verify that Docker server certificate file permissions are set to 444 or more restrictive" check_3_12="3.12 - Ensure that Docker server certificate file permissions are set to 444 or more restrictive"
if ! [ -z $(get_docker_configuration_file_args 'tlscert') ]; then if ! [ -z $(get_docker_configuration_file_args 'tlscert') ]; then
tlscert=$(get_docker_configuration_file_args 'tlscert') tlscert=$(get_docker_configuration_file_args 'tlscert')
else else
@ -214,7 +214,7 @@ else
fi fi
# 3.13 # 3.13
check_3_13="3.13 - Verify that Docker server key file ownership is set to root:root" check_3_13="3.13 - Ensure that Docker server certificate key file ownership is set to root:root"
if ! [ -z $(get_docker_configuration_file_args 'tlskey') ]; then if ! [ -z $(get_docker_configuration_file_args 'tlskey') ]; then
tlskey=$(get_docker_configuration_file_args 'tlskey') tlskey=$(get_docker_configuration_file_args 'tlskey')
else else
@ -233,14 +233,14 @@ else
fi fi
# 3.14 # 3.14
check_3_14="3.14 - Verify that Docker server key file permissions are set to 400 or more restrictive" check_3_14="3.14 - Ensure that Docker server certificate key file permissions are set to 400"
if ! [ -z $(get_docker_configuration_file_args 'tlskey') ]; then if ! [ -z $(get_docker_configuration_file_args 'tlskey') ]; then
tlskey=$(get_docker_configuration_file_args 'tlskey') tlskey=$(get_docker_configuration_file_args 'tlskey')
else else
tlskey=$(get_docker_effective_command_line_args '--tlskey' | sed -n 's/.*tlskey=\([^s]\)/\1/p' | sed 's/--/ --/g' | cut -d " " -f 1) tlskey=$(get_docker_effective_command_line_args '--tlskey' | sed -n 's/.*tlskey=\([^s]\)/\1/p' | sed 's/--/ --/g' | cut -d " " -f 1)
fi fi
if [ -f "$tlskey" ]; then if [ -f "$tlskey" ]; then
if [ "$(stat -c %a $tlskey)" -eq 444 -o "$(stat -c %a $tlskey)" -eq 400 ]; then if [ "$(stat -c %a $tlskey)" -eq 400 ]; then
pass "$check_3_14" pass "$check_3_14"
else else
warn "$check_3_14" warn "$check_3_14"
@ -252,7 +252,7 @@ else
fi fi
# 3.15 # 3.15
check_3_15="3.15 - Verify that Docker socket file ownership is set to root:docker" check_3_15="3.15 - Ensure that Docker socket file ownership is set to root:docker"
file="/var/run/docker.sock" file="/var/run/docker.sock"
if [ -S "$file" ]; then if [ -S "$file" ]; then
if [ "$(stat -c %U:%G $file)" = 'root:docker' ]; then if [ "$(stat -c %U:%G $file)" = 'root:docker' ]; then
@ -267,7 +267,7 @@ else
fi fi
# 3.16 # 3.16
check_3_16="3.16 - Verify that Docker socket file permissions are set to 660 or more restrictive" check_3_16="3.16 - Ensure that Docker socket file permissions are set to 660 or more restrictive"
file="/var/run/docker.sock" file="/var/run/docker.sock"
if [ -S "$file" ]; then if [ -S "$file" ]; then
if [ "$(stat -c %a $file)" -eq 660 -o "$(stat -c %a $file)" -eq 600 ]; then if [ "$(stat -c %a $file)" -eq 660 -o "$(stat -c %a $file)" -eq 600 ]; then
@ -282,7 +282,7 @@ else
fi fi
# 3.17 # 3.17
check_3_17="3.17 - Verify that daemon.json file ownership is set to root:root" check_3_17="3.17 - Ensure that daemon.json file ownership is set to root:root"
file="/etc/docker/daemon.json" file="/etc/docker/daemon.json"
if [ -f "$file" ]; then if [ -f "$file" ]; then
if [ "$(stat -c %U:%G $file)" = 'root:root' ]; then if [ "$(stat -c %U:%G $file)" = 'root:root' ]; then
@ -297,7 +297,7 @@ else
fi fi
# 3.18 # 3.18
check_3_18="3.18 - Verify that daemon.json file permissions are set to 644 or more restrictive" check_3_18="3.18 - Ensure that daemon.json file permissions are set to 644 or more restrictive"
file="/etc/docker/daemon.json" file="/etc/docker/daemon.json"
if [ -f "$file" ]; then if [ -f "$file" ]; then
if [ "$(stat -c %a $file)" -eq 644 -o "$(stat -c %a $file)" -eq 600 ]; then if [ "$(stat -c %a $file)" -eq 644 -o "$(stat -c %a $file)" -eq 600 ]; then
@ -312,7 +312,7 @@ else
fi fi
# 3.19 # 3.19
check_3_19="3.19 - Verify that /etc/default/docker file ownership is set to root:root" check_3_19="3.19 - Ensure that /etc/default/docker file ownership is set to root:root"
file="/etc/default/docker" file="/etc/default/docker"
if [ -f "$file" ]; then if [ -f "$file" ]; then
if [ "$(stat -c %U:%G $file)" = 'root:root' ]; then if [ "$(stat -c %U:%G $file)" = 'root:root' ]; then
@ -327,7 +327,7 @@ else
fi fi
# 3.20 # 3.20
check_3_20="3.20 - Verify that /etc/default/docker file permissions are set to 644 or more restrictive" check_3_20="3.20 - Ensure that /etc/default/docker file permissions are set to 644 or more restrictive"
file="/etc/default/docker" file="/etc/default/docker"
if [ -f "$file" ]; then if [ -f "$file" ]; then
if [ "$(stat -c %a $file)" -eq 644 -o "$(stat -c %a $file)" -eq 600 ]; then if [ "$(stat -c %a $file)" -eq 644 -o "$(stat -c %a $file)" -eq 600 ]; then

View file

@ -1,10 +1,10 @@
#!/bin/sh #!/bin/sh
logit "\n" logit "\n"
info "4 - Container Images and Build Files" info "4 - Container Images and Build File"
# 4.1 # 4.1
check_4_1="4.1 - Create a user for the container" check_4_1="4.1 - Ensure a user for the container has been created"
# If container_users is empty, there are no running containers # If container_users is empty, there are no running containers
if [ -z "$containers" ]; then if [ -z "$containers" ]; then
@ -41,19 +41,19 @@ set +f; unset IFS
images=$(docker images -q) images=$(docker images -q)
# 4.2 # 4.2
check_4_2="4.2 - Use trusted base images for containers" check_4_2="4.2 - Ensure that containers use trusted base images"
note "$check_4_2" note "$check_4_2"
# 4.3 # 4.3
check_4_3="4.3 - Do not install unnecessary packages in the container" check_4_3="4.3 - Ensure unnecessary packages are not installed in the container"
note "$check_4_3" note "$check_4_3"
# 4.4 # 4.4
check_4_4="4.4 - Scan and rebuild the images to include security patches" check_4_4="4.4 - Ensure images are scanned and rebuilt to include security patches"
note "$check_4_4" note "$check_4_4"
# 4.5 # 4.5
check_4_5="4.5 - Enable Content trust for Docker" check_4_5="4.5 - Ensure Content trust for Docker is Enabled"
if [ "x$DOCKER_CONTENT_TRUST" = "x1" ]; then if [ "x$DOCKER_CONTENT_TRUST" = "x1" ]; then
pass "$check_4_5" pass "$check_4_5"
else else
@ -61,7 +61,7 @@ else
fi fi
# 4.6 # 4.6
check_4_6="4.6 - Add HEALTHCHECK instruction to the container image" check_4_6="4.6 - Ensure HEALTHCHECK instructions have been added to the container image"
fail=0 fail=0
for img in $images; do for img in $images; do
if docker inspect --format='{{.Config.Healthcheck}}' "$img" 2>/dev/null | grep -e "<nil>" >/dev/null 2>&1; then if docker inspect --format='{{.Config.Healthcheck}}' "$img" 2>/dev/null | grep -e "<nil>" >/dev/null 2>&1; then
@ -80,7 +80,7 @@ if [ $fail -eq 0 ]; then
fi fi
# 4.7 # 4.7
check_4_7="4.7 - Do not use update instructions alone in the Dockerfile" check_4_7="4.7 - Ensure update instructions are not use alone in the Dockerfile"
fail=0 fail=0
for img in $images; do for img in $images; do
if docker history "$img" 2>/dev/null | grep -e "update" >/dev/null 2>&1; then if docker history "$img" 2>/dev/null | grep -e "update" >/dev/null 2>&1; then
@ -99,11 +99,11 @@ if [ $fail -eq 0 ]; then
fi fi
# 4.8 # 4.8
check_4_8="4.8 - Remove setuid and setgid permissions in the images" check_4_8="4.8 - Ensure setuid and setgid permissions are removed in the images"
note "$check_4_8" note "$check_4_8"
# 4.9 # 4.9
check_4_9="4.9 - Use COPY instead of ADD in Dockerfile" check_4_9="4.9 - Ensure COPY is used instead of ADD in Dockerfile"
fail=0 fail=0
for img in $images; do for img in $images; do
docker history "$img" 2> /dev/null | grep 'ADD' >/dev/null 2>&1 docker history "$img" 2> /dev/null | grep 'ADD' >/dev/null 2>&1
@ -123,9 +123,9 @@ if [ $fail -eq 0 ]; then
fi fi
# 4.10 # 4.10
check_4_10="4.10 - Do not store secrets in Dockerfiles" check_4_10="4.10 - Ensure secrets are not stored in Dockerfiles"
note "$check_4_10" note "$check_4_10"
# 4.11 # 4.11
check_4_11="4.11 - Install verified packages only" check_4_11="4.11 - Ensure verified packages are only Installed"
note "$check_4_11" note "$check_4_11"

View file

@ -11,7 +11,7 @@ else
set -f; IFS=$' set -f; IFS=$'
' '
# 5.1 # 5.1
check_5_1="5.1 - Do not disable AppArmor Profile" check_5_1="5.1 - Ensure AppArmor Profile is Enabled"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -34,7 +34,7 @@ else
fi fi
# 5.2 # 5.2
check_5_2="5.2 - Verify SELinux security options, if applicable" check_5_2="5.2 - Ensure SELinux security options are set, if applicable"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -57,7 +57,7 @@ else
fi fi
# 5.3 # 5.3
check_5_3="5.3 - Restrict Linux Kernel Capabilities within containers" check_5_3="5.3 - Ensure Linux Kernel Capabilities are restricted within containers"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -83,7 +83,7 @@ else
fi fi
# 5.4 # 5.4
check_5_4="5.4 - Do not use privileged containers" check_5_4="5.4 - Ensure privileged containers are not used"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -106,7 +106,7 @@ else
fi fi
# 5.5 # 5.5
check_5_5="5.5 - Do not mount sensitive host system directories on containers" check_5_5="5.5 - Ensure sensitive host system directories are not mounted on containers"
# List of sensitive directories to test for. Script uses new-lines as a separator. # 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. # Note the lack of identation. It needs it for the substring comparison.
@ -149,7 +149,7 @@ else
fi fi
# 5.6 # 5.6
check_5_6="5.6 - Do not run ssh within containers" check_5_6="5.6 - Ensure ssh is not run within containers"
fail=0 fail=0
printcheck=0 printcheck=0
@ -185,7 +185,7 @@ else
fi fi
# 5.7 # 5.7
check_5_7="5.7 - Do not map privileged ports within containers" check_5_7="5.7 - Ensure privileged ports are not mapped within containers"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -194,7 +194,7 @@ else
# iterate through port range (line delimited) # iterate through port range (line delimited)
for port in $ports; do for port in $ports; do
if [ ! -z "$port" ] && [ "0$port" -lt 1024 ]; then if [ ! -z "$port" ] && [ "$port" -lt 1024 ]; then
# If it's the first container, fail the test # If it's the first container, fail the test
if [ $fail -eq 0 ]; then if [ $fail -eq 0 ]; then
warn "$check_5_7" warn "$check_5_7"
@ -212,11 +212,11 @@ else
fi fi
# 5.8 # 5.8
check_5_8="5.8 - Open only needed ports on container" check_5_8="5.8 - Ensure only needed ports are open on the container"
note "$check_5_8" note "$check_5_8"
# 5.9 # 5.9
check_5_9="5.9 - Do not share the host's network namespace" check_5_9="5.9 - Ensure the host's network namespace is not shared"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -239,7 +239,7 @@ else
fi fi
# 5.10 # 5.10
check_5_10="5.10 - Limit memory usage for container" check_5_10="5.10 - Ensure memory usage for container is limited"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -266,7 +266,7 @@ else
fi fi
# 5.11 # 5.11
check_5_11="5.11 - Set container CPU priority appropriately" check_5_11="5.11 - Ensure CPU priority is set appropriately on the container"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -293,7 +293,7 @@ else
fi fi
# 5.12 # 5.12
check_5_12="5.12 - Mount container's root filesystem as read only" check_5_12="5.12 - Ensure the container's root filesystem is mounted as read only"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -316,7 +316,7 @@ else
fi fi
# 5.13 # 5.13
check_5_13="5.13 - Bind incoming container traffic to a specific host interface" check_5_13="5.13 - Ensure incoming container traffic is binded to a specific host interface"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -339,7 +339,7 @@ else
fi fi
# 5.14 # 5.14
check_5_14="5.14 - Set the 'on-failure' container restart policy to 5" check_5_14="5.14 - Ensure 'on-failure' container restart policy is set to '5'"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -362,7 +362,7 @@ else
fi fi
# 5.15 # 5.15
check_5_15="5.15 - Do not share the host's process namespace" check_5_15="5.15 - Ensure the host's process namespace is not shared"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -385,7 +385,7 @@ else
fi fi
# 5.16 # 5.16
check_5_16="5.16 - Do not share the host's IPC namespace" check_5_16="5.16 - Ensure the host's IPC namespace is not shared"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -408,7 +408,7 @@ else
fi fi
# 5.17 # 5.17
check_5_17="5.17 - Do not directly expose host devices to containers" check_5_17="5.17 - Ensure host devices are not directly exposed to containers"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -431,7 +431,7 @@ else
fi fi
# 5.18 # 5.18
check_5_18="5.18 - Override default ulimit at runtime only if needed" check_5_18="5.18 - Ensure the default ulimit is overwritten at runtime, only if needed"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -454,7 +454,7 @@ else
fi fi
# 5.19 # 5.19
check_5_19="5.19 - Do not set mount propagation mode to shared" check_5_19="5.19 - Ensure mount propagation mode is not set to shared"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -476,7 +476,7 @@ else
fi fi
# 5.20 # 5.20
check_5_20="5.20 - Do not share the host's UTS namespace" check_5_20="5.20 - Ensure the host's UTS namespace is not shared"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -499,7 +499,7 @@ else
fi fi
# 5.21 # 5.21
check_5_21="5.21 - Do not disable default seccomp profile" check_5_21="5.21 - Ensure the default seccomp profile is not Disabled"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -520,15 +520,15 @@ else
fi fi
# 5.22 # 5.22
check_5_22="5.22 - Do not docker exec commands with privileged option" check_5_22="5.22 - Ensure docker exec commands are not used with privileged option"
note "$check_5_22" note "$check_5_22"
# 5.23 # 5.23
check_5_23="5.23 - Do not docker exec commands with user option" check_5_23="5.23 - Ensure docker exec commands are not used with user option"
note "$check_5_23" note "$check_5_23"
# 5.24 # 5.24
check_5_24="5.24 - Confirm cgroup usage" check_5_24="5.24 - Ensure cgroup usage is confirmed"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -551,7 +551,7 @@ else
fi fi
# 5.25 # 5.25
check_5_25="5.25 - Restrict container from acquiring additional privileges" check_5_25="5.25 - Ensure the container is restricted from acquiring additional privileges"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -572,7 +572,7 @@ else
fi fi
# 5.26 # 5.26
check_5_26="5.26 - Check container health at runtime" check_5_26="5.26 - Ensure container health is checked at runtime"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -595,7 +595,7 @@ else
info "$check_5_27" info "$check_5_27"
# 5.28 # 5.28
check_5_28="5.28 - Use PIDs cgroup limit" check_5_28="5.28 - Ensure PIDs cgroup limit is used"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -618,7 +618,7 @@ else
fi fi
# 5.29 # 5.29
check_5_29="5.29 - Do not use Docker's default bridge docker0" check_5_29="5.29 - Ensure Docker's default bridge docker0 is not used"
fail=0 fail=0
networks=$(docker network ls -q 2>/dev/null) networks=$(docker network ls -q 2>/dev/null)
@ -644,7 +644,7 @@ else
fi fi
# 5.30 # 5.30
check_5_30="5.30 - Do not share the host's user namespaces" check_5_30="5.30 - Ensure the host's user namespaces is not shared"
fail=0 fail=0
for c in $containers; do for c in $containers; do
@ -665,7 +665,7 @@ else
fi fi
# 5.31 # 5.31
check_5_31="5.31 - Do not mount the Docker socket inside any containers" check_5_31="5.31 - Ensure the Docker socket is not mounted inside any containers"
fail=0 fail=0
for c in $containers; do for c in $containers; do

View file

@ -4,44 +4,32 @@ logit "\n"
info "6 - Docker Security Operations" info "6 - Docker Security Operations"
# 6.1 # 6.1
check_6_1="6.1 - Perform regular security audits of your host system and containers" check_6_1="6.1 - Avoid image sprawl"
info "$check_6_1"
# 6.2
check_6_2="6.2 - Monitor Docker containers usage, performance and metering"
info "$check_6_2"
# 6.3
check_6_3="6.3 - Backup container data"
info "$check_6_3"
# 6.4
check_6_4="6.4 - Avoid image sprawl"
images=$(docker images -q | sort -u | wc -l | awk '{print $1}') images=$(docker images -q | sort -u | wc -l | awk '{print $1}')
active_images=0 active_images=0
for c in $(docker inspect -f "{{.Image}}" $(docker ps -qa)); do 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 if docker images --no-trunc -a | grep "$c" > /dev/null ; then
active_images=$(( active_images += 1 )) active_images=$(( active_images += 1 ))
fi fi
done done
info "$check_6_4" info "$check_6_1"
info " * There are currently: $images images" info " * There are currently: $images images"
if [ "$active_images" -lt "$((images / 2))" ]; then if [ "$active_images" -lt "$((images / 2))" ]; then
info " * Only $active_images out of $images are in use" info " * Only $active_images out of $images are in use"
fi fi
# 6.5 # 6.2
check_6_5="6.5 - Avoid container sprawl" check_6_2="6.2 - Avoid container sprawl"
total_containers=$(docker info 2>/dev/null | grep "Containers" | awk '{print $2}') total_containers=$(docker info 2>/dev/null | grep "Containers" | awk '{print $2}')
running_containers=$(docker ps -q | wc -l | awk '{print $1}') running_containers=$(docker ps -q | wc -l | awk '{print $1}')
diff="$((total_containers - running_containers))" diff="$((total_containers - running_containers))"
if [ "$diff" -gt 25 ]; then if [ "$diff" -gt 25 ]; then
info "$check_6_5" info "$check_6_2"
info " * There are currently a total of $total_containers containers, with only $running_containers of them currently running" info " * There are currently a total of $total_containers containers, with only $running_containers of them currently running"
else else
info "$check_6_5" info "$check_6_2"
info " * There are currently a total of $total_containers containers, with $running_containers of them currently running" info " * There are currently a total of $total_containers containers, with $running_containers of them currently running"
fi fi

View file

@ -0,0 +1,114 @@
#!/bin/sh
logit "\n"
info "7 - Docker Swarm Configuration"
# 7.1
check_7_1="7.1 - Ensure swarm mode is not Enabled, if not needed"
if docker info 2>/dev/null | grep -e "Swarm:*\sinactive\s*" >/dev/null 2>&1; then
pass "$check_7_1"
else
warn "$check_7_1"
fi
# 7.2
check_7_2="7.2 - Ensure the minimum number of manager nodes have been created in a swarm"
if docker info 2>/dev/null | grep -e "Swarm:*\sactive\s*" >/dev/null 2>&1; then
managernodes=$(docker node ls | grep -c "Leader")
if [ "$managernodes" -le 1 ]; then
pass "$check_7_2"
else
warn "$check_7_2"
fi
else
pass "$check_7_2 (Swarm mode not enabled)"
fi
# 7.3
check_7_3="7.3 - Ensure swarm services are binded to a specific host interface"
if docker info 2>/dev/null | grep -e "Swarm:*\sactive\s*" >/dev/null 2>&1; then
netstat -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"
else
warn "$check_7_3"
fi
else
pass "$check_7_3 (Swarm mode not enabled)"
fi
# 7.4
check_7_4="7.4 - Ensure data exchanged between containers are encrypted on different nodes on the overlay network"
if docker network ls --filter driver=overlay --quiet | \
xargs docker network inspect --format '{{.Name}} {{ .Options }}' 2>/dev/null | \
grep -v 'encrypted:' 2>/dev/null 1>&2; then
warn "$check_7_4"
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
warn " * Unencrypted overlay network: $(docker network inspect --format '{{ .Name }} ({{ .Scope }})' "$encnet")"
fi
done
else
pass "$check_7_4"
fi
# 7.5
check_7_5="7.5 - Ensure Docker's secret management commands are used for managing secrets in a Swarm cluster"
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"
else
info "$check_7_5"
fi
else
pass "$check_7_5 (Swarm mode not enabled)"
fi
# 7.6
check_7_6="7.6 - Ensure swarm manager is run in auto-lock mode"
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"
else
pass "$check_7_6"
fi
else
pass "$check_7_6 (Swarm mode not enabled)"
fi
# 7.7
check_7_7="7.7 - Ensure swarm manager auto-lock key is rotated periodically"
if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
note "$check_7_7"
else
pass "$check_7_7 (Swarm mode not enabled)"
fi
# 7.8
check_7_8="7.8 - Ensure node certificates are rotated as appropriate"
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"
else
info "$check_7_8"
fi
else
pass "$check_7_8 (Swarm mode not enabled)"
fi
# 7.9
check_7_9="7.9 - Ensure CA certificates are rotated as appropriate"
if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
info "$check_7_9"
else
pass "$check_7_9 (Swarm mode not enabled)"
fi
# 7.10
check_7_10="7.10 - Ensure management plane traffic has been separated from data plane traffic"
if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
info "$check_7_10"
else
pass "$check_7_10 (Swarm mode not enabled)"
fi