Amazon ECS タスクおよびコンテナのセキュリティのベストプラクティス
コンテナイメージは、攻撃に対する防御の最前線と見なしてください。安全性が低く、構築が不十分なイメージがあると、攻撃者はコンテナの境界を抜け出し、ホストにアクセスできるようになる可能性があります。これが発生するリスクを軽減するには、次のことを行う必要があります。
タスクとコンテナを設定するときは、次のことを行うことをお勧めします。
最小限のイメージを作成するか、distroless のイメージを使用する
まず、コンテナイメージから不要なバイナリをすべて削除します。Amazon ECR Public Gallery にある見慣れないイメージを使用している場合は、そのイメージを調べてコンテナの各レイヤーの内容を参照してください。これには Dive
あるいは、アプリケーションとそのランタイム依存関係のみを含む distroless イメージを使用することもできます。パッケージマネージャーやシェルは含まれません。Distroless イメージは、「スキャナーの信号対雑音比を向上させ、必要なものだけを調達する負担を軽減する」ことができます。詳細については、GitHub の distroless
Docker には、scratch と呼ばれる、予約済みの最小限のイメージからイメージを作成するメカニズムがあります。詳細については、Docker ドキュメントの「scratch を使用した単純な親イメージの作成
############################ # STEP 1 build executable binary ############################ FROM golang:alpine AS builder # Install git. # Git is required for fetching the dependencies. RUN apk update && apk add --no-cache git WORKDIR $GOPATH/src/mypackage/myapp/ COPY . . # Fetch dependencies. # Using go get. RUN go get -d -v # Build the binary. RUN go build -o /go/bin/hello ############################ # STEP 2 build a small image ############################ FROM scratch # Copy our static executable. COPY --from=builder /go/bin/hello /go/bin/hello # Run the hello binary. ENTRYPOINT ["/go/bin/hello"] This creates a container image that consists of your application and nothing else, making it extremely secure.
前の例も、マルチステージビルドの例です。これらのタイプのビルドは、コンテナレジストリにプッシュされる最終イメージのサイズを最小限に抑えることができるため、セキュリティの観点からは魅力的です。コンテナイメージからビルドツールやその他の無関係なバイナリを省くことで、イメージのアタックサーフェスが減り、セキュリティ対策を強化することができます。マルチステージビルドの詳細については、Docker ドキュメントの「Multi-stage builds
イメージをスキャンして脆弱性がないか調べる
対応する仮想マシンと同様に、コンテナイメージには脆弱性のあるバイナリやアプリケーションライブラリが含まれていたり、時間の経過とともに脆弱性が生じたりする可能性があります。エクスプロイトから保護する最善の方法は、イメージスキャナーでイメージを定期的にスキャンすることです。
Amazon ECR に保存されている画像は、プッシュまたはオンデマンド (24 時間に 1 回) でスキャンできます。Amazon ECR のベーシックスキャンでは、オープンソースのイメージスキャンソリューションである ClairHIGH
または CRITICAL
のイメージは、削除するか再構築する必要があります。デプロイされたイメージに脆弱性が生じた場合は、できるだけ早く交換する必要があります。
Docker Desktop Edge バージョン 2.3.6.0
-
Amazon ECR と AWS Security Hub を使用してイメージコンプライアンスを自動化する
では、AWS Security Hub の Amazon ECR から脆弱性情報を検出し、脆弱なイメージへのアクセスをブロックすることで修復を自動化する方法について説明します。
イメージから特別な権限を削除する
アクセス権フラグsetuid
と setgid
は、実行ファイルの所有者またはグループの権限で実行できるようにします。これらのアクセス権限を持つバイナリは権限昇格に利用される可能性があるため、イメージからすべてのバイナリを削除してください。悪意のある目的に使用される可能性のある、nc
や curl
などのシェルやユーティリティをすべて削除することを検討してください。次のコマンドを使用すると setuid
および setgid
アクセス権のあるファイルを見つけることができます。
find / -perm /6000 -type f -exec ls -ld {} \;
これらのファイルから、これらの特別な権限を削除するには、以下のディレクティブをコンテナイメージに追加します。
RUN find / -xdev -perm /6000 -type f -exec chmod a-s {} \; || true
キュレーションされたイメージのセットを作成する
開発者が独自のイメージを作成できるようにするのではなく、組織内のさまざまなアプリケーションスタック用に、検証済みのイメージセットを作成することができます。そうすることで、開発者は Dockerfile の作成方法を学ぶ必要がなくなり、コードの記述に集中できます。変更がコードベースにマージされると、CI/CD パイプラインがアセットを自動的にコンパイルし、アーティファクトリポジトリに保存できます。最後に、アーティファクトを適切なイメージにコピーしてから、Amazon ECR などの Docker レジストリにプッシュします。少なくとも、開発者が独自の Dockerfile を作成できるようなベースイメージのセットを作成する必要があります。Docker Hub からイメージをプルすることは避けてください。イメージに何が入っているかを常に把握できるわけではなく、上位 1000 個のイメージの約 5 分の 1 に脆弱性があります。これらのイメージとその脆弱性のリストは https://vulnerablecontainers.org/
アプリケーションパッケージとライブラリをスキャンして脆弱性がないか調べる
オープンソースライブラリの使用は今や一般的になっています。オペレーティングシステムや OS パッケージと同様に、これらのライブラリには脆弱性が潜んでいる可能性があります。開発ライフサイクルの一環として、重大な脆弱性が見つかった場合は、これらのライブラリをスキャンして更新する必要があります。
Docker Desktop は Snyk を使用してローカルスキャンを実行します。また、オープンソースライブラリの脆弱性や潜在的なライセンス問題の検出にも使用できます。開発者のワークフローに直接統合できるため、オープンソースライブラリがもたらすリスクを軽減できます。詳細については、以下の各トピックを参照してください。
-
オープンソースのアプリケーションセキュリティツール
には、アプリケーションの脆弱性を検出するためのツールのリストが含まれています。
静的コード分析を行う
コンテナイメージを構築する前に、静的コード分析を実行する必要があります。これはソースコードに対して実行され、コーディングエラーや、フォールトインジェクションなどの悪意のある攻撃者に悪用される可能性のあるコードの特定に使用されます。Amazon Inspector を使用できます。詳細については、「Amazon Inspector ユーザーガイド」の「Amazon Inspector による Amazon ECR コンテナイメージのスキャン」を参照してください。
非ルートユーザーとしてコンテナを実行する
コンテナを実行するときは、非ルートユーザーとして実行してください。デフォルトでは、Dockerfile に USER
ディレクティブが含まれていない限り、コンテナは root
ユーザーとして実行されます。Docker によって割り当てられるデフォルトの Linux 機能では、root
として実行できるアクションが制限されますが、制限されるのはごくわずかです。例えば、root
として実行しているコンテナは、デバイスにアクセスすることがまだできません。
CI/CD パイプラインの一部として、Dockerfiles をリントして USER
ディレクティブを探し、見つからない場合はビルドを失敗させる必要があります。詳細については、以下の各トピックを参照してください。
-
Dockerfile-lint
は RedHat のオープンソースツールで、ファイルがベストプラクティスに準拠しているかどうかを確認するために使用できます。 -
Hadolint
も、ベストプラクティスに準拠した Docker イメージを構築するためのツールです。
読み取り専用のルートファイルシステムを使用する
読み取り専用のルートファイルシステムを使用してください。コンテナのルートファイルシステムは、デフォルトでは書き込み可能です。コンテナに RO
(読み取り専用) ルートファイルシステムを設定すると、データを保存できる場所を明示的に定義する必要性が生じます。これにより、権限が具体的に付与されない限りコンテナのファイルシステムに書き込みができなくなるため、アタックサーフェスが減少します。
注記
ルートファイルシステムが読み取り専用であると、そのファイルシステムへの書き込みが可能であることを想定している特定の OS パッケージで問題が発生する可能性があります。読み取り専用のルートファイルシステムを使用する予定がある場合は、事前に十分にテストしてください。
CPU とメモリの制限を設定してタスクを設定する (Amazon EC2)
以下のリスクを最小限に抑えるには、CPU とメモリの制限を設定してタスクを設定する必要があります。タスクのリソース制限は、タスク内のすべてのコンテナで予約できる CPU とメモリの量の上限を設定します。制限が設定されていない場合、タスクはホストの CPU とメモリにアクセスできます。これにより、共有ホストにデプロイされたタスクが他のタスクのシステムリソースを枯渇させるという問題が発生する可能性があります。
注記
Amazon ECS on AWS Fargate Tasks では CPU とメモリの制限を指定する必要があります。これらの値は請求目的で使用されるためです。Amazon ECS Fargate では、1 つのタスクがすべてのシステムリソースを占有しても問題にはなりません。各タスクは専有インスタンスで実行されるからです。メモリ制限を指定しない場合、Amazon ECS は各コンテナに最低 4MB を割り当てます。同様に、タスクに CPU 制限が設定されていない場合、Amazon ECS コンテナエージェントはタスクに最低 2 つの CPU を割り当てます。
Amazon ECR でイミュータブルタグを使用する
Amazon ECR では、イミュータブルタグを使用してイメージを設定することができるので、これを使用するようにしてください。これにより、変更または更新されたバージョンの画像が、同一のタグで画像リポジトリにプッシュされるのを防ぐことができます。また、攻撃者が侵害されたバージョンのイメージを同じタグが付いたイメージにプッシュすることを防ぐことができます。イミュータブルタグを使用すれば、変更するたびに異なるタグが付いた新しいイメージを効果的にプッシュできます。
コンテナを特権として実行することは避けてください (Amazon EC2)
コンテナを特権として実行することは避けてください。バックグラウンドでは、privileged
として実行されるコンテナは、ホスト上で拡張された権限でされます。つまり、ホスト上で root
に割り当てられた Linux 機能がすべてコンテナに継承されるということです。その使用は厳しく制限するか禁止してください。Amazon ECS コンテナエージェント環境変数 ECS_DISABLE_PRIVILEGED
を true
に設定して、privileged
が必要がない場合はコンテナが privileged
として特定のホストで実行されないようにすることをお勧めします。あるいは、AWS Lambda を使用してタスク定義をスキャンして privileged
パラメータを使用することもできます。
注記
AWS Fargate 上の Amazon ECS では、コンテナを privileged
として実行することはサポートされていません。
不要な Linux 機能をコンテナから削除する
Docker コンテナに割り当てられているデフォルトの Linux 機能のリストを以下に示します。各機能の詳細については、「Linux 機能の概要
CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_SETGID, CAP_SETUID, CAP_SETPCAP, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SYS_CHROOT, CAP_MKNOD, CAP_AUDIT_WRITE, CAP_SETFCAP
コンテナが上記の Docker カーネル機能のすべてを必要としない場合は、それらをコンテナから削除することを検討してください。各 Docker カーネル機能の詳細については、「KernelCapabilities」を参照してください。次の操作を実行することで、どの機能が使われているかを確認できます。
カスタマーマネージドキー (CMK) を使用して Amazon ECR にプッシュされるイメージを暗号化する
Amazon ECR にプッシュされるイメージの暗号化には、カスタマーマネージドキー (CMK) を使用してください。Amazon ECR にプッシュされたイメージは、保存時に AWS Key Management Service (AWS KMS) 管理キーで自動的に暗号化されます。独自のキーを使用したい場合は、Amazon ECR ではカスタマーマネージドキー (CMK) による AWS KMS 暗号化がサポートされています。CMK によるサーバー側の暗号化を有効にする前に、「保管データ暗号化」に関するドキュメントに記載されている考慮事項を確認してください。