Coder Social home page Coder Social logo

docker / docker-bench-security Goto Github PK

View Code? Open in Web Editor NEW
9.0K 236.0 1.0K 4.45 MB

The Docker Bench for Security is a script that checks for dozens of common best-practices around deploying Docker containers in production.

License: Apache License 2.0

Shell 99.69% Dockerfile 0.31%

docker-bench-security's Introduction

Docker Bench for Security

Docker Bench for Security running

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 based on the CIS Docker Benchmark v1.6.0.

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.

Release CIS
1.6.0 1.6.0
1.5.0 1.5.0
1.3.6 1.4.0
1.3.5 1.2.0
1.3.3 1.1.0
1.3.0 1.13.0

Running Docker Bench for Security

Run from your base host

You can simply run this script from your base host by running:

git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
sudo sh docker-bench-security.sh

Note: jq is an optional but recommended dependency.

Run with Docker

Building Docker image

You have two options if you wish to build and run this container yourself:

  1. Use Docker Build:
git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
docker build --no-cache -t docker-bench-security .

Followed by an appropriate docker run command as stated below.

  1. Use Docker Compose:
git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
docker-compose run --rm docker-bench-security

Please note that the docker/docker-bench-security image is out-of-date and and a manual build is required. See #405 for more information.

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.

Using the container

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-bench-security

Don't forget to adjust the shared volumes according to your operating system. Some examples are:

  1. On Ubuntu the docker.service and docker.secret files are located in /lib/systemd/system folder by default.
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-bench-security
  1. The /etc/hostname file is missing on macOS, so it will need to be created first. Also, Docker Desktop on macOS doesn't have /usr/lib/systemd or the above Docker binaries.
sudo touch /etc/hostname

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-bench-security

Note

Docker bench requires Docker 1.13.0 or later in order to run.

Note that when distributions don't contain auditctl, the audit tests will check /etc/audit/audit.rules to see if a rule is present instead.

Docker Bench for Security options

  -b           optional  Do not print colors
  -h           optional  Print this help message
  -l FILE      optional  Log output in FILE, inside container if run using docker
  -u USERS     optional  Comma delimited list of trusted docker user(s)
  -c CHECK     optional  Comma delimited list of specific check(s) id
  -e CHECK     optional  Comma delimited list of specific check(s) id 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
  -t LABEL     optional  Comma delimited list of labels within a container or image to 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).
  -p PRINT     optional  Disable the printing of remediation measures. Default: print remediation measures.

By default the Docker Bench for Security script will run all available CIS tests and produce logs in the log folder from current directory, named docker-bench-security.log.json and docker-bench-security.log.

If the docker container is used then the log files will be created inside the container in location /usr/local/bin/log/. If you wish to access them from the host after the container has been run you will need to mount a volume for storing them in.

The CIS based checks are named check_<section>_<number>, e.g. check_2_6 and community contributed checks are named check_c_<number>.

sh docker-bench-security.sh -c check_2_2 will only run check 2.2 Ensure the logging level is set to 'info'.

sh docker-bench-security.sh -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 -e docker_enterprise_configuration will run all available checks except the docker_enterprise_configuration group

sh docker-bench-security.sh -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 -c container_images,container_runtime will run just the container_images and container_runtime checks

sh docker-bench-security.sh -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.

docker-bench-security's People

Contributors

aermie avatar andreagalle avatar archaeogeek avatar boblington avatar brsolomon-deloitte avatar csabapalfi avatar diogomonica avatar ellerbrock avatar fatherlinux avatar halfluke avatar j0wi avatar jammasterj89 avatar jessfraz avatar jlusiardi avatar joaocfernandes avatar jumanjiman avatar kbabioch avatar kevinll avatar konstruktoid avatar lekpamartin avatar lusitania avatar markdumay avatar mpritter76 avatar mrsecure avatar mstemm avatar nikitastupin avatar razvanstoica89 avatar thajeztah avatar wilmardo avatar zawazawa0316 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

docker-bench-security's Issues

command line options checks are for short or long versions of options only

Only the short or long variants of various docker daemon command line options are checked for, giving incorrect results. The following are not accounted for (not necessarily exhaustive)

tests/2_docker_daemon_configuration.sh

  • 2.3: -l, --log-level, only long version checked
  • 2.8, 2.9, 2.10: -H, --host=[], only short checked

Turn off colors when logging to a file

I want to collect logs from many kinds of nodes, but when I look at the log files, they're filled with unreadable ANSI escape codes!

$ ansible --become all -a "docker run -it --net host --pid host --cap-add audit_control -v /var/lib:/var/lib -v /var/run/docker.sock:/var/run/docker.sock -v /usr/lib/systemd:/usr/lib/systemd -v /etc:/etc --label docker_bench_security docker/docker-bench-security -l /tmp/docker-security.txt"

# success

# ssh into node

$ less /tmp/docker-security.txt
ESC[1;34m[INFO]ESC[0m 1 - Host Configuration
ESC[1;31m[WARN]ESC[0m 1.1  - Create a separate partition for containers
ESC[1;32m[PASS]ESC[0m 1.2  - Use an updated Linux Kernel
ESC[1;31m[WARN]ESC[0m 1.4  - Remove all non-essential services from the host - Network
ESC[1;31m[WARN]ESC[0m      * Host listening on: 35 ports
ESC[1;32m[PASS]ESC[0m 1.5  - Keep Docker up to date

Error connecting to docker daemon

Hi, clone docker compose and trying to run, got this error:

docker-compose run --rm docker-bench-security
.
.
.
Successfully built 345e17343307
Error connecting to docker daemon (does docker ps work?)
docker-bench-security|master โ‡’ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
docker-bench-security|master โ‡’ 

Different behaviour for pgrep between version 3.3.3-3 (Debian 7) and 3.3.9-1ubuntu2.2 (Ubuntu 14.04)

Hey guys,

i tried to execute your script on a Ubuntu 14.04 host and learned that pgrep from the procps tools (version 3.3.9-1ubuntu2.2) shipped with that distro changed it behaviour.

For example, taken from your script (2_docker_daemon_configuration.sh line 8)

pgrep -lf docker | grep lxc >/dev/null 2>&1

In version 3.3.3-3 the result of "pgrep -lf docker" looks like "2086 /usr/bin/docker -d -p /var/run/docker.pid" which is perfect for the piped greps.

In version 3.3.9-1ubuntu2.2 the result of "pgrep -lf docker" looks just like "910 docker" where as "pgrep -alf docker" returns the desired information (e.g. "910 /usr/bin/docker -d --icc=false") again.

This breaks all tests that use pgrep for the new version.

Please have a look to improve the script for Ubuntu Users

Thanks!

Joachim

1.7 group check only works for local users and groups

Check 1.7 Only allow trusted users to control Docker daemon" in tests/1_host_configuration.sh only works for local users:

docker_users=$(grep docker /etc/group)

This disregards users and their group membership coming from non-local sources, e.g. NIS, LDAP, AD.

Recently added use of systemctl to get systemd file path is not working on centos7

related to this merge a couple weeks ago: #102

Running the benchmark script inside a Centos7 container on the centos host returns a few of these in section 3:

Failed to get D-Bus connection: No connection to service manager.

It looks like the running benchmark container is missing access to some socket or another that systemctl wants.

But simple adding -v /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket Did not resolve this.

Maybe the benchmark should go back to the hard coded file-path, unless @konstruktoid has a really good reason not to?

daemon options can only be extracted from command line

Hi,

docker daemon holds an option --config-file and other options can be set inside the file. However, from your implementation, I can't see it supporting extracting options from the configuration file so it can only support extracting options set in command line.

Alex

CPU information misleading

The benchmark reports:

[WARN]      * Container running without CPU restrictions: 9f39cbf8e538

This is misleading at best, as CPU shares are relative and set by default. This means that a user who doesn't set any CPU shares will find that all containers share CPU equally when under load. Contrast this with a user who sets containers to a share of 10 by default, if they accidentally set a container to 100 or forget to set a value for a container, they will be in much worse position with one container getting the lion's share of resources.

Disabling check execution by param

Add a param to disable check execution, something like:

docker run -it --net host --pid host --cap-add audit_control \
    -e "disable_checks=check_1_6,check_1_12"
    -v /var/lib:/var/lib \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /usr/lib/systemd:/usr/lib/systemd \
    -v /etc:/etc --label docker_bench_security \
    docker/docker-bench-security

Test 2.6 is unreliable

Test 2.6 uses get_command_line_args docker which returns info about the most recently launched process with "docker" in its name. This is often NOT the docker daemon.

A better path would likely be to use get_docker_cumulative_command_line_args to ensure the analysis is done on the docker daemon process info.

Proposal: Use Docker Config Files to Override Settings

So one of the issues that's causing me to heavily modify the base code (which is easy enough since it's just a bunch of shell scripts) of this app is the fact that we've set our own standards for where to install and run Docker.

Initially, our docker filesystem runs out of /docker instead of /var/lib/docker and our socket file exists in the /docker area also.

All of these settings are stored in /etc/sysconfig (RHEL Based Distribution, I know it's different in Debian/Ubuntu). It would be nice if the code took into consideration the various stored switches in the config files to override the defaults: For instance, if the code looked for the "-g" option to the docker run line in /etc/sysconfig/docker and then overrode "directory" in 1.1 to point to the location specified by the -g command line switch.

Several things are gained by this methodology: you can override directories, check for networking options or even skip tests based upon understanding the default behavior of docker + what's configured in the config files.

Add ability to filter out docker-bench-security container from results

The Docker container that executes the security benchmark tests shows up in a number of warnings that obscures the work needed to secure the target Docker containers. It would be nice to exclude the container that is running the tests from the analysis by default (or atleast add an option to exclude).

README incorrect for quick start.

It appears 2 days ago it was changed to docker-bench-security, to pull from docker hub. This container does not exists on docker hub so this is broken at the moment.

docker run -it --net host --pid host --cap-add audit_control
-v /var/lib:/var/lib
-v /var/run/docker.sock:/var/run/docker.sock
-v /usr/lib/systemd:/usr/lib/systemd
-v /etc:/etc --label docker-bench-security
docker-bench-security

Audits check CLI arguments, not actual settings

Lots of the tests (particularly in 2) look at CLI args to commands, like docker, i.e. https://github.com/diogomonica/docker-bench-security/blob/master/tests/2_docker_daemon_configuration.sh#L72 looks for -H via ps -ef | grep docker | grep "\-H".

It appears you could easily fake this out with liberal toying with the docker arguments. Reviewing them at https://docs.docker.com/reference/commandline/cli/, the pidfile stands out as an arbitrary string that could be abused. You could pass tests by creating the following pidfile: /var/tmp/lxcicc\=falselog-level\=\\\"debug\\\"iptables\=falseinsecure-registryregistry-mirror\\-Hdefault-ulimit (you cannot insert / even when escaped, so the tcp:// check would have to be faked with another argument.

Also, you're not looking at positions in the ps output. I believe you could exploit the lack of positional testing with something simple like a grep command that isn't given a 3rd argument:

$ grep "docker lxcicc\=falselog-level\=\\\"debug\\\"iptables\=falseinsecure-registryregistry-mirror\\-Htcp\:\/\/default-ulimittcp://"

# ps -ef | grep docker | grep "\-H"
user   32093 28062  0 21:29 pts/0    00:00:00 grep docker lxcicc\=falselog-level\=\"debug\"iptables\=falseinsecure-registryregistry-mirror\-Htcp\:\/\/default-ulimittcp://

I think if there are ways to test for the present of a listening network socket, for instance, rather than looking for tcp://, that would more accurately and consistently determine the state.

Count unique images only

We have a lot of images, which are mostly duplicates (they share the same image id) - I think that it would be best to count only the unique image ids.

/usr/lib/systemd error on OS X.

$ docker run -it --net host --pid host --cap-add audit_control \
    -v /var/lib:/var/lib \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /usr/lib/systemd:/usr/lib/systemd \
    -v /etc:/etc --label docker_bench_security \
    germanramos/docker-bench-security
docker: Error response from daemon: Mounts denied: 
The path /usr/lib/systemd
is not shared from OS X and does not belong to the system.
You can configure shared paths from Docker -> Preferences...

There is no /usr/lib/systemd on Mac. Is this volume mapping required? The test seem to run fine without it? Maybe the docs need to be updated to reflect this?

Mounting /etc to container /etc results in unexpected container failures

I suggest to mount host /etc to /host/etc folder inside docker-bench-security container. Otherwise you overwrite container /etc folder.
This can cause different problems: for example in Alpine container you will see "xterm terminal not found" error, when running clear or tput command - as result of hiding default '/etc' folder.
This will require to update all checks that looks for files and directories under /etc. I suggest to check if /host/etc exists than use it as /etc folder.

auditctl not found

Several of the tests will fail if the auditctl command is not found. Shouldn't this be something that's installed in the image?

tests do not account for command line switched used multiple times

Connected to #97: some checks are against non-cumulative options that can be specified multiple times, overwriting previous setting. e.g.:

docker daemon --log-level="debug" --log-level="info"

This will run the daemon with info, but the grep in check 2.3 finds a false positive:

#2.3
check_2_3="2.3  - Set the logging level"
get_command_line_args docker | grep "log-level=\"debug\"" >/dev/null 2>&1

Sign docker hub image

Docker Hub image for docker-bench-security is not signed, which causes some hilarity when you try to pull the image to run security audit when content trust is enabled and docker says the image is not trusted

Docker content trust test (4.5) will always fail when using pre-built container.

The README.md suggests using the pre-built container for running the tests as so:

docker run -it --net host --pid host --cap-add audit_control --rm
-v /var/lib:/var/lib
-v /var/run/docker.sock:/var/run/docker.sock
-v /usr/lib/systemd:/usr/lib/systemd
-v /etc:/etc --label docker_bench_security
docker/docker-bench-security

When doing this, the test for docker content trust uses the environment variables of the container the docker-bench-security.sh script is run in and so will always report that the test has failed.

This can be confirmed by overriding the entrypoint with /bin/sh, echo'ing DOCKER_CONTENT_TRUST to confirm it's not set, running the docker-bench-security.sh script, noting that the test fails, exporting DOCKER_CONTENT_TRUST=1 within the container, running the script again and noting that the test now passes.

I'm not sure the best way to resolve this. One way is to modify the above run command to copy over the DOCKER_CONTENT_TRUST environment variable like so:

docker run -it --net host --pid host --cap-add audit_control --rm
-e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST
-v /var/lib:/var/lib
-v /var/run/docker.sock:/var/run/docker.sock
-v /usr/lib/systemd:/usr/lib/systemd
-v /etc:/etc --label docker_bench_security
docker/docker-bench-security

Any better ideas?

Explanation of warnings

When I run this script, I get several warnings that I don't quite understand, or that don't seem fully fleshed out. Many could just mention the docker daemon setting that they're talking about, like --icc for warning 1.10, or --userns-remap for 2.8.

Here are some examples of more ambiguous warnings (sorry for the ANSI escape codes):

[WARN] 1.1  - Create a separate partition for containers
[WARN] 1.7  - Audit docker daemon - /usr/bin/docker
[WARN] 1.8  - Audit Docker files and directories - /var/lib/docker
[WARN] 1.9  - Audit Docker files and directories - /etc/docker
[WARN] 1.10 - Audit Docker files and directories - docker.service
[WARN] 4.1  - Create a user for the container
[WARN] 5.25 - Restrict container from acquiring additional privileges
[WARN] 5.20 - Do not share the host's UTS namespace

Sorry if these are clear to everyone else ๐Ÿ’ก

Erroneous [WARN] 5.3 - Verify that containers are running only a single main process

Running the docker-bench-security.sh script produced a WARN entry for ensuring only one process is running inside the container. Looking at the test for this check on https://benchmarks.cisecurity.org/tools2/docker/CIS_Docker_1.6_Benchmark_v1.0.0.pdf (docker exec $INSTANCE_ID ps -el) the output contains the ps process itself as well as the container's single process:

docker exec $INSTANCE_ID ps -el
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 600 1 0 0 80 0 - 706419 futex_ ? 00:03:22 java
4 R 600 128 0 0 80 0 - 2270 - ? 00:00:00 ps

Adding the following would exclude the test from the search results and not produce a false negative.
docker exec $INSTANCE_ID ps -el | grep -v ps
docker version
Client:
Version: 1.9.1
API version: 1.21
Go version: go1.4.2
Git commit: a34a1d5/1.9.1
Built:
OS/Arch: linux/amd64

Server:
Version: 1.9.1
API version: 1.21
Go version: go1.4.2
Git commit: a34a1d5/1.9.1
Built:
OS/Arch: linux/amd64

Replace auditctl with grep

Some Linux distributions do not have auditctl installed. For example: Alpine Linux (your default Docker image). This results in multiple check failures.

I suggest to replace auditctl with grep. Or do it if auditctl is not installed, at least.
The following grep expression should work: search for audit on $file, skipping commented lines

grep "$file" "/etc/audit/audit.rules" | grep "^[^#;]" 

auditctl not found, but on host OS

Not sure how this is supposed to work, but whenever I run it on my host (Ubuntu 14.04) with auditctl installed, it always reports that auditctl was not found. I'm running it via the docker run command in the README:

docker run -it --net host --pid host --cap-add audit_control     -v /var/lib:/var/lib     -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

It doesn't list anything about mounting /sbin, so I'm not sure how it is supposed to find auditctl:

# which auditctl
/sbin/auditctl

Bug: [WARN] 1.1 - Create a separate partition for containers

Though, the upstream CIS Benchmark only specifies one way of testing, I am thinking that another test might make sense to determine if someone is using an external partition.

It seems brittle, but checking /etc/sysconfig/docker-storage for the dm.thinpooldev string, then ensuring that it's

DOCKER_STORAGE_OPTIONS=--storage-opt dm.fs=xfs --storage-opt dm.thinpooldev=/dev/mapper/rhel-docker--pool

Then doing something like the following:

DOCKER_POOL_CHECK=docker info | grep "Pool Name" | cut -f2 -d:
ls /dev/mapper/ | grep $DOCKER_POOL_CHECK

Feel free to rethink my logic, this was very quick and dirty :-)

Missing MAINTAINERS file

I'm working on preparing the open source repositories for the new centralized maintainers file, but noticed this repository does not yet have a MAINTAINERS file.

I can create a PR to fix this, but I'm not sure who should be included as maintainer(s).

@konstruktoid @diogomonica are you the maintainers, of this project, or should I add other people here?

for reference, see docker/opensource#35 and moby/moby#18321

1.11/1.12 Audit Docker files and directories - assumes docker is run under systemd

1.11 Audit Docker files and directories - docker-registry.service

#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.12 Audit Docker files and directories - docker.service (Scored)

#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"
  else
    warn "$check_1_12"
  fi
else
  warn "1.12 - Failed to inspect: auditctl command not found."
fi

Sections 1.8 through 1.18 are failing on RHEL7 hosts

When I use the following command, these sections fail:

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

Sections

[WARN] 1.8 - Failed to inspect: auditctl command not found.
[WARN] 1.9 - Failed to inspect: auditctl command not found.
[WARN] 1.10 - Failed to inspect: auditctl command not found.
[WARN] 1.11 - Failed to inspect: auditctl command not found.
[WARN] 1.12 - Failed to inspect: auditctl command not found.
[WARN] 1.13 - Failed to inspect: auditctl command not found.
[WARN] 1.14 - Failed to inspect: auditctl command not found.
[WARN] 1.15 - Failed to inspect: auditctl command not found.
[WARN] 1.16 - Failed to inspect: auditctl command not found.
[WARN] 1.17 - Failed to inspect: auditctl command not found.
[WARN] 1.18 - Failed to inspect: auditctl command not found.

However, if I run the script locally, it works

git clone https://github.com/diogomonica/docker-bench-security.git
cd docker-bench-security/
bash docker-bench-security.sh

Sections
[PASS] 1.8 - Audit docker daemon
[PASS] 1.9 - Audit Docker files and directories - /var/lib/docker
[PASS] 1.10 - Audit Docker files and directories - /etc/docker
[PASS] 1.11 - Audit Docker files and directories - docker-registry.service
[PASS] 1.12 - Audit Docker files and directories - docker.service
[PASS] 1.13 - Audit Docker files and directories - /var/run/docker.sock
[PASS] 1.14 - Audit Docker files and directories - /etc/sysconfig/docker
[PASS] 1.15 - Audit Docker files and directories - /etc/sysconfig/docker-network
[PASS] 1.16 - Audit Docker files and directories - /etc/sysconfig/docker-registry
[PASS] 1.17 - Audit Docker files and directories - /etc/sysconfig/docker-storage
[PASS] 1.18 - Audit Docker files and directories - /etc/default/docker

I had a suspicion that it might be something in the container, so I built my own version from RHEL:

Dockerfile
FROM rhel7

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 net-tools; yum clean all
RUN mkdir /docker-bench-security
COPY . /docker-bench-security
WORKDIR /docker-bench-security
ENTRYPOINT ["/bin/sh", "docker-bench-security.sh"]

Build
docker build -t fatherlinux/docker-bench-security .

While it builds and runs properly, I get the same failures:

[WARN] 1.8 - Failed to inspect: auditctl command not found.
[WARN] 1.9 - Failed to inspect: auditctl command not found.
[WARN] 1.10 - Failed to inspect: auditctl command not found.
[WARN] 1.11 - Failed to inspect: auditctl command not found.
[WARN] 1.12 - Failed to inspect: auditctl command not found.
[WARN] 1.13 - Failed to inspect: auditctl command not found.
[WARN] 1.14 - Failed to inspect: auditctl command not found.
[WARN] 1.15 - Failed to inspect: auditctl command not found.
[WARN] 1.16 - Failed to inspect: auditctl command not found.
[WARN] 1.17 - Failed to inspect: auditctl command not found.
[WARN] 1.18 - Failed to inspect: auditctl command not found.

Any ideas on what could be happening or how to troubleshoot?

How to run this against a swarm?

Since the default commands provided are using host-volumes I asked myself, if there is any advice how to run this against a swarm or is docker-bench-security intended to run on every host of a swarm?

1.6 version check claims a version as being current indefinately

The version check 1.6 / 1_host_configuration.sh has the following example output:

[WARN] 1.6  - Keep Docker up to date
[WARN]       * Using 1.8.3, when 1.9.0 is current.

This statement about 1.9.0 is only a snapshot in time, and is untrue with the release of the next version. The code is frequently updated when docker version as it is released, e.g. 2e6d3b2.

The user cannot be assumed to always fetch the latest version of this code.

To improve the statement security wise, it should be clarified that a particular version is current as of a particular date. This is what I propose:

[WARN]       * Using X.X.X, when as of YYYY-MM-DD Z.Z.Z is current.

or

[INFO]       * Using X.X.X, which is current as of YYYY-MM-DD.

Where YYYY-MM-DD is the release date of the particular version.

In addition, in the light of Linux distributions providing support and security coverage, let's add an [INFO] indicating that the package may be (security) supported and maintained by the vendor.

I am not proposing an online version check.

Bump the version

# Docker Bench for Security v1.0.0

We should have changed the version when we updated it to 1.11 :)

Can not wrong docker-bench-security on old docker daemon

As I see to communicate with docker daemon, docker client API version has to older than docker engine.

However, the README says it can be run since docker daemon 1.6.2, I think this isn't correct since docker-bench-security installed docker 1.10 which client API version is 1.22, which far more newer than docker daemon 1.6.2(1.18).

Since docker-bench-security installed docker 1.10 that means it only can be run on docker 1.10 and newer version, is it right?

Proposal: Update Check / Benchmark Numbers to Match CIS Document Sections

As it is right now, the checks in Docker-Bench in many cases do not match up to the current (1.6) version of the CIS document. This means that when reading a WARN from the tool, we can't match it up to the CIS document to determine what that warning got produced from or what the recommendation is.

It would be EXCEPTIONALLY helpful if, upon updating, we could re-set the check numbers to identically match the CIS sections so that the tool is self referencing and self documenting.

Wrong permission check in CoreOS?

cat /etc/os-release
NAME=CoreOS
ID=coreos
VERSION=681.0.0
VERSION_ID=681.0.0
BUILD_ID=
PRETTY_NAME="CoreOS 681.0.0"
ANSI_COLOR="1;32"
HOME_URL="https://coreos.com/"
BUG_REPORT_URL="https://github.com/coreos/bugs/issues"

docker -v
Docker version 1.6.2, build 7c8fca2-dirty

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
diogomonica/docker-bench-security

[WARN] 3.1 - Verify that docker.service file ownership is set to root:root
[WARN] * Wrong ownership for /usr/lib/systemd/system/docker.service

ls -l /usr/lib/systemd/system/docker.service
-rw-r--r-- 1 root root 489 May 14 00:35 /usr/lib/systemd/system/docker.service

Erroneously fails 2.2

This is on docker 1.10.2

I have --icc enabled on my system

# ps aux | grep 1610
root       1610  1.4  0.1 8692468 111684 ?      Ssl  13:07   6:05 /usr/bin/docker daemon -D -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock --icc=false -r=false --storage-driver=overlay

Unwrapping all of the bash calls:

# tr "\0" " " < /proc/1610/cmdline | sed         -e 's/\-\-debug/-D/g'         -e 's/\-\-host/-H/g'         -e 's/\-\-log-level/-l/g'         -e 's/\-\-version/-v/g' | sed         -e 's/\-\([DHlv]\)[= ]\([^- ][^ ]\)/-\1=\2/g' | tr ' ' "\n" |     grep "^--icc" | sed         -e 's/"//g'         -e "s/'//g" | tail -n1 | grep "false" >/dev/null 2>&1
root@ip-10-11-217-218:~# echo $?
0

Though somewhere along the way this line is failing: https://github.com/docker/docker-bench-security/blob/master/tests/2_docker_daemon_configuration.sh#L18

Proposal - Adding test for Docker socket access by container

Hi,

I wanted to add an additional test to DockerBench, which is not part of CIS 1.6, and wanted to check whether this is aligned with DockerBench purpose.

The test is for checking whether a container has access to host's Docker socket. This can be done by chekcing if container is executed with '-v /var/run/docker.sock:/var/run/docker.sock', or top level mount points that can provide such access.

Such containers can run any Docker management command on the host, which in my opnion should raise a security warning as part of the benchmark analysis.

Note that currently the CIS only suggest checking mounts for the following directories (section 5.6):
/, /boot, /dev, /etc, /lib, /proc, /sys, /usr

I'll be happy to provide a PR for such addition to the DockerBench. This test can be categorized as "Non CIS" in the DockerBench output.

Does not complain for engine on TCP with no authentication

I have opened my Docker host to the public internet without any TLS authentication:

$ ps aux | grep docker
root     55428  0.9  1.8 773376 65708 ?        Ssl  Jun11  52:40 /usr/bin/docker --daemon -H=unix:// -H=0.0.0.0:2375

and it didn't complain with any warnings or errors:

image

Not sure if that's a bug or by design, but I think -H=ip without --tls** must be a red flag of some sort. I know there could be firewalls or other ACLs on top of the VM hosting the Docker engine, therefore it might be the safe(?).

Another dangerous option could be triggering an external service to call into this docker instance to figure out if it's really open to the internet w/o any auth...

/var/lib/docker/devicemapper/mnt/d68c341169cec947dda3104e469511f132d31a757c5bc2ef947f349c0322ad08/rootfs/etc/hostname: read-only file system

CentOS 6.6:

docker version
Client version: 1.6.2
Client API version: 1.18
Go version (client): go1.4.2
Git commit (client): 7c8fca2
OS/Arch (client): linux/amd64
Server version: 1.6.2
Server API version: 1.18
Go version (server): go1.4.2
Git commit (server): 7c8fca2
OS/Arch (server): linux/amd64

Timestamp: 2015-05-31 09:03:30.895404758 +0200 CEST
Code: System error

Message: open /var/lib/docker/devicemapper/mnt/d68c341169cec947dda3104e469511f132d31a757c5bc2ef947f349c0322ad08/rootfs/etc/hostname: read-only file system

Frames:

0: setupRootfs
Package: github.com/docker/libcontainer

File: rootfs_linux.go@29

1: Init
Package: github.com/docker/libcontainer.(*linuxStandardInit)

File: standard_init_linux.go@52

2: StartInitialization
Package: github.com/docker/libcontainer.(*LinuxFactory)

File: factory_linux.go@223

3: initializer
Package: github.com/docker/docker/daemon/execdriver/native

File: init.go@35

4: Init
Package: github.com/docker/docker/pkg/reexec

File: reexec.go@26

5: main
Package: main

File: docker.go@29

6: main
Package: runtime

File: proc.go@63

7: goexit
Package: runtime
File: asm_amd64.s@2232
FATA[0005] Error response from daemon: Cannot start container d68c341169cec947dda3104e469511f132d31a757c5bc2ef947f349c0322ad08: [8] System error: open /var/lib/docker/devicemapper/mnt/d68c341169cec947dda3104e469511f132d31a757c5bc2ef947f349c0322ad08/rootfs/etc/hostname: read-only file system

Docker Daemon Config tests on CoreOS when using early-docker

I'm running Kubernetes on CoreOS and using early-docker to start flannel (network overlay for k8s) before starting docker.

The 'Docker Daemon Config' test searches for the oldest running docker process (https://github.com/docker/docker-bench-security/blob/master/helper_lib.sh#L44) and picks up early-docker instead of docker and ends up running config tests on it. Any reason why we look for oldest running docker process instead of newest?

command line options tests check for specific quotation of options

Connected to #97, #98: A specific use of quotation marks of the command line options is checked for:

#2.3
check_2_3="2.3  - Set the logging level"
get_command_line_args docker | grep "log-level=\"debug\"" >/dev/null 2>&1

This misses the following cases of spacing and quotation, all of which enable the debug mode:

  • --log-level=debug
  • --log-level debug

Conflict of tool and goal?

We definitely need something like this tool to ensure Docker deployment is secure. However, it seems to me that we might have a conflict of the tool and goal here. The tool runs with lots of privileges, but a reasonably secured deployment of Docker daemon will prohibit that, e.g. host network.

For an example, when I turn on the user namespace in Docker 1.10, I can not run the tool as a container

docker run -it --net host --pid host --cap-add audit_control     -v /var/lib:/var/lib     -v /var/run/docker.sock:/var/run/docker.sock     -v /usr/lib/systemd:/usr/lib/systemd     -v /etc:/etc --label docker_bench_security     docker/docker-bench-security
docker: Error response from daemon: Cannot share the host or a container's network namespace when user namespaces are enabled..
See 'docker run --help'.

Can this tool run outside Docker, i.e. not as a container?

Tests 2.2 Set the logging level

From the Docker doc[1] there is more than info and debug log levels.
The current implementation[2] however doesn't seems to comply to the CIS benchmark[3] documentation, where CIS suggests to pass only if log-level is set to info OR non presence.

Current implementation for 2.2 is checking:

get_docker_effective_command_line_args '-l' | grep "debug" >/dev/null 2>&1

Is there a reason why the test is only checking if log level is set to debug, instead of CIS benchmark's advice?

[1] https://docs.docker.com/registry/configuration/#loglevel
[2] https://github.com/docker/docker-bench-security/blob/master/tests/2_docker_daemon_configuration.sh#L17
[3] https://benchmarks.cisecurity.org/tools2/docker/CIS_Docker_1.12.0_Benchmark_v1.0.0.pdf

Dockerfile.centos "misses" FROM

If I use distros/Dockerfile.centos instead of the default one docker build yields this message:

Sending build context to Docker daemon 264.2 kB
Sending build context to Docker daemon
Step 0 : MAINTAINER [email protected]
Please provide a source image with `from` prior to commit

Reordering 0: MAINTAINER <-> 1: FROM solves this issue.

Docker 1.7.1

Edit: I tried to create a pull request but I fail at the signing requirement, sorry

No -U option in BusyBox

362c62a replaced the ps_ variables (2085e1d) with pgrep -U root -u root -lf but BusyBox pgrep does not have the -U option:

2.7  - Do not use the aufs storage driver
invalid option -- U
BusyBox v1.22.1 (2015-03-20 11:09:37 GMT) multi-call binary.

Usage: pgrep [-flnovx] [-s SID|-P PPID|PATTERN]

Display process(es) selected by regex PATTERN

        -l      Show command name too
        -f      Match against entire command line
        -n      Show the newest process only
        -o      Show the oldest process only
        -v      Negate the match
        -x      Match whole name (not substring)
        -s      Match session ID (0 for current)
        -P      Match parent process ID

ESC[1;32m[PASS]ESC[0m 2.8  - Do not bind Docker to another IP/Port or a Unix socket
invalid option -- U
BusyBox v1.22.1 (2015-03-20 11:09:37 GMT) multi-call binary.

Usage: pgrep [-flnovx] [-s SID|-P PPID|PATTERN]

Display process(es) selected by regex PATTERN

        -l      Show command name too
        -f      Match against entire command line
        -n      Show the newest process only
        -o      Show the oldest process only
        -v      Negate the match
        -x      Match whole name (not substring)
        -s      Match session ID (0 for current)
        -P      Match parent process ID

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.