5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

docker Advent Calendar 2021

Day 10

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

Posted at

目的

アドベンドカレンダーを埋めたい
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

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

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

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

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

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

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

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

CHECK4:/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

補足1

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

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

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

補足2

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

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?