最近 Docker 関連のセキュリティツールを調査する機会があり,今回は「Docker Bench for Security」を試したログを残しておく.「Docker Bench for Security」は Docker から公式に提供されているセキュリティ診断ツールで,具体的には「CIS Docker Community Edition Benchmark v1.1.0」をサポートしている.
コンテナ実行
「Docker Bench for Security」を実行する方法は複数ある.1番簡単なのはコンテナを実行する方法で,Docker イメージ「docker/docker-bench-security」が Docker Hub に公開されている.
注意点としては,コンテナから CAP_AUDIT_CONTROL
ケーパビリティなどの特権を許可する必要があることと,診断対象となるディレクトリをコンテナから参照できるようにする必要がある.GitHub に載っているコマンドはあくまでサンプルで,systemd を指定しているため,CentOS 7 系を前提にしているように思う.
$ docker run -it --net host --pid host --userns host --cap-add audit_control \ -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
シェル実行
「Docker Bench for Security」のリポジトリを clone して docker-bench-security.sh
を実行すると,シェルですぐに診断ができる.診断項目を include / exclude するオプションもあり,柔軟に使える.
$ ./docker-bench-security.sh $ ./docker-bench-security.sh -c check_1_1 $ ./docker-bench-security.sh -c check_1_1,check_1_2 $ ./docker-bench-security.sh -h usage: docker-bench-security.sh [options] -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 name to check -x EXCLUDE optional Comma delimited list of patterns within a container name to exclude from check -t TARGET optional Comma delimited list of images name to check
ちなみに docker-bench-security.sh
の内部では ss
コマンドを使っているため,Mac で Docker for Mac を診断しようとすると,以下のエラーが出る.とは言え,Mac で診断をするシチュエーションはあまりなさそう.
$ ./docker-bench-security.sh
ss command not found.
診断項目
GitHub Wiki などに診断項目の一覧がまとまってなく,自分用に整理をした.診断項目の実装は GitHub で tests
ディレクトリ直下のシェルを読めばわかる.基本的にはシェル芸で実装されている.
- 1 - Host Configuration
- 1.1 - Ensure a separate partition for containers has been created
- 1.2 - Ensure the container host has been Hardened
- 1.3 - Ensure Docker is up to date
- 1.4 - Ensure only trusted users are allowed to control Docker daemon
- 1.5 - Ensure auditing is configured for the Docker daemon
- 1.6 - Ensure auditing is configured for Docker files and directories - /var/lib/docker
- 1.7 - Ensure auditing is configured for Docker files and directories - /etc/docker
- 1.8 - Ensure auditing is configured for Docker files and directories - docker.service
- 1.9 - Ensure auditing is configured for Docker files and directories - docker.socket
- 1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker
- 1.11 - Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json
- 1.12 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-containerd
- 1.13 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-runc
- 2 - Docker daemon configuration
- 2.1 - Ensure network traffic is restricted between containers on the default bridge
- 2.2 - Ensure the logging level is set to 'info'
- 2.3 - Ensure Docker is allowed to make changes to iptables
- 2.4 - Ensure insecure registries are not used
- 2.5 - Ensure aufs storage driver is not used
- 2.6 - Ensure TLS authentication for Docker daemon is configured
- 2.7 - Ensure the default ulimit is configured appropriately
- 2.8 - Enable user namespace support
- 2.9 - Ensure the default cgroup usage has been confirmed
- 2.10 - Ensure base device size is not changed until needed
- 2.11 - Ensure that authorization for Docker client commands is enabled
- 2.12 - Ensure centralized and remote logging is configured
- 2.13 - Ensure operations on legacy registry (v1) are Disabled (Deprecated)
- 2.14 - Ensure live restore is Enabled
- 2.15 - Ensure Userland Proxy is Disabled
- 2.16 - Ensure daemon-wide custom seccomp profile is applied, if needed
- 2.17 - Ensure experimental features are avoided in production
- 2.18 - Ensure containers are restricted from acquiring new privileges
- 3 - Docker daemon configuration files
- 3.1 - Ensure that docker.service file ownership is set to root:root
- 3.2 - Ensure that docker.service file permissions are set to 644 or more restrictive
- 3.3 - Ensure that docker.socket file ownership is set to root:root
- 3.4 - Ensure that docker.socket file permissions are set to 644 or more restrictive
- 3.5 - Ensure that /etc/docker directory ownership is set to root:root
- 3.6 - Ensure that /etc/docker directory permissions are set to 755 or more restrictive
- 3.7 - Ensure that registry certificate file ownership is set to root:root
- 3.8 - Ensure that registry certificate file permissions are set to 444 or more restrictive
- 3.9 - Ensure that TLS CA certificate file ownership is set to root:root
- 3.10 - Ensure that TLS CA certificate file permissions are set to 444 or more restrictive
- 3.11 - Ensure that Docker server certificate file ownership is set to root:root
- 3.12 - Ensure that Docker server certificate file permissions are set to 444 or more restrictive
- 3.13 - Ensure that Docker server certificate key file ownership is set to root:root
- 3.14 - Ensure that Docker server certificate key file permissions are set to 400
- 3.15 - Ensure that Docker socket file ownership is set to root:docker
- 3.16 - Ensure that Docker socket file permissions are set to 660 or more restrictive
- 3.17 - Ensure that daemon.json file ownership is set to root:root
- 3.18 - Ensure that daemon.json file permissions are set to 644 or more restrictive
- 3.19 - Ensure that /etc/default/docker file ownership is set to root:root
- 3.20 - Ensure that /etc/default/docker file permissions are set to 644 or more restrictive
- 4 - Container Images and Build File
- 4.1 - Ensure a user for the container has been created
- 4.2 - Ensure that containers use trusted base images
- 4.3 - Ensure unnecessary packages are not installed in the container
- 4.4 - Ensure images are scanned and rebuilt to include security patches
- 4.5 - Ensure Content trust for Docker is Enabled
- 4.6 - Ensure HEALTHCHECK instructions have been added to the container image
- 4.7 - Ensure update instructions are not use alone in the Dockerfile
- 4.8 - Ensure setuid and setgid permissions are removed in the images
- 4.9 - Ensure COPY is used instead of ADD in Dockerfile
- 4.10 - Ensure secrets are not stored in Dockerfiles
- 4.11 - Ensure verified packages are only Installed
- 5 - Container Runtime
- 6 - Docker Security Operations
- 6.1 - Avoid image sprawl
- 6.2 - Avoid container sprawl
- 7 - Docker Swarm Configuration
- 7.1 - Ensure swarm mode is not Enabled, if not needed
- 7.2 - Ensure the minimum number of manager nodes have been created in a swarm (Swarm mode not enabled)
- 7.3 - Ensure swarm services are binded to a specific host interface (Swarm mode not enabled)
- 7.4 - Ensure data exchanged between containers are encrypted on different nodes on the overlay network
- 7.5 - Ensure Docker's secret management commands are used for managing secrets in a Swarm cluster (Swarm mode not enabled)
- 7.6 - Ensure swarm manager is run in auto-lock mode (Swarm mode not enabled)
- 7.7 - Ensure swarm manager auto-lock key is rotated periodically (Swarm mode not enabled)
- 7.8 - Ensure node certificates are rotated as appropriate (Swarm mode not enabled)
- 7.9 - Ensure CA certificates are rotated as appropriate (Swarm mode not enabled)
- 7.10 - Ensure management plane traffic has been separated from data plane traffic (Swarm mode not enabled)
改善 : 1 - Host Configuration
今回は Amazon Linux 2 を検証用ホストとして,Docker 18.06.1-ce のデフォルト状態に対して「Docker Bench for Security (1 - Host Configuration)」を実行した.すると,計7項目が WARN になった.今回は「auditd」 で Docker 関連の監査ログを取れるようにする.
$ ./docker-bench-security.sh -c check_1,check_1_1,check_1_2,check_1_3,check_1_4,check_1_5,check_1_6,check_1_7,check_1_8,check_1_9,check_1_10,check_1_11,check_1_12,check_1_13 (中略) [INFO] 1 - Host Configuration [WARN] 1.1 - Ensure a separate partition for containers has been created [NOTE] 1.2 - Ensure the container host has been Hardened [INFO] 1.3 - Ensure Docker is up to date [INFO] * Using 18.06.1, verify is it up to date as deemed necessary [INFO] * Your operating system vendor may provide support and security maintenance for Docker [INFO] 1.4 - Ensure only trusted users are allowed to control Docker daemon [INFO] * docker:x:993: [WARN] 1.5 - Ensure auditing is configured for the Docker daemon [WARN] 1.6 - Ensure auditing is configured for Docker files and directories - /var/lib/docker [WARN] 1.7 - Ensure auditing is configured for Docker files and directories - /etc/docker [WARN] 1.8 - Ensure auditing is configured for Docker files and directories - docker.service [INFO] 1.9 - Ensure auditing is configured for Docker files and directories - docker.socket [INFO] * File not found [INFO] 1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker [INFO] * File not found [INFO] 1.11 - Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json [INFO] * File not found [WARN] 1.12 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-containerd [WARN] 1.13 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-runc [INFO] Checks: 13 [INFO] Score: -7
以下の設定になるように /etc/audit/rules.d/audit.rules
を修正する.
$ auditctl -l -w /usr/bin/docker -p wa -w /var/lib/docker -p wa -w /etc/docker -p wa -w /usr/lib/systemd/system/docker.service -p wa -w /lib/systemd/system/docker.socket -p wa -w /usr/bin/docker-containerd -p wa -w /usr/bin/docker-runc -p wa
すると,WARN を残り1個まで改善できた.項目 1.1 は docker info -f '{{ .DockerRootDir }}'
で取得できるディレクトリを別ファイルシステムにすると改善できる.今回は実施しなかった.
$ ./docker-bench-security.sh -c check_1,check_1_1,check_1_2,check_1_3,check_1_4,check_1_5,check_1_6,check_1_7,check_1_8,check_1_9,check_1_10,check_1_11,check_1_12,check_1_13 (中略) [INFO] 1 - Host Configuration [WARN] 1.1 - Ensure a separate partition for containers has been created [NOTE] 1.2 - Ensure the container host has been Hardened [INFO] 1.3 - Ensure Docker is up to date [INFO] * Using 18.06.1, verify is it up to date as deemed necessary [INFO] * Your operating system vendor may provide support and security maintenance for Docker [INFO] 1.4 - Ensure only trusted users are allowed to control Docker daemon [INFO] * docker:x:993: [PASS] 1.5 - Ensure auditing is configured for the Docker daemon [PASS] 1.6 - Ensure auditing is configured for Docker files and directories - /var/lib/docker [PASS] 1.7 - Ensure auditing is configured for Docker files and directories - /etc/docker [PASS] 1.8 - Ensure auditing is configured for Docker files and directories - docker.service [INFO] 1.9 - Ensure auditing is configured for Docker files and directories - docker.socket [INFO] * File not found [INFO] 1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker [INFO] * File not found [INFO] 1.11 - Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json [INFO] * File not found [PASS] 1.12 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-containerd [PASS] 1.13 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-runc [INFO] Checks: 13 [INFO] Score: 5
改善 : 4 - Container Images and Build File
次に「Docker Bench for Security (4 - Container Images and Build File)」を実行した.すると,計1項目が WARN になった.
$ ./docker-bench-security.sh -c 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 (中略) [INFO] 4.1 - Ensure a user for the container has been created [INFO] * No containers running [NOTE] 4.2 - Ensure that containers use trusted base images [NOTE] 4.3 - Ensure unnecessary packages are not installed in the container [NOTE] 4.4 - Ensure images are scanned and rebuilt to include security patches [WARN] 4.5 - Ensure Content trust for Docker is Enabled [PASS] 4.6 - Ensure HEALTHCHECK instructions have been added to the container image [PASS] 4.7 - Ensure update instructions are not use alone in the Dockerfile [NOTE] 4.8 - Ensure setuid and setgid permissions are removed in the images [PASS] 4.9 - Ensure COPY is used instead of ADD in Dockerfile [NOTE] 4.10 - Ensure secrets are not stored in Dockerfiles [NOTE] 4.11 - Ensure verified packages are only Installed [INFO] Checks: 11 [INFO] Score: 1
項目 4.5 は「Docker Content Trust (DCT)」を有効化すると改善できる.
今回は環境変数 DOCKER_CONTENT_TRUST
を設定して診断をすると,改善できた.
$ export DOCKER_CONTENT_TRUST=1 $ ./docker-bench-security.sh -c 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 (中略) [INFO] 4.1 - Ensure a user for the container has been created [INFO] * No containers running [NOTE] 4.2 - Ensure that containers use trusted base images [NOTE] 4.3 - Ensure unnecessary packages are not installed in the container [NOTE] 4.4 - Ensure images are scanned and rebuilt to include security patches [PASS] 4.5 - Ensure Content trust for Docker is Enabled [PASS] 4.6 - Ensure HEALTHCHECK instructions have been added to the container image [PASS] 4.7 - Ensure update instructions are not use alone in the Dockerfile [NOTE] 4.8 - Ensure setuid and setgid permissions are removed in the images [PASS] 4.9 - Ensure COPY is used instead of ADD in Dockerfile [NOTE] 4.10 - Ensure secrets are not stored in Dockerfiles [NOTE] 4.11 - Ensure verified packages are only Installed [INFO] Checks: 11 [INFO] Score: 3
プルリクエストを出した 🎉
docker-bench-security.sh
の実装を読みながら README.md
に書いてあるオプション一覧を確認したところ,今月に追加されたオプション -t
が README.md
に反映されていないことに気付いた.さっそく README.md
を修正し,プルリクエストを出して,すぐに merge してもらえた!
なお Docker (Moby) 関連のリポジトリにプルリクエストを出す場合,コミットメッセージに署名を追加する必要がある.詳しくは CONTRIBUTING.md
に書いてある.覚えておこう!
まとめ
- 「CIS Docker Community Edition Benchmark v1.1.0」をサポートしている診断ツール「Docker Bench for Security」を試した
- コンテナを実行する方法とシェルを実行する方法がある
- 例えば auditd を有効化するなど,診断結果を使って改善できる
README.md
を修正するプルリクエストを出して merge してもらえた!