DockerのRootlessを考える
何も考えない場合Dockerはroot権限で動くが、そうしたければ非root権限( = Rootless)で動かすこともできる。
Dockerの実行権限について
Dockerのデーモンとコンテナはプロセスとして動き、それぞれが権限を持つ。
そのためDockerの話をしていてRootlessという単語が出てきたら、何がRootlessなのか(デーモンが?コンテナが?)を意識する必要がある。
以下でDockerデーモン・Dockerコンテナとroot権限・非root権限の組み合わせを考える。
| Dockerデーモン | Dockerコンテナ | 説明 |
|---|---|---|
| root | root | デフォルト。何でもできて便利だが脆弱性によってホスト、コンテナともに乗っ取られるかもしれない。 |
| root | 非root | デフォルトよりマシだが、ホスト側の脆弱性によってホストを乗っ取られるかもしれない。 |
| 非root | root | デフォルトよりマシだが、コンテナ側の脆弱性によってコンテナを乗っ取られるかもしれない。 |
| 非root | 非root | デフォルトに比べてホスト、コンテナともに被害は抑えられるが、ネットワークやファイル読み書きで問題が出ることがある。 |
権限は安全と利便性の両方を考慮して決めるのが良いと思う。
デーモン・コンテナ共にユーザー権限で間に合うのであればそうすれば良いし、5分以内にコンテナを立ち上げないと地球が爆発してしまう事態であれば両方rootで済ませてしまってもいいかもしれない。
Rootlessモードを使う
Rootlessモードについて
Rootlessモード(Rootless Dockerともいう)を使うとDockerデーモンを非root権限で動作させることができる。
Rootlessモードを使うとセキュリティが向上する一方で、以下のようなデメリットも有る。
- 80や443などのWell-knownポートを使うには工夫が必要となる
- 権限が狭まる分、Dockerコンテナが上手く起動しないこともある
docker context lsでDockerのコンテキスト(接続先デーモン)の一覧と権限を確認できる。
アスタリスクの行のDOCKER ENDPOINTがunix:///var/run/docker.sockであればroot権限で動作している。
1 2 3 | |
Rootlessモードをインストールする
1 | |
従属UID/GIDが65536以上であることを確認する。
1 2 3 4 | |
root権限のDockerデーモンが動いている場合は以下のコマンドを実行して止める。
1 2 3 4 5 | |
ユーザーにRootlessモードをインストールする。ユーザー権限でインストールするのでsudoは要らない。
1 | |
Rootlessモード になっているか確認する。docker context lsを実行したとき、アスタリスクの行のDESCRIPTIONがRootless modeであればRootlessモードになっている。
1 2 3 4 | |
1 | |
Rootlessモードを無効にする
Rootlessモードを元に戻したいときは、以下を実行する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Rootlessモードを有効にする
やっぱりRootlessモードにしたいときは、以下を実行する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
ターミナルを開いている間だけRootlessモードを有効にする
上記の手順は恒久的にモードを切り替える方法だが、ターミナルを開いている間だけRootlessモードを有効にしたいときもある。
そういうときは以下を実行する。
1 | |
RootlessモードでWell-knownポートを使う
Rootlessモードで80や443などのWell-knownポートを使いたい場合、工夫が要る。
バイナリにWell-knownポートのバインド権限を与えることができるsetcapというコマンドがあるので、それが使える。
RootlessモードのDockerはrootlesskitを使ってポートフォワーディングを行うのでrootlesskitにバインド権限を与えれば良い。
1 2 3 4 5 6 7 8 9 10 11 12 | |
RootlessモードのDockerデーモンを常駐させる
Rootlessモードならではの注意点の一つとして、SSHセッションを閉じるとDockerデーモンが終了してしまうことがある。
何故かというと、RootlessモードのDockerデーモンは~/.config/systemd/user/docker.serviceで起動しており、これはsystemdのユーザーサービスであり、systemdのユーザーサービスはSSHセッションを閉じると終了してしまうからである。
しかし以下のコマンドでユーザーサービスの常駐を有効化することで、SSHセッションを閉じてもRootlessモードのDockerデーモンを起動し続けることができる。
1 2 3 4 5 6 7 8 9 | |
コンテナを非root権限で動作させる
docker
--user: 1000:1000でDockerを動かしているユーザと同じ権限で動作させることができる。
Dockerfile
USERでroot以外のユーザーを指定することで非root権限で動作させることができる。
docker-compose.yml
user: 1000:1000でDockerを動かしているユーザと同じ権限で動作させることができる。
コンテナの実行権限を確認する
コンテナがどの権限で動いているかは以下のコマンドで確認できる。
1 2 | |
UIDのマッピング
Rootless DockerではコンテナUIDはホストUIDへリマッピングされる。
| コンテナUID | ホストUID | 補足 |
|---|---|---|
| 0 (root) | 1000 (owner) | ホストユーザー自身 |
| N (1~65536) | 100000 + N | subordinate UID範囲 |
| 1000 (node) | 101000 | N=1000のケース |
Rootless Dockerはそのコンセプト上、コンテナUIDをrootユーザーのUID(0)へマッピングすることはない。