これを書いた理由
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をつけた方がいいと思います。