ユーザーがコード(Java、C#)を記述、コンパイル、および実行できるWebアプリケーションを作成しました。アプリケーションは、コンパイルとコード実行が行われるすべてのユーザーに対してDockerコンテナーを作成します。コンテナを固定するために、私は次の対策を講じました。
このコンテナは信頼できないコードを実行しても安全だと思いますか?このような構成のコンテナー内からホストマシンに影響を与える既知の方法はありますか?
tl; dr:コンテナソリューションは完全な分離を提供することを保証せず、保証しません。これが必要な場合は、代わりに仮想化を使用してください。
Docker(および同じことが類似のコンテナーソリューションに適用されます)は完全な分離を保証するものではなく、仮想化と混同しないでください。コンテナーの分離は、それらの間には障壁がありますが、それでもカーネルとして共有リソースを使用します。一方、仮想化の共有リソースははるかに小さく、理解しやすく、十分にテストされていますが、アクセスを制限するためのハードウェア機能によって強化されることがよくあります。 Docker自体はこれを Dockerセキュリティの記事 で説明しています
Dockerコンテナーの実行に伴う主なリスクの1つは、コンテナーに与えられたデフォルトの機能とマウントのセットが、独立して、またはカーネルの脆弱性と組み合わせて使用すると、不完全な分離を提供する可能性があることです。
仮想化の場合は、ほぼ完全な分離から始めて、some十分に保護され、適切に記述されたインターフェースを提供します。これは、仮想マシンからの分離が難しいことをかなり確信できることを意味します。カーネルは共有されません。ユーザーの制限から逃れるためのカーネルエクスプロイトがある場合、ハイパーバイザーはあなたと他の仮想マシンの中間まで存在します。
これは完全な分離を意味するものではありません。何度も、ハイパーバイザーの問題が見つかりましたが、それらのほとんどは、実行が困難な限定された範囲の非常に複雑な攻撃です(しかし、非常に重要で「悪用しやすい」攻撃もあります。
コンテナーを使用すると、同じカーネルでアプリケーションを実行することから開始しますが、バリア(カーネル名前空間、cgroupなど)を追加して、それらをより適切に分離します。これにはオーバーヘッドが少ないといういくつかの利点がありますが、何も忘れていないことを「確認」することははるかに困難ですが、Linuxカーネルは非常に大きく複雑なソフトウェアです。そして、カーネル自体はまだ共有されています。カーネルにエクスプロイトがある場合、ホスト(および/または他のコンテナー)にエスケープできる可能性が高くなります。
特にpre - ユーザーネームスペースを取得するDocker 1.9 は、Dockerマシン(またはカーネルエクスプロイト)に別の不足しているバリアが見つかるとすぐに、「コンテナルートにもホストルート権限がある」ことを意味します。 以前にそのような問題がありました 、あなたはもっと来ることを期待するべきです Dockerは推奨します
コンテナー内でプロセスを非特権ユーザー(つまり、非ルート)として実行することに注意してください。
詳細に興味がある場合は、 estepがhttp://integratedcode.usにユーザーの名前空間を説明する優れた記事を投稿しました です。
Rootアクセスを制限すること(たとえば、イメージを作成するとき、または少なくとも新しいユーザー名前空間を使用するときに非特権ユーザーを強制することによって)は、分離を提供するために必要かつ基本的なセキュリティ対策であり、satisfyingコンテナー間の分離。制限されたユーザーとユーザーの名前空間を使用すると、ホストへのエスケープが非常に難しくなりますが、まだコンテナから抜け出すために考慮されていない別の方法があることを確認する必要はありません(カーネルにパッチされていないセキュリティ問題の悪用が含まれる場合) )、信頼されていないコードの実行には使用しないでください。
@ jens-eratからの回答 は、仮想化がDockerなどのコンテナー化ソリューションに対して優れた分離を提供するという正確な概要を持っていますが、白黒のセットアップではありません。
一方では、多数のゲスト->仮想化テクノロジーにおけるホストのブレイクアウト(たとえば、仮想フロッピーデバイスドライバーの「 Venom 脆弱性」)により、仮想化によって提供される分離がセキュリティ制御のように100%ではありません。
分離を改善し、リスクを軽減するためにDockerインストールを強化する観点から、Dockerインストールを保護するために実行できるいくつかの手順があります。
Dockerには、セキュリティ強化に関する優れたセキュリティガイダンスがあります。 (少し古くなっている) CIS Security Guide と docker bench があり、構成の確認に使用できます
アプリケーションがどのように動作するか(つまり、コンパイルのためにコードがどのように機能するか)に応じて、Dockerの動作を変更して悪意のあるアクティビティの可能性を減らすことができます。たとえば、コードがホストレベルで実行されると仮定すると、コンテナへのネットワークアクセスを拒否できる場合があります(--net none
スイッチdocker run
)。追加の capabilities をドロップして、コンテナーで実行されているプロセスが実行できる処理を減らすことができるかどうかを確認することもできます。
AppArmorプロファイルを使用してリソースを制限することを検討してください。 AppArmorは、コンテナで実行できることを制限するために使用でき、 bane などのツールを使用して、アプリケーションのプロファイルを生成できます。
また、ホストレベルで監視を実装して、悪意のある可能性のあるアクセスを探すことをお勧めします。コンテナーがすべきこと、すべきでないことを知っているので、比較的厳密な監視を行うと、発生の可能性があることを警告します
この種のセットアップを強化するために生産的である可能性があるもう1つの領域は、ホストOSとコンテナーイメージを取り除いたものを使用することです。公開されるコードが少ないほど、攻撃対象領域は小さくなります。 CoreOS または buntu Snappy Core のようなものは一見の価値があります
私のソリューションはSmartOSのようなものです。 SmartOSである理由は、Docker、KVM、およびゾーンをサポートします。したがって、これらを組み合わせて使用して、Dockerコンテナーを超えて悪意のあるコードが実行されるのを防ぐことができます。結局、Dockerコンテナーはファイルシステム上のファイルのままです。