Docker apiのセキュリティ対策を確認してみた

## 経緯
Docker apiが原因のインシデントとして、次のような記事があったので、
実際に試しながらどのようなセキュリティ対策ができるか確認しました

https://www.security-next.com/099752


## 環境
EC2上でDockerを起動し、自身のPCからapiを実行します
EC2のセキュリティグループはPCのIPからは許可している状態です


## 準備
以下のサイトを参考にしながらDocker apiを設定します
https://blog.naosuke.me/entry/2017/11/17/011046

EC2にて`/lib/systemd/system/docker.service`の`ExecStart`部分を
`ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375  -H unix:///var/run/docker.sock`と変更します

`curl localhost:2375/images/json` を実行
事前に入れていたイメージを確認できました

```
[
  {
    "Containers": -1,
    "Created": 1616710767,
    "Id": "sha256:b0da5d0678e7f0a5db2572363cd2bc2166c8078493573ad8229be9af2973d104",
    "Labels": null,
    "ParentId": "",
    "RepoDigests": [
      "alpine@sha256:a81f67aca260e41b2260a4cf91ac4435dcad62ccc108ab19ae3077aafa1a4722"
    ],
    "RepoTags": [
      "alpine:20210212"
    ],
    "SharedSize": -1,
    "Size": 5618417,
    "VirtualSize": 5618417
  }
]
```

## apiによる操作

### 1.イメージ一覧の取得
ローカル上でapiが使用できることは確認できたので、
PC上からコマンドを実行してみます

`curl EC2のIP:2375/images/json` を実行
EC2上で実行していた時と同様の結果が取得できたので、apiがうまく動いていそうです

```
[
  {
    "Containers": -1,
    "Created": 1616710767,
    "Id": "sha256:b0da5d0678e7f0a5db2572363cd2bc2166c8078493573ad8229be9af2973d104",
    "Labels": null,
    "ParentId": "",
    "RepoDigests": [
      "alpine@sha256:a81f67aca260e41b2260a4cf91ac4435dcad62ccc108ab19ae3077aafa1a4722"
    ],
    "RepoTags": [
      "alpine:20210212"
    ],
    "SharedSize": -1,
    "Size": 5618417,
    "VirtualSize": 5618417
  }
]
```

続いて、コンテナの起動までを実施します

### 2.イメージの作成

`curl -d "fromImage=python&tag=latest" -X POST "http://EC2のIP:2375/v1.41/images/create"`


1.のコマンドで使用したコマンドでイメージ一覧を取得すると、pythonが追加されていることを確認できました

```
 {
    "Containers": -1,
    "Created": 1663079621,
    "Id": "sha256:e285995a34947a2d58defdbdd65eb7478a4986292ff13127678c1f5ace92c9a2",
    "Labels": null,
    "ParentId": "",
    "RepoDigests": [
      "python@sha256:e9c35537103a2801a30b15a77d4a56b35532c964489b125ec1ff24f3d5b53409"
    ],
    "RepoTags": [
      "python:latest"
    ],
    "SharedSize": -1,
    "Size": 921099986,
    "VirtualSize": 921099986
  }

```

### 3. コンテナの作成


`curl -H "Content-Type: application/json" -d '{"Image":"python:latest"}' -X POST "http://EC2のIP:2375/v1.41/containers/create?name=test"`


確認のために次のコマンドを実行して、コンテナ一覧を取得し作成されていることを確認できました
`curl EC2のIP:2375/containers/json?all=true`

```
[
  {
    "Id": "60af394c08c3379b83e415e4766c8be2b169058f007eb416caa0b8a959b3f839",
    "Names": [
      "/test"
    ],
    "Image": "python:latest",
    "ImageID": "sha256:e285995a34947a2d58defdbdd65eb7478a4986292ff13127678c1f5ace92c9a2",
    "Command": "python3",
    "Created": 1664187895,
    "Ports": [],
    "Labels": {},
    "State": "created",
    "Status": "Created",
    "HostConfig": {
      "NetworkMode": "default"
    },
    "NetworkSettings": {
      "Networks": {
        "bridge": {
          "IPAMConfig": null,
          "Links": null,
          "Aliases": null,
          "NetworkID": "",
          "EndpointID": "",
          "Gateway": "",
          "IPAddress": "",
          "IPPrefixLen": 0,
          "IPv6Gateway": "",
          "GlobalIPv6Address": "",
          "GlobalIPv6PrefixLen": 0,
          "MacAddress": "",
          "DriverOpts": null
        }
      }
    },
    "Mounts": []
  }
]
```

### 4.コンテナ起動

`curl -X POST "http://EC2のIP:2375/v1.41/containers/60af394c08c3379b83e415e4766c8be2b169058f007eb416caa0b8a959b3f839/start"`

再度コンテナの一覧を取得すると

`Status`が`Created`から`Exited (0) 4 seconds ago`となっていたので起動できていることを確認できました


## 対策

### セキュリティグループ
EC2のセキュリティグループを設定して挙動確認します
セキュリティグループでPCのIPから接続できないように設定します

` Connection timed out`と表示され実行できないことが確認できました


### ExecStartの設定無効化
準備の際に変更していた`/lib/systemd/system/docker.service`の`ExecStart`部分を元に戻して挙動確認します

`Connection refused`と表示され実行できないことが確認できました

## 参考
APIのコマンドは以下のサイトを参考にしました
https://matsuand.github.io/docs.docker.jp.onthefly/engine/api/v1.41/
https://matsuand.github.io/docs.docker.jp.onthefly/engine/api/sdk/examples/