fbpx

rootless コンテナでセキュリティを強化 #aqua #コンテナ #セキュリティ#rootless #runtime #rootlessコンテナ

この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。

本ブログは「Aqua Security」社の技術ブログで2021年1月14日に公開された「 Boosting Container Security with Rootless Containers 」の日本語翻訳です。

rootless コンテナでセキュリティを強化


数あるコンテナセキュリティのベストプラクティスの中で最も重要なことは、コンテナを root で実行しないようにすることです。rootless コンテナはこれを容易に実現できます。このブログでは、なぜコンテナの root 実行を避けるべきなのか、rootless コンテナとは何か、そしてそれがどのように役立つのかについてお話します。

通常コンテナはデフォルトで root 実行される

コンテナを実行する際、そのコンテナは root で実行されている可能性が高いです(ユーザ ID を変更することをしていない限り)。いくつか例外があります。podman や OpenShift を使用している場合、デフォルトではコンテナを root 実行しません。しかし今日では、開発者が Docker イメージを使用したり、Kubernetes を使ってコンテナをデプロイする際、ほとんどの場合はデフォルトで root 実行されています。これは無数のコンテナが必要以上に多くの権限を持っていることにつながり、攻撃対象を増やし、権限昇格をより現実的なものにしています。

コンテナを root 実行すべきではない理由

コンテナを root 実行することはなぜ危険なのでしょうか。それは、コンテナ内の root の実態がホスト(仮想)マシン上の root と全く同じだからです。攻撃者が root として実行されているコンテナを侵害することに成功した場合、ホストを乗っ取るための一歩を踏み出すことになります。その「一歩」として、コンテナエスケープの脆弱性が利用される可能性があります。頻繁に起こるものではありませんが、可能性はゼロではありません。新しいコンテナ脱出の脆弱性が発見された場合、悪用されるためには権限が必要になることが多いため、まず行う対策としてはコンテナが root 実行されていないことを確認することです。

さらに危険性を高めるのは、設定を誤る(例えばコンテナにマウントされているファイルへのアクセス)ことで、コンテナから容易にエスケープできるということです。何らかのポリシー制御がされていない限り(Aqua のソリューションはこのようなポリシー制御ができます)、ホストの root ディレクトリをコンテナにマウントすることを止めるものは何もありません。そのためコンテナが root 実行されている場合、ファイルとディレクトリのパーミッションは、コンテナによるアクセスや改ざんからホストを保護できません。一度攻撃者がホスト上で root になると、すべてにアクセスできます。アプリケーションの安全を確保したいのであれば、攻撃者がホストの root アクセスを得ることを、より困難にすべきです。

rootless コンテナとは何か、どのように役立つのか

rootless コンテナは比較的新しく、広く議論されている概念で、コンテナを実行するためのより安全なアプローチを提供します。rootlesscontaine.rs のコミュニティ定義によると、「rootless コンテナとは、権限のないユーザがコンテナを作成、実行、その他の管理する能力」を指し、つまり root でなくてもコンテナを実行できることを意味します。rootless のアプローチは、コンテナの観点からは root ユーザに見えますが、実際はホスト上の root 権限と同一ではありません。ではどのように動作するのか、またその裏で何が行われているのかを見てみましょう。

ご存知のように、コンテナは Linux の名前空間を利用して、実行するホストから自分自身を隔離します。コンテナを rootless にするため使用されているのが、ユーザ名前空間です。これはユーザ(およびグループ)の ID をマッピングし、名前空間の内側からプロセスが別の ID で実行されているように見えるようにします。

rootless コンテナの内部(正確にはユーザ名前空間の内部)からは、アプリケーションコードは root として実行されているように見え、名前空間の外では許可されていない特権的が可能です。しかし、ホストから見ればコンテナ内の root ユーザは通常のユーザです。攻撃者がユーザ名前空間からホストへアクセスしようとしても、そのユーザはホスト上で通常の非 root ユーザ ID を持つため、通常 root ユーザが利用できる特権機能は、その名前空間内では全く利用できません。

ユーザ名前空間のもう1つの重要な点は、ユーザ名前空間を作成するのに特権ユーザである必要がないことです。rootless コンテナでは、ユーザにホスト上の root 権限に相当する権限を与えずにコンテナを実行する権限が与えられます。これは、多くのユーザが共通のマシンへのアクセスを共有するのが一般的な環境では大きなメリットとなります。rootless のサポートがなければ、マシン上でコンテナを実行する許可を与えることは、実質的には root アクセスを与えることと同じことになります。

要約すると、セキュリティの観点から rootless コンテナを利用することは、2つの良い理由があります。

  • rootless コンテナを作成するのに特権ユーザである必要はありません。
  • コードをホストの root ユーザとして実行することなく、root 権限を持つ rootless コンテナ内で実行できます。

ユーザ名前空間がどのように動作するかについては、Linux の unshare コマンドを使用して rootless コンテナがどのように作成されるかを説明している以下の動画をご覧ください。

今日の rootless コンテナ

rootless コンテナという概念はまだ新しいものですが、業界の主要なベンダーからの支持を得ています。Red Hat の podman や Singularity コンテナのようなツールは、長い間 rootless コンテナをサポートしてきました。Docker の最新アップデート 20.10 では rootless のサポートが「experimental」から外れ、権限のないユーザが個々の rootless コンテナと同様に Docker デーモンをインストールして実行できるようになりました。

Kubernetes でも rootless コンテナという概念の実践が現在進行形で作業が行われていて、須田 瑛大(Akihiro Suda)さんが Usernetes というプロジェクトで PoC を行っています。

Kubernetes で rootless のサポートができるまで、どんな対策ができるでしょうか。要するに、コンテナを root として実行するのは避けたいということですが、それを支援するツールがあります。AdmissionController Webhook は、root として実行するコンテナのデプロイを停止するためのチェックを提供できます(PodSecurityPolicy もこれを実現できますが、将来なくなる可能性があるため、これから使用することはお勧めしません)。ワークロードが root として実行されないように定義されているかどうかなど、ベストプラクティスを探すために YAML 上で実行される設定チェックツールがあります。私たちはこれらのツールの1つである Polaris をオープンソースプロジェクトの Starboard に含めており、Kubernetes API を通じてセキュリティ問題を洗い出しています。また、Aqua のコンテナセキュリティソリューションは柔軟なポリシーチェックが含まれており、root で実行されているコンテナをアラートで通知、あるいはブロックできます。

まとめ


理想的には、コンテナはデフォルトで root 権限なしで実行されるべきです。これが達成されると、攻撃対象が大幅に減少し、コンテナの外での特権のエスカレーションなど、多くの潜在的なセキュリティ問題を回避できます。セキュリティ上の観点から rootless コンテナはこれを容易にし、全体的なセキュリティ状態を改善するための大きな一歩となります。コンテナやコンテナランタイムが危殆化しても、攻撃者はホスト上で自動的に root 権限を得ることはありません。

New call-to-action
新規CTA