DockerのRootless modeで、rootユーザ以外でデーモンを実行してみた

Docker 19.03(2019年7月リリース)で入った機能の1つであるRootless modeを触ってみました。

Rootless モード(Rootless mode)は Docker デーモンとコンテナを root 以外のユーザが実行できるようにするもので、デーモンやコンテナ・ランタイムにおける潜在的脆弱性を回避してくれるものです。

CVE-2019–5736のようなコンテナの中からホスト上の権限を奪取することが出来る脆弱性が見つかっているので、特に実運用環境ではRootless modeで実行されるようにした方が良さそうです。

NTT須田さんの記事に詳しく書いてあるのでリンクを貼っておきます。 medium.com

Rootlessモードの場合とそうでない場合で、Dockerdのプロセスとコンテナ内で動くプロセスのユーザがどうなっているか確認してみました。

Rootlessモードではない場合

Dockerをインストール済のホストマシンで、起動中のDockerデーモンの実行ユーザを確認してみました。

psをコマンドでdockerdの実行ユーザを確認すると

f:id:moritamorie:20201222015545p:plain

たしかにrootで実行されていそうです。

次にUSERを指定しないでプロセスを起動しているコンテナに入って実行中のプロセス情報を確認してみます。

f:id:moritamorie:20201222024151p:plain

コンテナ内のプロセスの実行ユーザもrootになっていました。

Rootlessモードの場合

手元のマシンでは、既にrootlessモードではないdockerdが起動しているので、Amazon EC2(ubuntu 20.04 LTS, t2.nano )環境にDockerをインストールしrootlessモードで起動してみます。

前提条件は環境によって異なります。Ubuntuでは事前準備は不要ですが、他の環境で試される方はドキュメントを参考にセットアップしてみてください。

$ curl -fsSL https://get.docker.com/rootless | sh
# Installing stable version 20.10.1
# Missing system requirements. Please run following commands to
# install the requirements and run this installer again.
# Alternatively iptables checks can be disabled with SKIP_IPTABLES=1

cat <<EOF | sudo sh -x
apt-get install -y uidmap
EOF

uidmapのインストールが必要のようなので、インストールしてみました。

$ sudo apt update
$ cat <<EOF | sudo sh -x
apt-get install -y uidmap
EOF 

再度、dockerをインストールしてみます。

$ curl -fsSL https://get.docker.com/rootless | sh
# Installing stable version 20.10.1

〜〜〜

[INFO] Creating /home/ubuntu/.config/systemd/user/docker.service
[INFO] starting systemd service docker.service
+ systemctl --user start docker.service
+ sleep 3
+ systemctl --user --no-pager --full status docker.service
● docker.service - Docker Application Container Engine (Rootless)
     Loaded: loaded (/home/ubuntu/.config/systemd/user/docker.service; disabled; vendor preset: enabled)

〜〜〜

[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service`
[INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger ubuntu`

[INFO] Make sure the following environment variables are set (or add them to ~/.bashrc):

export PATH=/home/ubuntu/bin:$PATH
export DOCKER_HOST=unix:///run/user/1000/docker.sock

無事にdockerのインストールができました。インストールプロセスの中でsystemctlコマンドを使ってdocker.serviceを起動しているので、既にDockerデーモンは起動している状態です。

dockerコマンドにパスを通すために~/.bashrc環境変数を追加して、sourceコマンドで反映してみます。

export PATH=/home/ubuntu/bin:$PATH
export DOCKER_HOST=unix:///run/user/1000/docker.sock
$ source ~/.bashrc

Dockerデーモンの実行ユーザを確認してみました。psをコマンドでdockerdの実行ユーザを確認すると f:id:moritamorie:20201223000227p:plain

ubuntuユーザで実行されていて、rootではなくなっていることが確認できました。

次にUSERを指定しないでプロセスを起動しているコンテナに入って実行中のプロセス情報を確認してみます。

f:id:moritamorie:20201223003935p:plain

おや。rootユーザで実行されていて、Rootless modeではない場合とユーザと同じになっていそうです。

以下の Docker公式のブログ記事を読んでみると

ルートレスモードは、最初にユーザ名前空間を作成し、リマップされた名前空間で既にデーモンを起動することを除いて、同様の方法で動作します。デーモンとコンテナは、ホストとは異なる同じユーザー名空間を使用します。

https://i2.wp.com/cdn-images-1.medium.com/max/2000/1*SfAokC2YQ-f04Wc2WhSRCw.png?ssl=1

という内容が記載されているので、コンテナ内ではrootユーザではあるものの、ホストマシンのubuntuユーザにマッピングされて実行されているようなので、万が一コンテナが乗っ取られてもホスト上の権限を奪取できない状態になっていそうです。

参考記事