Docker Bench for Securityを触った(1. Dockerホストの設定編)

Dockerの公式ドキュメントにDockerのセキュリティについて述べられたものがあります。

[UNDERSTANDING DOCKER SECURITY AND BEST PRACTICES](https://blog.docker.com/2015/05/understanding-docker-security-and-best-practices/)

これを自動的にチェックするためのツールとして提供されているのが、
**Docker Bench for Security**です。

[docker/docker-bench-security](https://github.com/docker/docker-bench-security)

これを活用して、よりセキュア(と思われる)なコンテナ実行環境を実現することにトライしてみます。

# 前提

- Ubuntu 16.04
- docker 17.12.1-ce

# Docker Bench for Securityの実行

Githubのリポジトリでは最初にDockerイメージを使った実行方法が説明されています。
しかし、これではdockerの仕組み上一部の試験がどうしてもうまく行かない部分が
ある(具体的には1.5-1.13の監査系の一部)ので、
dockerイメージを利用するのではなく、スクリプトを直接実行する方式を活用します。

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

# Docker Bench for Securityの実行結果

単純にDockerをインストールした直後の状態を例示します。

```text
$ sudo sh docker-bench-security.sh 
# ------------------------------------------------------------------------------
# Docker Bench for Security v1.3.4
#
# Docker, Inc. (c) 2015-
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Inspired by the CIS Docker Community Edition Benchmark v1.1.0.
# ------------------------------------------------------------------------------

Initializing 2018年  7月 31日 火曜日 00:33:03 JST


[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 17.12.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:999:fujiwara
[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
[WARN] 1.9  - Ensure auditing is configured for Docker files and directories - docker.socket
[WARN] 1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker
[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] 2 - Docker daemon configuration
[WARN] 2.1  - Ensure network traffic is restricted between containers on the default bridge
[PASS] 2.2  - Ensure the logging level is set to 'info'
[PASS] 2.3  - Ensure Docker is allowed to make changes to iptables
[PASS] 2.4  - Ensure insecure registries are not used
[PASS] 2.5  - Ensure aufs storage driver is not used
[INFO] 2.6  - Ensure TLS authentication for Docker daemon is configured
[INFO]      * Docker daemon not listening on TCP
[INFO] 2.7  - Ensure the default ulimit is configured appropriately
[INFO]      * Default ulimit doesn't appear to be set
[WARN] 2.8  - Enable user namespace support
[PASS] 2.9  - Ensure the default cgroup usage has been confirmed
[PASS] 2.10 - Ensure base device size is not changed until needed
[WARN] 2.11 - Ensure that authorization for Docker client commands is enabled
[WARN] 2.12 - Ensure centralized and remote logging is configured
[INFO] 2.13 - Ensure operations on legacy registry (v1) are Disabled (Deprecated)
[WARN] 2.14 - Ensure live restore is Enabled
[WARN] 2.15 - Ensure Userland Proxy is Disabled
[PASS] 2.16 - Ensure daemon-wide custom seccomp profile is applied, if needed
[PASS] 2.17 - Ensure experimental features are avoided in production
[WARN] 2.18 - Ensure containers are restricted from acquiring new privileges


[INFO] 3 - Docker daemon configuration files
[PASS] 3.1  - Ensure that docker.service file ownership is set to root:root
[PASS] 3.2  - Ensure that docker.service file permissions are set to 644 or more restrictive
[PASS] 3.3  - Ensure that docker.socket file ownership is set to root:root
[PASS] 3.4  - Ensure that docker.socket file permissions are set to 644 or more restrictive
[PASS] 3.5  - Ensure that /etc/docker directory ownership is set to root:root
[PASS] 3.6  - Ensure that /etc/docker directory permissions are set to 755 or more restrictive
[INFO] 3.7  - Ensure that registry certificate file ownership is set to root:root
[INFO]      * Directory not found
[INFO] 3.8  - Ensure that registry certificate file permissions are set to 444 or more restrictive
[INFO]      * Directory not found
[INFO] 3.9  - Ensure that TLS CA certificate file ownership is set to root:root
[INFO]      * No TLS CA certificate found
[INFO] 3.10 - Ensure that TLS CA certificate file permissions are set to 444 or more restrictive
[INFO]      * No TLS CA certificate found
[INFO] 3.11 - Ensure that Docker server certificate file ownership is set to root:root
[INFO]      * No TLS Server certificate found
[INFO] 3.12 - Ensure that Docker server certificate file permissions are set to 444 or more restrictive
[INFO]      * No TLS Server certificate found
[INFO] 3.13 - Ensure that Docker server certificate key file ownership is set to root:root
[INFO]      * No TLS Key found
[INFO] 3.14 - Ensure that Docker server certificate key file permissions are set to 400
[INFO]      * No TLS Key found
[PASS] 3.15 - Ensure that Docker socket file ownership is set to root:docker
[PASS] 3.16 - Ensure that Docker socket file permissions are set to 660 or more restrictive
[INFO] 3.17 - Ensure that daemon.json file ownership is set to root:root
[INFO]      * File not found
[INFO] 3.18 - Ensure that daemon.json file permissions are set to 644 or more restrictive
[INFO]      * File not found
[PASS] 3.19 - Ensure that /etc/default/docker file ownership is set to root:root
[PASS] 3.20 - Ensure that /etc/default/docker file permissions are set to 644 or more restrictive


[INFO] 4 - Container Images and Build File
[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
[INFO] 4.9  - Ensure COPY is used instead of ADD in Dockerfile
[INFO]      * ADD in image history: [docker/docker-bench-security:latest]
[NOTE] 4.10 - Ensure secrets are not stored in Dockerfiles
[NOTE] 4.11 - Ensure verified packages are only Installed


[INFO] 5  - Container Runtime
[INFO]      * No containers running, skipping Section 5


[INFO] 6 - Docker Security Operations
[INFO] 6.1  - Avoid image sprawl
[INFO]      * There are currently: 1 images
[INFO] 6.2  - Avoid container sprawl
[INFO]      * There are currently a total of 1 containers, with 0 of them currently running


[INFO] 7 - Docker Swarm Configuration
[PASS] 7.1  - Ensure swarm mode is not Enabled, if not needed
[PASS] 7.2  - Ensure the minimum number of manager nodes have been created in a swarm (Swarm mode not enabled)
[PASS] 7.3  - Ensure swarm services are binded to a specific host interface (Swarm mode not enabled)
[PASS] 7.5  - Ensure Docker's secret management commands are used for managing secrets in a Swarm cluster (Swarm mode not enabled)
[PASS] 7.6  - Ensure swarm manager is run in auto-lock mode (Swarm mode not enabled)
[PASS] 7.7  - Ensure swarm manager auto-lock key is rotated periodically (Swarm mode not enabled)
[PASS] 7.8  - Ensure node certificates are rotated as appropriate (Swarm mode not enabled)
[PASS] 7.9  - Ensure CA certificates are rotated as appropriate (Swarm mode not enabled)
[PASS] 7.10 - Ensure management plane traffic has been separated from data plane traffic (Swarm mode not enabled)

[INFO] Checks: 73
[INFO] Score: 11
```

まあ、ぼろぼろなので徐々に改善していくことにします。
今回は`1 - Host Configuration`を範囲とします。
更に、1.2 ~ 1.4は`ここに注意してくださいね。`以上の意味合いは無いのでここもスキップします。

## 1.1 - Ensure a separete partition for containers has been created

コンテナのために分離されたパーティションを用意せよとの警告。
具体的には、dockerが利用するデータ領域(デフォルトでは`/var/lib/docker`配下)
に専用のディスクパーティションを準備することで対応します。

```bash
$ sudo systemctl stop docker
```

```bash
$ sudo fdisk /dev/sdb
Welcome to fdisk (util-linux 2.27.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

コマンド (m でヘルプ): g

コマンド (m でヘルプ): n
パーティション番号 (1-128, default 1): 1
First sector (2048-209715166, default 2048): 
Last sector, +sectors or +size{K,M,G,T,P} (2048-209715166, default 209715166): 

Created a new partition 1 of type 'Linux filesystem' and of size 100 GiB.

コマンド (m でヘルプ): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
```


```bash
$ sudo mkfs -t ext4 /dev/sdb1
mke2fs 1.42.13 (17-May-2015)
Creating filesystem with 26214139 4k blocks and 6553600 inodes
Filesystem UUID: 1f2c0bb1-967f-4d12-b304-e7c06f6de806
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
	4096000, 7962624, 11239424, 20480000, 23887872

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
```
`ext4`でフォーマットされたパーティション(dev/sdb1)が作成できたので、これを`/var/lib/docker`配下にマウントする。

`/etc/fstab`を修正して以下の内容を追加する。

```
/dev/sdb1	/var/lib/docker	ext4	defaults	0	0
```

```bash
$ sudo mount -a
$ df -h
Filesystem                         Size  Used Avail Use% Mounted on
〜〜〜 中略 〜〜〜 
/dev/sdb1                           99G   60M   94G   1% /var/lib/docker
```

```
$ sudo systemctl start docker
```

## 1.5 - 1.13 監査系の機能のチェック

ここでは、`INFO`レベルのものを含むがまとめて記述しておきます。

基本的には、**各種コマンドの実行やら、設定ファイルの変更を監査ログに吐くようにしておけよ**以上の意味合いはないです。

Dockerデーモンに対しての監査が行われてることを確認します。
ここでは監査の仕組みとして`auditd`を利用しているので、この設定を追加していきます。

`auditd`のインストールはUbuntuでは以下で行います。
auditdの設定内容は`/etc/audit/audit.rules`に書き込むことで対応します。
(auditctlコマンドでも可能ですが、永続化されないのでファイルに書き込みます)

```bash
$ sudo apt-get update
$ sudo apt-get install -y auditd
```

対象となる認証系機能は以下の通り。

- 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

### 1.5  - Ensure auditing is configured for the Docker daemon

Dockerのデーモンを監査対象とします。(※)

※Dockerのデーモンなら`dockerd`のはずですがツールでは、
コード上では対象が`docker`になっているので一旦はこれで良しとします。(継続調査が必要？)

```bash
$ echo "-w /usr/bin/docker -p wa" | sudo tee -a /etc/audit/audit.rules
```

### 1.6  - Ensure auditing is configured for Docker files and directories - /var/lib/docker

Dockerのルートディレクトリである`/var/lib/docker`ディレクトリ配下を監査対象とします。

```bash
$ echo "-w /var/lib/docker -p wa" | sudo tee -a /etc/audit/audit.rules
```


### 1.7  - Ensure auditing is configured for Docker files and directories - /etc/docker

`/etc/docker`ディレクトリ(dockerdの設定ファイルを格納したディレクトリ)配下を
監査対象とします。


```bash
echo "-w /etc/docker -p wa" | sudo tee -a /etc/audit/audit.rules
```

### 1.8  - Ensure auditing is configured for Docker files and directories - docker.service

dockerデーモンの起動設定諸々が記述されている
`/lib/systemd/system/docker.service`の監査を追加します。

```bash
echo "-w /lib/systemd/system/docker.service -p wa" | sudo tee -a /etc/audit/audit.rules
```


### 1.9  - Ensure auditing is configured for Docker files and directories - docker.socket

dockerのunix domainソケット周りの設定が書き込まれている
`/lib/systemd/system/docker.socket`の監査を追加します。

```bash
$ echo "-w /lib/systemd/system/docker.socket -p wa" | sudo tee -a /etc/audit/audit.rules
```

### 1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker

ファイルの中身を見るとわかるとおり、Ubuntuで配布されているdockerについては
このファイルはデフォルトでは意味をなしませんが一応監査対象とします。

```bash
$ echo "-w /etc/default/docker -p wa" | sudo tee -a /etc/audit/audit.rules
```

### 1.11 - Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json

dockerdの起動時の各種オプションについて設定を記述する`/etc/docker/daemon.json`ファイルを監査対象とします。

```bash
$ echo "-w /etc/docker/daemon.json -p wa" | sudo tee -a /etc/audit/audit.rules
```

### 1.12 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-containerd

普通に使うぶんには直接いじることはあまりなさそうですが含めます。

```bash
$ echo "-w /usr/bin/docker-containerd -p wa" | sudo tee -a /etc/audit/audit.rules
```

### 1.13 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-runc

docker-containerdと同じく普通に使うぶんには直接いじることはあまりなさそうですがも含めます。

```bash
$ echo "-w /usr/bin/docker-runc -p wa" | sudo tee -a /etc/audit/audit.rules
```

# まとめ

ここまでやると、`1 - Host Configuration`の部分は設定実施前後でこのように違いが出ます。

```text:設定実施前
[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 17.12.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:999:fujiwara
[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
[WARN] 1.9  - Ensure auditing is configured for Docker files and directories - docker.socket
[WARN] 1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker
[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
```



```text:設定実施後後
[INFO] 1 - Host Configuration
[PASS] 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 17.12.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:999:fujiwara
[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
[PASS] 1.9  - Ensure auditing is configured for Docker files and directories - docker.socket
[PASS] 1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker
[PASS] 1.11 - Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json
[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
```
`[WARN]`の宇文がほぼすべて`[PASS]`になっていることが確認できます。

一部については、Docker Bench for Securityのコードを見ながら対応した部分もあるので
インチキ感満載ですが、これで多少はセキュアになったかと思われます。
次回は`2 - Docker daemon configuration`に取り組みます。


# Special Thanks.

2018/7/31 khskさんの編集リクエストを受けて修正