Docker ホスト-コンテナ間でのユーザー/グループの分離をしたい

#### 目的
~~アドベンドカレンダーを埋めたい~~
Docker ホスト-コンテナ間でのユーザー/グループの分離をしたい。
Dockerのデフォルト設定では、コンテナ内のプロセスはroot権限で実行される。
コンテナ内のプロセスがコンテナ内のファイルシステムにのみアクセスするのであれば問題ない。
しかし、もしホストのディレクトリをコンテナにマウントすると、コンテナ内のプロセスはroot権限でマウントしたディレクトリにアクセスできてしまう。

例えば、以下のようにホストのルートディレクトリをマウントした場合、コンテナ内から/usr/src/root経由で、ホストのすべてのディレクトリにアクセスできてしまう。

```
docker run -it -v /:/usr/src/root
```

「コンテナに攻撃されても、ホストはセーフ」ということはなく、正直、どんな脆弱性を突かれるか分からないので、出来る限りのセキュリティ面での対策はしておきたい。
※コンテナ内で root として振る舞うのはいいけど、ホストでも root として振る舞われたりしたらなんて恐ろしい
その対策の一つとして、「Docker ホスト-コンテナ間でのユーザー/グループの分離」をしてみる
※同じような記事はたくさんありますが、初めて試してみたという観点で書きます（ご了承ください）

#### 環境(ホスト)
```
Operating System: Ubuntu 18.04.2 LTS
          Kernel: Linux 4.15.0-51-generic
Docker version 20.10.7, build 20.10.7-0ubuntu5~18.04.3
```

#### ユーザー名前空間（UID，GID）でコンテナを分離する
コンテナからの特権昇格攻撃を防ぐ方法として、コンテナのアプリケーションを特権のないユーザーとして実行するように構成する。
具体的には、プロセスがコンテナ内で root ユーザーとして実行される場合、このユーザーをDockerホスト側では、より権限の低いユーザーに再マップする。

マップされたユーザーには、名前空間内で0〜65536の通常のUIDとして機能する一連のUIDが割り当てられるが、ホストマシン自体に対する権限はない。

Dockerではこの再マップする機能を userns-remap として提供している。

#### userns-remap を有効化するために使うユーザー、グループを指定する
ホスト側の「/etc/docker/daemon.json」にマップするユーザー、グループを指定します。
私はこのファイルを新規で作成しました。

```:ホスト側
/etc/docker/daemon.json
{
  "userns-remap": "mydockermap"
}
```

ホスト側にこのユーザーを作成します。
※これが存在しないと、docker のサービスを起動した時に失敗します

```:ホスト側
sudo adduser mydockermap
```

#### コンテナ内とコンテナ外でのユーザー/グループの対応付けを設定する（マッピング）
ホスト側の /etc/subuid と /etc/subgid に以下の記述を追加し、ユーザー/グループをマッピングします。
※100000は変更OK
[書式]
＜ユーザー名/グループ名＞:＜コンテナ内でrootユーザーとして使用するUID/GID）:65536

```:ホスト側/etc/subuidと/etc/subgidに追加
mydockermap:100000:65536
```

#### 設定変更を反映するために、docker daemon を再起動する
```:ホスト側
systemctl restart docker
```

※ここで起動に失敗した場合、ユーザーが正しく作成されているか、typo が無いか確認する

#### 設定が有効になっているか確認してみる
ホスト上にマウントするディレクトリを作成しておきます。

```
sudo mkdir /var/mounttest && ls -ld /var/mounttest
```

docker コンテナを起動(/var/mounttest をコンテナの /mounttest にマウントする）
※centos:7である必要はありません

```
docker run -it --rm -v /var/mounttest:/mounttest centos:7 bash
```

CHECK１：プロセスを実行しているユーザを確認すると、/etc/subuid で設定した値(100000)になっている

```:ホスト側
$ ps aux | grep 100000
100000   27081  0.0  0.0  11840  2864 pts/0    Ss+  19:26   0:00 bash
```

CHECK２：/mounttest の所有者/グループが root ではなく、65534 になっている

```:コンテナ側
# ls -ld /mounttest
drwxr-xr-x 2 65534 65534 4096 Dec 18 10:24 /mounttest
```

CHECK３：コンテナから /mounttest に対してファイル作成や権限変更は拒否されるはず

```:コンテナ側
# touch /mounttest/hoge
touch: cannot touch '/mounttest/hoge': Permission denied

# chown root:root /mounttest
chown: changing ownership of '/mounttest': Operation not permitted
```

CHECK４：/var/mounttest の所有者を 100000 にしたら、/mounttest にファイル作成できるようになるはず

```:ホスト側
$ sudo chown 100000 /var/mounttest && ls -ld /var/mounttest
drwxr-xr-x 2 100000 root 4096 Dec 18 19:24 /var/mounttest

# コンテナ起動
$ docker run -it --rm -v /var/mounttest:/mounttest centos:7 bash
```

```:コンテナ側
# touch /mounttest/hoge && ls -l /mounttest/
total 0
-rw-r--r-- 1 root root 0 Dec 18 10:45 hoge
```

#### 補足１

/etc/subuid に手動で「mydockermap:100000:65536」を追加した後に、adduser で mydockermap　を作ったので、以下のような状態になってしまった。

```
$ less /etc/subuid | grep mydockermap
mydockermap:100000:65536
mydockermap:296608:65536
```

mydockermap:296608:65536 の方を手動で削除した後、docker daemon を再起動しても動作した。同じユーザが重複して書かれている場合は、上の方に記載されているのが優先されている様子。

#### 補足２

typo に気づかずに、動かないから、docker のバージョンを上げたり色々してたら、docker image が消えてしまった。。( ◞‸◟ )
一旦、きれいに掃除できたと捉えよう！