Dockerでユーザーをdockerグループに追加することの危険性を理解しよう

これを書いた理由

Dockerに初期から存在するセキュリティ上の問題点を未だに理解せずにQiitaにDocker記事を書いている人が後を立たないので一応日本での第一報告者として解説しなくてはと思いました。

Dockerはなぜrootでなければ動かないのか?

Dockerはroot権限で動いているデーモン(dockerd)とunixソケットまたはtcp/ipで通信していますが、dockerdにアクセスするにはdockerグループに所属しているかroot権限が必要になってきます。そしてdockerはroot無しでアクセスすると簡単に権限昇格ができてしまうのです。

Dockerで権限昇格する

試しにユーザーをdockerグループに所属させてみましょう。

sudo usermod -aG docker $USER

すると簡単にパスワードなしでdockerコマンドを使うことができるようになります。

 docker images

しかしそうするとこういうことができてしまいます。

touch backdoor.sh #悪いことをするスクリプト
docker run -v /tmp:/mnt -it ubuntu:latest バックドアを設置するコマンド

このコマンドはコンテナ内のroot権限だけでなく、ホスト側のroot権限も与えてしまうので簡単にバックドアを設置できてしまうのです。(設置するコマンドは調べればすぐに出てきますが流石にコピペできるように書くのはやばいので)
また他にもコンテナを--privileged付きで起動しホストの/をマウントしてchrootするというもっと凶悪な手もあります。

元々sudoが使えるのに、何が問題なの?

問題はユーザーが意図的にdockerコマンドを実行した時には発生しません。問題は悪意のあるプログラムやがサーバなどに混入した時や、怪しいDockerfileを使用した場合です。
大抵の悪意のあるプログラムは何らかの手段でroot権限を取得しようとしますが、それはゼロデイ脆弱性であったりそもそもの権限のミスであったりしますが、dockerがインストールされている条件下ならばこの方法で権限昇格を狙ってくる場合があるのです。また職場のPCだとかで目を離した隙に誰かがこっそり何かをし込んだりする可能性や、SSHの公開鍵が漏洩した場合なども十分に考えられます。

ではどうすればいいのか?

毎回sudoするのはあまり得策ではありませんし、suやsudo -iで全部のコマンドをrootで動かすのは逆効果かつ自爆行為にもほどがあります。
この問題は2つの対応手段があります。
1つ目はnewgrpコマンドを使った一時的なdockerグループへの所属です。
2つ目はユーザー名前空間(--user-remap)を用いたuidの変更です。これはdockerdの設定で変更可能ですが、--privilegedを付けて実行できなくなります。--privilegedを使う時は設定を変えてdockerdを再起動するか、別のデーモンプロセスを起動する必要があります。
この2つの解説は長くなるのでしませんが、両方を組み合わせるのが得策だと思います。--privilegedを使わなければならない場合は素直にsudoをつけた方がいいと思います。