diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..36d2d2f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,48 @@ +# Contributing to Docker Bench for Security + +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. + +Otherwise, go read +[Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md). + +### 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 + +#### 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 . +``` + +Or you can simply run the shell script locally: + +```sh +✗ 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 tests are split in 6 different files: + +```sh +✗ docker-bench-security git:(master) ✗ tree 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 +``` + +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. + +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. diff --git a/Dockerfile b/Dockerfile index 5b948bc..a552ef4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM gliderlabs/alpine:3.1 +FROM alpine:3.1 RUN apk --update add docker diff --git a/README.md b/README.md index eb5e117..74de8e8 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ docker run -it --net host --pid host -v /var/lib:/var/lib \ Also, this script can also be simply run from your base host by running: ```sh -git clone https://github.com/diogomonica/docker-bench-security.git +git clone https://github.com/docker/docker-bench-security.git cd docker-bench-security sh docker-bench-security.sh ``` diff --git a/docker-bench-security.sh b/docker-bench-security.sh old mode 100644 new mode 100755 diff --git a/tests/2_docker_daemon_configuration.sh b/tests/2_docker_daemon_configuration.sh index 8561f52..ed94926 100644 --- a/tests/2_docker_daemon_configuration.sh +++ b/tests/2_docker_daemon_configuration.sh @@ -5,7 +5,7 @@ info "2 - Docker Daemon Configuration" # 2.1 check_2_1="2.1 - Do not use lxc execution driver" -pgrep -U root -u root -lf docker | grep lxc >/dev/null 2>&1 +pgrep -lf docker | grep lxc >/dev/null 2>&1 if [ $? -eq 0 ]; then warn "$check_2_1" else @@ -14,7 +14,7 @@ fi # 2.2 check_2_2="2.2 - Restrict network traffic between containers" -pgrep -U root -u root -lf docker | grep "icc=false" >/dev/null 2>&1 +pgrep -lf docker | grep "icc=false" >/dev/null 2>&1 if [ $? -eq 0 ]; then pass "$check_2_2" else @@ -23,7 +23,7 @@ fi # 2.3 check_2_3="2.3 - Set the logging level" -pgrep -U root -u root -lf docker | grep "log-level=\"debug\"" >/dev/null 2>&1 +pgrep -lf docker | grep "log-level=\"debug\"" >/dev/null 2>&1 if [ $? -eq 0 ]; then warn "$check_2_3" else @@ -32,7 +32,7 @@ fi # 2.4 check_2_4="2.4 - Allow Docker to make changes to iptables" -pgrep -U root -u root -lf docker | grep "iptables=false" >/dev/null 2>&1 +pgrep -lf docker | grep "iptables=false" >/dev/null 2>&1 if [ $? -eq 0 ]; then warn "$check_2_4" else @@ -41,7 +41,7 @@ fi # 2.5 check_2_5="2.5 - Do not use insecure registries" -pgrep -U root -u root -lf docker | grep "insecure-registry" >/dev/null 2>&1 +pgrep -lf docker | grep "insecure-registry" >/dev/null 2>&1 if [ $? -eq 0 ]; then warn "$check_2_5" else @@ -50,7 +50,7 @@ fi # 2.6 check_2_6="2.6 - Setup a local registry mirror" -pgrep -U root -u root -lf docker | grep "registry-mirror" >/dev/null 2>&1 +pgrep -lf docker | grep "registry-mirror" >/dev/null 2>&1 if [ $? -eq 0 ]; then pass "$check_2_6" else @@ -69,7 +69,7 @@ fi # 2.8 check_2_8="2.8 - Do not bind Docker to another IP/Port or a Unix socket" -pgrep -U root -u root -lf docker | grep "\-H" >/dev/null 2>&1 +pgrep -lf docker | grep "\-H" >/dev/null 2>&1 if [ $? -eq 0 ]; then info "$check_2_8" info " * Docker daemon running with -H" @@ -79,9 +79,9 @@ fi # 2.9 check_2_9="2.9 - Configure TLS authentication for Docker daemon" -pgrep -U root -u root -lf docker | grep "tcp://" >/dev/null 2>&1 +pgrep -lf docker | grep "tcp://" >/dev/null 2>&1 if [ $? -eq 0 ]; then - pgrep -U root -u root -lf docker | grep "tlsverify" | grep "tlskey" >/dev/null 2>&1 + 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" @@ -96,7 +96,7 @@ fi # 2.10 check_2_10="2.10 - Set default ulimit as appropriate" -pgrep -U root -u root -lf docker | grep "default-ulimit" >/dev/null 2>&1 +pgrep -lf docker | grep "default-ulimit" >/dev/null 2>&1 if [ $? -eq 0 ]; then pass "$check_2_10" else diff --git a/tests/5_container_runtime.sh b/tests/5_container_runtime.sh index 11e14df..35c41b5 100644 --- a/tests/5_container_runtime.sh +++ b/tests/5_container_runtime.sh @@ -201,18 +201,21 @@ else fail=0 for c in $containers; do - port=$(docker port "$c" | awk '{print $1}' | cut -d '/' -f1) + ports=$(docker port "$c" | awk '{print $1}' | cut -d '/' -f1) - if [ ! -z "$port" ] && [ "$port" -lt 1025 ]; then - # If it's the first container, fail the test - if [ $fail -eq 0 ]; then - warn "$check_5_8" - warn " * Privileged Port in use: $port in $c" - fail=1 - else - warn " * Privileged Port in use: $port in $c" + # iterate through port range (line delimited) + for port in $ports; do + if [ ! -z "$port" ] && [ "0$port" -lt 1025 ]; then + # If it's the first container, fail the test + if [ $fail -eq 0 ]; then + warn "$check_5_8" + warn " * Privileged Port in use: $port in $c" + fail=1 + else + warn " * Privileged Port in use: $port in $c" + fi fi - fi + done done # We went through all the containers and found no privileged ports if [ $fail -eq 0 ]; then @@ -316,17 +319,18 @@ else fail=0 for c in $containers; do - ip=$(docker port "$c" | awk '{print $3}' | cut -d ':' -f1) - if [ "$ip" = "0.0.0.0" ]; then - # If it's the first container, fail the test - if [ $fail -eq 0 ]; then - warn "$check_5_14" - warn " * Port being bound to wildcard IP: $ip in $c" - fail=1 - else - warn " * Port being bound to wildcard IP: $ip in $c" + for ip in $(docker port "$c" | awk '{print $3}' | cut -d ':' -f1); do + if [ "$ip" = "0.0.0.0" ]; then + # If it's the first container, fail the test + if [ $fail -eq 0 ]; then + warn "$check_5_14" + warn " * Port being bound to wildcard IP: $ip in $c" + fail=1 + else + warn " * Port being bound to wildcard IP: $ip in $c" + fi fi - fi + done done # We went through all the containers and found no ports bound to 0.0.0.0 if [ $fail -eq 0 ]; then diff --git a/tests/6_docker_security_operations.sh b/tests/6_docker_security_operations.sh index f5b1f01..3165986 100644 --- a/tests/6_docker_security_operations.sh +++ b/tests/6_docker_security_operations.sh @@ -40,8 +40,8 @@ images=$(docker images -q | wc -l | awk '{print $1}') active_images=0 for c in $(docker inspect -f "{{.Image}}" $(docker ps -qa)); do - if [[ $(docker images --no-trunc -a | grep $c) ]]; then - ((active_images++)) + if docker images --no-trunc -a | grep $c > /dev/null ; then + active_images=$(( active_images += 1 )) fi done @@ -53,7 +53,7 @@ else info " * There are currently: $images images" fi -if [[ "$active_images" -lt "$((images / 2))" ]]; then +if [ "$active_images" -lt "$((images / 2))" ]; then warn " * Only $active_images out of $images are in use" fi