mirror of
https://github.com/docker/docker-bench-security.git
synced 2025-06-20 21:59:09 +00:00
Merge ca0db8898f
into ebcbf9a231
This commit is contained in:
commit
5928ecb73f
28 changed files with 4303 additions and 948 deletions
|
@ -1 +1,5 @@
|
|||
.git
|
||||
*.md
|
||||
*.png
|
||||
distros
|
||||
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1 +1 @@
|
|||
*.log
|
||||
*.log*
|
||||
|
|
|
@ -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.
|
||||
|
|
58
CONTRIBUTORS.md
Normal file
58
CONTRIBUTORS.md
Normal file
|
@ -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.
|
26
Dockerfile
26
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 [""]
|
||||
|
|
34
MAINTAINERS
Normal file
34
MAINTAINERS
Normal file
|
@ -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"
|
149
README.md
149
README.md
|
@ -1,45 +1,150 @@
|
|||
# Docker Bench for Security
|
||||
|
||||

|
||||

|
||||
|
||||
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.
|
||||
|
|
Binary file not shown.
Before ![]() (image error) Size: 180 KiB After ![]() (image error) Size: 275 KiB ![]() ![]() |
25
distros/Dockerfile.alpine
Normal file
25
distros/Dockerfile.alpine
Normal file
|
@ -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 [""]
|
15
distros/Dockerfile.centos
Normal file
15
distros/Dockerfile.centos
Normal file
|
@ -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"]
|
24
distros/Dockerfile.debian
Normal file
24
distros/Dockerfile.debian
Normal file
|
@ -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"]
|
13
distros/Dockerfile.openSUSE
Normal file
13
distros/Dockerfile.openSUSE
Normal file
|
@ -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"]
|
18
distros/Dockerfile.rhel
Normal file
18
distros/Dockerfile.rhel
Normal file
|
@ -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"]
|
21
distros/README.md
Normal file
21
distros/README.md
Normal file
|
@ -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"
|
||||
```
|
|
@ -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 "$@"
|
||||
|
|
21
docker-compose.yml
Normal file
21
docker-compose.yml
Normal file
|
@ -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
|
345
functions_lib.sh
Normal file
345
functions_lib.sh
Normal file
|
@ -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
|
||||
}
|
141
helper_lib.sh
141
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.
|
||||
# ------------------------------------------------------------------------------"
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
}
|
||||
|
|
250
tests/7_docker_swarm_configuration.sh
Normal file
250
tests/7_docker_swarm_configuration.sh
Normal file
|
@ -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
|
||||
}
|
181
tests/8_docker_enterprise_configuration.sh
Normal file
181
tests/8_docker_enterprise_configuration.sh
Normal file
|
@ -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
|
||||
}
|
59
tests/99_community_checks.sh
Normal file
59
tests/99_community_checks.sh
Normal file
|
@ -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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue