Docker Security
Trickestを使用して、世界で最も高度なコミュニティツールによって強化されたワークフローを簡単に構築および自動化します。 今すぐアクセスを取得:
基本的なDocker Engineセキュリティ
Docker EngineはLinuxカーネルのNamespacesとCgroupsを使用してコンテナを分離し、基本的なセキュリティレイヤーを提供します。Capabilities dropping、Seccomp、SELinux/AppArmorによる追加の保護により、コンテナの分離が強化されます。認証プラグインを使用すると、ユーザーのアクションをさらに制限できます。
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2Fsreeninet.files.wordpress.com%2F2016%2F03%2Fdockersec1.png&width=768&dpr=4&quality=100&sign=dda5c97e&sv=1)
Docker Engineへの安全なアクセス
Docker Engineは、Unixソケットを介してローカルでアクセスするか、HTTPを使用してリモートでアクセスできます。リモートアクセスの場合、機密性、整合性、および認証を確保するためにHTTPSとTLSを使用することが重要です。
デフォルトでは、Docker EngineはUnixソケットでunix:///var/run/docker.sock
でリッスンします。Ubuntuシステムでは、Dockerの起動オプションは/etc/default/docker
に定義されています。Docker APIとクライアントへのリモートアクセスを有効にするには、次の設定を追加してDockerデーモンをHTTPソケットで公開してください:
しかし、DockerデーモンをHTTP経由で公開することはセキュリティ上の懸念から推奨されていません。接続を安全にするためには、HTTPSを使用することがお勧めされます。接続を保護するための主なアプローチは2つあります:
クライアントがサーバーの正体を確認します。
クライアントとサーバーの両方がお互いの正体を相互認証します。
証明書はサーバーの正体を確認するために使用されます。両方の方法の詳細な例については、このガイドを参照してください。
コンテナイメージのセキュリティ
コンテナイメージは、プライベートまたはパブリックのリポジトリに保存することができます。Dockerには、コンテナイメージのためのいくつかのストレージオプションがあります:
Docker Hub: Dockerのパブリックレジストリサービス。
Docker Registry: ユーザーが独自のレジストリをホストできるオープンソースプロジェクト。
Docker Trusted Registry: Dockerの商用レジストリオファリングで、ロールベースのユーザー認証とLDAPディレクトリサービスとの統合を提供しています。
イメージスキャン
コンテナには、ベースイメージまたはベースイメージの上にインストールされたソフトウェアのせいでセキュリティの脆弱性がある場合があります。Dockerは、コンテナのセキュリティスキャンを行い脆弱性をリストアップするプロジェクトNautilusに取り組んでいます。Nautilusは、各コンテナイメージレイヤーを脆弱性リポジトリと比較してセキュリティホールを特定します。
詳細については、こちらを読んでください。
docker scan
**docker scan
**コマンドを使用すると、イメージ名またはIDを使用して既存のDockerイメージをスキャンできます。たとえば、次のコマンドを実行してhello-worldイメージをスキャンできます:
Dockerイメージの署名
Dockerイメージの署名は、コンテナで使用されるイメージのセキュリティと整合性を確保します。以下は要約した説明です:
Dockerコンテンツ信頼を有効にするには、
export DOCKER_CONTENT_TRUST=1
を設定します。この機能は、Dockerバージョン1.10以降ではデフォルトでオフになっています。この機能を有効にすると、署名されたイメージのみをダウンロードできます。最初のイメージプッシュでは、ルートとタグ付けキーのパスフレーズを設定する必要があり、Dockerはセキュリティを強化するためにYubikeyもサポートしています。詳細はこちらにあります。
コンテンツ信頼が有効な状態で署名されていないイメージを取得しようとすると、「最新の信頼データがありません」というエラーが発生します。
最初の後のイメージプッシュでは、Dockerはイメージに署名するためにリポジトリキーのパスフレーズを要求します。
プライベートキーをバックアップするには、次のコマンドを使用します:
Dockerホストを切り替える際には、操作を維持するためにルートとリポジトリキーを移動する必要があります。
Trickestを使用して、世界で最も先進的なコミュニティツールによって強化されたワークフローを簡単に構築および自動化します。 今すぐアクセスしてください:
コンテナセキュリティ機能
名前空間
名前空間はLinuxカーネルの機能で、1つのプロセスセットが1つのリソースセットを見る一方、別のプロセスセットが異なるリソースセットを見るようにカーネルリソースを分割する機能です。この機能は、一連のリソースとプロセスに同じ名前空間があるが、それらの名前空間が異なるリソースを参照するように機能します。リソースは複数のスペースに存在する可能性があります。
Dockerは、コンテナの分離を実現するために以下のLinuxカーネル名前空間を利用しています:
pid名前空間
マウント名前空間
ネットワーク名前空間
ipc名前空間
UTS名前空間
名前空間に関する詳細情報については、以下のページを参照してください:
Namespacescgroups
Linuxカーネル機能cgroupsは、一連のプロセス間でcpu、メモリ、io、ネットワーク帯域幅などのリソースを制限する機能を提供します。 Dockerは、特定のコンテナのリソース制御を可能にするcgroup機能を使用してコンテナを作成できます。 以下は、ユーザースペースメモリが500mに制限され、カーネルメモリが50mに制限され、CPU共有が512に、blkioweightが400に設定されたコンテナの例です。 CPU共有は、コンテナのCPU使用率を制御する比率です。デフォルト値は1024で、0から1024の範囲です。 CPUリソースの競合が発生した場合、CPU共有が1024の3つのコンテナがある場合、各コンテナはCPUの最大33%を取ることができます。 blkio-weightは、コンテナのIOを制御する比率です。デフォルト値は500で、10から1000の範囲です。
コンテナのcgroupを取得するには、次のようにします:
以下は、特権昇格に関する情報です:
CGroups機能
機能は、rootユーザーに許可される機能を細かく制御することを可能にします。DockerはLinuxカーネルの機能を使用して、ユーザーの種類に関係なくコンテナ内で行われる操作を制限します。
Dockerコンテナが実行されると、プロセスは隔離から脱出するために使用できる機密機能を削除します。これにより、プロセスが機密アクションを実行したり脱出したりすることができないようにします:
Linux CapabilitiesDocker内のSeccomp
これは、Dockerがコンテナ内で使用できるシステムコールを制限するセキュリティ機能です:
SeccompDocker内のAppArmor
AppArmorは、プログラムごとのプロファイルでコンテナを限られたリソースに制限するためのカーネル拡張機能です。:
AppArmorDocker内のSELinux
ラベリングシステム:SELinuxは、すべてのプロセスとファイルシステムオブジェクトに一意のラベルを割り当てます。
ポリシーの強制:プロセスラベルがシステム内の他のラベルに対して実行できるアクションを定義するセキュリティポリシーを強制します。
コンテナプロセスラベル:コンテナエンジンがコンテナプロセスを開始するとき、通常は
container_t
という制限付きSELinuxラベルが割り当てられます。コンテナ内のファイルラベリング:コンテナ内のファイルは通常、
container_file_t
としてラベル付けされます。ポリシールール:SELinuxポリシーは、主に
container_t
ラベルを持つプロセスがcontainer_file_t
としてラベル付けされたファイルとのみ相互作用(読み取り、書き込み、実行)できることを確認します。
このメカニズムにより、コンテナ内のプロセスが侵害されても、対応するラベルを持つオブジェクトとの相互作用に制限され、そのような侵害からの潜在的な被害が大幅に制限されます。
SELinuxAuthZ&AuthN
Dockerでは、認可プラグインが重要な役割を果たし、Dockerデーモンへのリクエストを許可するかブロックするかを決定します。この決定は、次の2つのキーとなるコンテキストを調査することで行われます:
認証コンテキスト:これには、ユーザーに関する包括的な情報が含まれます。たとえば、ユーザーが誰であり、どのように認証されたかなどです。
コマンドコンテキスト:これには、リクエストに関連するすべての関連データが含まれます。
これらのコンテキストにより、認証されたユーザーからの正当なリクエストのみが処理され、Docker操作のセキュリティが向上します。
AuthZ& AuthN - Docker Access Authorization PluginコンテナからのDoS
コンテナが使用できるリソースを適切に制限していない場合、侵害されたコンテナが実行されているホストをDoS攻撃する可能性があります。
CPU DoS
バンド幅 DoS
インタレスティングなDockerフラグ
--privileged フラグ
次のページで、--privileged
フラグが意味するものを学ぶことができます:
--security-opt
no-new-privileges
低い特権ユーザーとしてアクセスを取得した攻撃者がコンテナを実行している場合、誤構成されたsuidバイナリがあると、攻撃者はそれを悪用してコンテナ内で特権を昇格させる可能性があります。これにより、脱出することができるかもしれません。
no-new-privileges
オプションを有効にしてコンテナを実行すると、この種の特権昇格を防ぐことができます。
その他
さらなる**--security-opt
**オプションについては、https://docs.docker.com/engine/reference/run/#security-configurationを参照してください。
その他のセキュリティ考慮事項
シークレットの管理:ベストプラクティス
Dockerイメージにシークレットを直接埋め込んだり環境変数を使用したりすることは避けることが重要です。これらの方法は、docker inspect
やexec
などのコマンドを介してコンテナにアクセス権を持つ者に機密情報を公開してしまいます。
Dockerボリュームは、機密情報にアクセスするために推奨されるより安全な代替手段です。これらは一時的なメモリ内のファイルシステムとして利用でき、docker inspect
やログ記録に関連するリスクを軽減します。ただし、ルートユーザーやコンテナへのexec
アクセス権を持つユーザーは依然としてシークレットにアクセスできる可能性があります。
Dockerシークレットは、機密情報を取り扱うためのさらに安全な方法を提供します。イメージのビルドフェーズ中にシークレットが必要な場合、BuildKitはビルド時間のシークレットをサポートする効率的なソリューションを提供し、ビルド速度を向上させ追加機能を提供します。
BuildKitを活用するためには、次の3つの方法でアクティブ化できます:
環境変数を介して:
export DOCKER_BUILDKIT=1
コマンドにプレフィックスを付けて:
DOCKER_BUILDKIT=1 docker build .
Docker構成でデフォルトで有効にする:
{ "features": { "buildkit": true } }
と設定し、その後Dockerを再起動します。
BuildKitを使用すると、--secret
オプションを使用してビルド時のシークレットを利用でき、これらのシークレットがイメージビルドキャッシュや最終イメージに含まれないようにします。
実行中のコンテナで必要なシークレットについては、Docker ComposeとKubernetesが堅牢なソリューションを提供しています。Docker Composeは、docker-compose.yml
の例に示すように、サービス定義内のsecrets
キーを使用してシークレットファイルを指定します。
この設定では、Docker Composeを使用してサービスを起動する際にシークレットを使用できるようになります。
Kubernetes環境では、シークレットはネイティブでサポートされており、Helm-Secretsなどのツールでさらに管理できます。 KubernetesのRole Based Access Controls(RBAC)は、Docker Enterpriseと同様にシークレット管理のセキュリティを向上させます。
gVisor
gVisorは、Goで書かれたアプリケーションカーネルであり、Linuxシステムサーフェスの大部分を実装しています。アプリケーションとホストカーネルの間の隔離境界を提供するrunsc
というOpen Container Initiative(OCI)ランタイムを含んでいます。 runsc
ランタイムはDockerとKubernetesと統合されており、サンドボックス化されたコンテナを簡単に実行できます。
Kata Containers
Kata Containersは、コンテナと同様に感じ、パフォーマンスが高い軽量な仮想マシンを使用して、ハードウェア仮想化技術を使用してより強力なワークロード分離を提供するセキュアなコンテナランタイムを構築するために取り組むオープンソースコミュニティです。
要約のヒント
--privileged
フラグを使用しないか、コンテナ内にDockerソケットをマウントしないでください。 Dockerソケットを使用すると、コンテナを生成できるため、たとえば--privileged
フラグを使用して別のコンテナを実行することでホストを完全に制御することが簡単になります。コンテナ内でrootとして実行しないでください。異なるユーザー とユーザーネームスペース を使用してください。 コンテナ内のrootは、ユーザーネームスペースでリマップされていない限り、ホストと同じです。主にLinuxのネームスペース、機能、およびcgroupsによってわずかに制限されています。
すべての機能を削除 (
--cap-drop=all
)し、必要な機能のみを有効にしてください(--cap-add=...
)。多くのワークロードには機能が必要ない場合があり、それらを追加すると攻撃の範囲が広がります。プロセスが特権を取得するのを防ぐために、「no-new-privileges」セキュリティオプションを使用してください。たとえば、suidバイナリを介して特権を取得することがあります。
コンテナに利用可能なリソースを制限してください。リソース制限は、マシンをサービス拒否攻撃から保護できます。
**公式のDockerイメージ**を使用し、署名を要求するか、それらを基に独自のイメージを構築してください。バックドアが仕込まれたイメージを継承したり使用しないでください。また、ルートキー、パスフレーズは安全な場所に保存してください。 Dockerは、UCPでキーを管理する計画を立てています。
定期的にイメージを再構築して、ホストとイメージにセキュリティパッチを適用してください。
シークレットを賢く管理して、攻撃者がアクセスしにくくしてください。
Dockerデーモンを公開する場合は、HTTPSを使用してクライアントとサーバーの認証を行ってください。
Dockerfileでは、ADDの代わりにCOPYを使用してください。 ADDは自動的にzipファイルを解凍し、URLからファイルをコピーできます。 COPYにはこれらの機能がありません。可能な限りADDを使用せず、リモートURLやZipファイルを介した攻撃に対して脆弱にならないようにしてください。
各マイクロサービスに別々のコンテナを使用してください。
コンテナイメージを小さくしてください
Docker Breakout / Privilege Escalation
Dockerコンテナ内にいるか、dockerグループのユーザーにアクセス権がある場合、脱出して特権を昇格することができます:
Docker Breakout / Privilege EscalationDocker Authentication Plugin Bypass
Dockerソケットにアクセス権があるか、dockerグループのユーザーにアクセス権があるが、docker認証プラグインによって制限されている場合、バイパスできるかどうかを確認してください:
AuthZ& AuthN - Docker Access Authorization PluginDockerのハードニング
docker-bench-securityツールは、本番環境でDockerコンテナを展開する際の数十の一般的なベストプラクティスをチェックするスクリプトです。テストはすべて自動化されており、CIS Docker Benchmark v1.3.1に基づいています。 ツールを実行するには、Dockerを実行しているホストからまたは十分な権限を持つコンテナから実行する必要があります。READMEでの実行方法について詳細を確認してください:https://github.com/docker/docker-bench-security。
参考文献
Trickestを使用して、世界で最も高度なコミュニティツールによって強化されたワークフローを簡単に構築および自動化できます。 今すぐアクセスしてください:
Last updated