Google Cloudとコンテナの継続的なセキュリティ
本文の内容は、2021年10月12日に Álvaro Iradierが投稿したブログ(https://sysdig.com/blog/container-security-best-practices/)を元に日本語に翻訳・再構成した内容となっております。
コンテナセキュリティのベストプラクティスにこだわることは、検証済みソフトウェアの提供を成功させるだけでなく、深刻なセキュリティ侵害とその結果を防ぐためにも重要です。
2020年のCNFC調査によると、92%の企業が本番環境でコンテナを使用しており、2016年から300%増加しています。このように、KubernetesやOpenshiftなどのコンテナ技術はあらゆる場所に存在しています。
しかし、コンテナは安全で隔離されたものではないのでしょうか?まあ、そんなところです。
例えば、コンテナ内部の悪用可能な脆弱性が、露出したメタデータや誤った認証情報の設定と組み合わさると、クラウドのインフラ全体を危険にさらすことになります。クラウドラテラルムーブメントの記事で説明したように、ハッカーは、この一連の脆弱性と誤った設定を利用して、お客様のクラウドアカウントでクリプトマイニングアプリケーションを実行することができます。
コンテナは、自己完結型アプリケーションの配布メカニズムとして設計されており、分離された環境でプロセスを実行できるようになっています。 分離の目的で、カーネルカーネルネームスペースを使用する軽量メカニズムを採用し、完全なオペレーティングシステム、CPUとハードウェアの仮想化など、VM内のいくつかの追加レイヤーの要件を排除しています。
このような追加の抽象化レイヤーがないことや、カーネル、オペレーティングシステム、コンテナランタイムとの緊密な結合により、コンテナの内部から外部へ、またはその逆にジャンプするためのエクスプロイトが利用しやすくなります。コンテナセキュリティの機能イメージ
コンテナセキュリティのベストプラクティスには、配信されるアプリケーションやコンテナイメージ自体だけでなく、コンテナのビルド、配布、特別な実行に使用されるコンポーネントスタック全体も含まれます。
これには以下が含まれます:
セキュリティは、開発、配布、実行、検知、脅威への対応など、それぞれの段階で適用することができます。
それでは、一般的な考え方を、DevOpsのワークフローに適用できる18の具体的なコンテナセキュリティのベストプラクティスに分解しながら、興味深い詳細を見ていきましょう。
コンテナの成功は、2つの便利な機能によって支えられています。
VMとコンテナの比較
ほとんどの場合、コンテナのセキュリティモデルで十分かもしれませんが、例えば、AWSはサーバーレスソリューションに追加のセキュリティを加えています。これは、Firecrackerというマイクロ仮想マシンの中でコンテナを実行することで実現しています。このマイクロ仮想マシンは、顧客間での侵入を防ぐために、もう一つのレベルの仮想化を追加します。
これはコンテナが安全ではないということなのでしょうか?
それは諸刃の剣だと言えます。
コンテナの中で動作するアプリケーションは、マシンの中で直接動作するアプリケーションと変わらず、他の多くのアプリケーションとファイルシステムやプロセスを共有しています。ある意味では、悪用可能な脆弱性を含む可能性のあるアプリケーションに過ぎません。
コンテナ内で実行すると、これを防ぐことはできませんが、アプリケーションのエクスプロイトからホストシステムにジャンプしたり、他のアプリケーションからデータにアクセスしたりすることが非常に困難になります。
一方で、コンテナは、別のカーネル機能、コンテナランタイム、そして通常はクラスターやオーケストレータに依存しており、これらも悪用される可能性があります。
そのため、スタック全体を考慮する必要があり、コンテナのライフサイクルのさまざまな段階でコンテナセキュリティのベストプラクティスを適用することができます。この2つの次元を以下の図に反映させ、各ブロックで適用できるプラクティスに焦点を当ててみましょう:
サーバーレスのコンピュートエンジンであるECS FargateやGoogle Cloud Runなどのように、これらのピースの一部が我々の手に負えない場合もあるので、責任共有モデルで対応しています。
責任共有モデル
シフトレフトセキュリティ
コンテナ内のアプリケーションが実行される前に、脅威の発生を防ぐためのさまざまな技術を適用できる場所がいくつかあります。
予防とセキュリティの早期適用が重要であり、コンテナイメージの開発と配布時にいくつかのグッドプラクティスを適用すれば、最小限の労力で多くのトラブル、時間、コストを削減することができます。
セキュリティスキャンとは、ソフトウェア、構成、インフラを分析し、潜在的な問題や既知の脆弱性を検出するプロセスです。スキャンは、さまざまな段階で行うことができます。
最初のステージであるコードに注目してみましょう。アプリケーションの提供を行う前に、あるいはアプリケーションをビルドする前に、コードをスキャンしてバグや悪用される可能性のあるコード(新しい脆弱性)を検出することができます。
アプリケーションコードについては、さまざまな言語に対応した脆弱性スキャナを提供するsonarqubeや、goのコードを分析し、ルールやリンターなどに基づいて問題を検出するgosecなど、さまざまなSAST(Static Application Security Testing)ツールがあります。
これらを開発者のマシンで実行することもできますが、コードスキャンツールをCI/CDプロセスに統合することで、最低限のコード品質を確保することができます。例えば、いくつかのチェックが失敗した場合、プルリクエストをデフォルトでブロックすることができます。
gosecをGithub Actionで実行する:
name: "Security Scan" on: push: jobs: tests: runs-on: ubuntu-latest env: GO111MODULE: on steps: - name: Checkout Source uses: actions/checkout@v2 - name: Run Gosec Security Scanner uses: securego/gosec@master with: args: ./...
そして、それに対応する出力:
サードパーティ製のライブラリやフレームワークを使用しないのは、非常にミニマムでトイなアプリケーションだけです。しかし、外部の依存関係にあるコードを再利用することは、これらの依存関係にあるバグや脆弱性をアプリケーションの一部として含むことになります。依存関係のスキャンは、あらゆるアプリケーションのビルドプロセスにおいて、ベストプラクティスとして含めるべきです。
npm、maven、goなどのパッケージ管理ツールは、脆弱性データベースとアプリケーションの依存関係を照合し、有用な警告を提供することができます。
例えば、Mavenでdependency-checkプラグインを有効にするには、pom.xmlにプラグインを追加するだけです:
<project> ... <build> ... <plugins> ... <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> <version>6.2.2</version> <executions> <execution> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> ... </plugins> ... </build> ... </project>
そして、mavenが実行されるたびに、脆弱性レポートが生成されます:
依存関係にあるものを、修正を加えた新しいバージョンに更新することで、依存関係による脆弱性の導入を回避します。依存関係のツリー
場合によっては、修正プログラムが利用できなかったり、バージョンを上げるには、破壊的な変更のために多くのリファクタリングが必要になったりするため、これができないこともあります。依存関係のスキャンによって明らかになった脆弱性を分析して、その影響度や悪用可能性を評価し、その脆弱性が悪用されるのを防ぐために、コード内のチェックや保護メカニズムなどの追加措置を導入します。
なお、依存関係を後からスキャンすることも可能ですが、アプリケーションがビルドされると、メタデータの情報が得られないものもあるため、依存関係のスキャンの精度は低くなります。また、GoやRustのように静的にリンクされたアプリケーションでは不可能な場合もあります。
アプリケーションがビルドされ、パッケージ化されると、ライブラリ、依存するフレームワーク(Python、Nodeなど)、設定ファイルの最小限のセットを持つコンテナ内にコピーするのが一般的です。コンテナのビルドとランタイムに焦点を当てたベストプラクティスについては、「Dockerfileのベストプラクティス Top 20」をお読みください。
イメージスキャナーを使用してコンテナイメージを分析します。イメージスキャンツールは、コンテナイメージのベースディストリビューションが提供するオペレーティングシステムパッケージ(rpm、dpkg、apkなど)の脆弱性を発見します。また、前の段階で依存関係のスキャンを適用していなくても、Java、Node、Pythonなどのパッケージの依存関係にある脆弱性も発見されます。イメージスキャンのスキーマ
イメージスキャンは、自動化と実施が容易です。CI/CDパイプラインの一部として組み込んだり、新しいイメージがレジストリにプッシュされたときにトリガーしたり、クラスターアドミッションコントローラーで検証して、非準拠のイメージの実行が許可されたことを確認したりすることができます。また、Sysdig Node Image Analyzerをインストールして、Sysdig Node Image Analyzerが稼働しているホストでイメージの実行が開始されると同時にスキャンするという方法もあります。
例としては、Sysdig Secure Inline Scan ActionとGithub Actionの統合があります。
name: "Security Scan" on: push: jobs: build-and-scan: runs-on: ubuntu-latest steps: - name: Build the Docker image run: docker build . --file Dockerfile --tag my-image:latest - name: Scan image id: scan uses: sysdiglabs/scan-action@v3 with: image-tag: my-image:latest sysdig-secure-token: ${{ secrets.SYSDIG_SECURE_TOKEN }} input-type: docker-daemon run-as-user: root
前述の例では、Dockerイメージをビルドしてから、Dockerデーモンからローカルにスキャンしています。
スキャン結果はアクションの出力の一部として直接提供され、pull-requestはチェックステータスに応じてマージをブロックすることができます:脆弱性をリストアップ
コンテナイメージの完全性は、Docker Notaryなどを介してデジタル署名を追加することで強制することができ、アドミッションコントローラーやコンテナランタイムで検証することができます。
簡単な例を見てみましょう:
$ docker trust key generate example1 Generating key for example1... Enter passphrase for new example1 key with ID 7d7b320: Repeat passphrase for new example1 key with ID 7d7b320: Successfully generated and loaded private key. Corresponding public key available: /Users/airadier/example1.pub
これで、「example1」という署名鍵ができました。公開部分は以下の場所にあります:
$HOME/example1.pub
秘密鍵は次の場所にあります:
$HOME/.docker/trust/private/<key ID>.key
他の開発者も自分の鍵を生成し、公開部分を共有することができます。
それでは、許可された署名者の鍵をリポジトリに追加することで、署名付きリポジトリを有効にします(例ではairadier/alpine):
$ docker trust signer add --key example1.pub example1 airadier/alpine Adding signer "example1" to airadier/alpine... Initializing signed repository for airadier/alpine... ... Enter passphrase for new repository key with ID 16db658: Repeat passphrase for new repository key with ID 16db658: Successfully initialized "airadier/alpine" Successfully added signer: example1 to airadier/alpine
そして、リポジトリのイメージに署名することができます:
$ docker trust sign airadier/alpine:latest Signing and pushing trust data for local image airadier/alpine:latest, may overwrite remote trust data The push refers to repository [docker.io/airadier/alpine] bc276c40b172: Layer already exists latest: digest: sha256:be9bdc0ef8e96dbc428dc189b31e2e3b05523d96d12ed627c37aa2936653258c size: 528 Signing and pushing trust metadata Enter passphrase for example1 key with ID 7d7b320: Successfully signed docker.io/airadier/alpine:latest
環境変数 DOCKER_CONTENT_TRUST
が 1
に設定されていれば、プッシュされたイメージは自動的に署名されます:
$ export DOCKER_CONTENT_TRUST=1 $ docker push airadier/alpine:3.11 The push refers to repository [docker.io/airadier/alpine] 3e207b409db3: Layer already exists 3.11: digest: sha256:39eda93d15866957feaee28f8fc5adb545276a64147445c64992ef69804dbf01 size: 528 Signing and pushing trust metadata Enter passphrase for example1 key with ID 7d7b320: Successfully signed docker.io/airadier/alpine:3.11
イメージの署名者を確認するには、次のようにします:
$ docker trust inspect --pretty airadier/alpine:latest Signatures for airadier/alpine:latest SIGNED TAG DIGEST SIGNERS latest be9bdc0ef8e96dbc428dc189b31e2e3b05523d9... example1 List of signers and their keys for airadier/alpine:latest SIGNER KEYS example1 7d7b320791b7 Administrative keys for airadier/alpine:latest Repository Key: 16db658159255bf0196... Root Key: 2308d2a487a1f2d499f184ba...
環境変数 DOCKER_CONTENT_TRUST
が 1
に設定されていると、Docker CLIは信頼情報のないイメージのプルを拒否します:
$ export DOCKER_CONTENT_TRUST=1 $ docker pull airadier/alpine-ro:latest Error: remote trust data does not exist for docker.io/airadier/alpine-ro: notary.docker.io does not have trust data for docker.io/airadier/alpine-ro
Connaisseurのようなアドミッションコントローラーを使うことで、Kubernetesクラスターでコンテンツの信頼性を確保することができます。
ホスト、コンテナランタイム、クラスター、クラウドのリソースが誤って設定されていると、攻撃への扉が開いたままになったり、特権を昇格させてラテラルムーブメントを行うための簡単な方法が生まれたりします。
ベンチマーク、ベストプラクティス、およびハードニングガイドでは、これらの誤設定を発見する方法、問題となる理由、および修正方法に関する情報を提供しています。様々な情報源の中でも、Center for Internet Security (CIS) は最も重要です。非営利団体であるCISは、様々な環境のベンチマークを無料で公開しており、個人や企業がその知識を活かしてコントリビュートすることができます。これは、セキュリティベンチマークのデファクトスタンダードとなっています。
コンテナのセキュリティに関するこのような設定を確実にチェックするには、できるだけ自動化するのが一番です。そのためのツールがいくつか存在し、主に静的な設定分析をベースに、さまざまなレベルの設定パラメータをチェックし、修正のガイダンスを提供することができます。
Sysdig Secureには、コンプライアンス&ベンチマーク機能があり、CISベンチマークをはじめ、PCI DSS、SOC 2、NIST 800-53、NIST 800-190、HIPAA、ISO 27001、GDPRなどのコンプライアンス基準に基づいて、すべてのインフラ(Linuxホスト、Docker、Kubernetes、EKS、GKE、Openshiftクラスターなど)をスケジュール、実行、分析することができ、すべてを1つの集中ダッシュボードで行うことができます。Sysdigのセキュアダッシュボード
他にも、linux-bench、docker-bench、kube-bench、kube-hunter、kube-striker、Cloud Custodian、OVAL、OS Queryなどのツールを利用することができます。
Linuxをインストールしたばかりの物理マシン、クラウドプロバイダーでプロビジョニングされた仮想マシン、またはオンプレミスの仮想マシンには、あなたが気付いていない安全でないアウトオブボックスの設定がいくつか含まれている可能性があります。長期間、本番環境で使用したり、インターネットに接続したりする場合は、特に注意しなければなりません。これはKubernetesやOpenShiftのノードにも言えることです。クラウドプロバイダーがプロビジョニングしたクラスターを使用しているからといって、そのクラスターが完全に保護されているとは思わないでください。
CISでは、ディストリビューションに依存しないLinuxのベンチマークを用意しており、Debian、CentOs、Red Hatなど多くのディストリビューションに対応しています。
検出できる設定ミスの例:
次の図は、CIS Benchmark for Distribution Independant Linuxで提供されているもので、rshサーバが有効になっていないことを確認するための設定です。
Dockerのようなコンテナランタイムを自分で所有するサーバにインストールする場合、ベンチマークを使ってデフォルトの安全でない構成が改善されていることを確認することが不可欠です。次の図は、Dockerクライアントコマンドの認証が有効になっていることを確認するための設定です。
Kubernetesは、デフォルトでは、多くの認証メカニズムをサードパーティの統合によって管理するようになっています。ベンチマークにより、考えられるすべての不安要素に対処することができます。下の画像は、-anonymous-auth引数がfalseに設定されていることを確認するための設定を示しています。
クラウドプロバイダーのアカウントにおけるベンチマークは、CSPM(Cloud Security Posture Management)とも呼ばれ、アカウント上のすべての資産のセキュリティをチェックするため、必要不可欠なものです。攻撃につながる可能性のある設定や、プライベートであるべきなのに公開されているリソース(S3バケットなど)、暗号化されていないストレージなどはすべてこのようなベンチマークで定義されます。クラウドアカウントの資産は常に変化しており、すべてが可能な限り安全であることを常に監視しなければならないため、これは自動化が必須のベンチマークです。次の画像は、90日以上使われていない認証情報が無効になっていることを確認する設定チェックの例です。
クラウドのリソース管理は複雑な作業であり、TerraformやCloudFormationなどのツールはこの負担を軽減してくれます。インフラはコードとして宣言され、別名「Infrastructure as Code」として、リポジトリに保存され、バージョン管理されます。そして、定義の変更を適用して、既存のインフラを宣言に合わせて最新の状態にすることは、自動化によって行われます。
コードとしてのインフラストラクチャーを使用している場合、Apolicy、Checkov、tfsec、cfn_nagなどのIaCスキャンツールを組み込んで、インフラストラクチャーを作成または更新する前にその構成を検証します。他のリンティングツールと同様に、IaCスキャンツールをローカルおよびパイプラインに適用し、セキュリティ上の問題を引き起こす変更をブロックすることを検討してください。
checkovの実行例です:
$ pip install checkov $ checkov --quiet -d . _ _ ___| |__ ___ ___| | _______ __ / __| '_ \ / _ \/ __| |/ / _ \ \ / / | (__| | | | __/ (__| < (_) \ V / \___|_| |_|\___|\___|_|\_\___/ \_/ By bridgecrew.io | version: 2.0.346 terraform scan results: Passed checks: 314, Failed checks: 57, Skipped checks: 0 Check: CKV_AWS_108: "Ensure IAM policies does not allow data exfiltration" FAILED for resource: aws_iam_policy_document.cloudtrail_ingestor File: /modules/ingestor/main.tf:17-31 Guide: https://docs.bridgecrew.io/docs/ensure-iam-policies-do-not-allow-data-exfiltration 17 | data "aws_iam_policy_document" "ingestor" { 18 | statement { 19 | effect = "Allow" 20 | actions = [ 21 | "s3:Get*", 22 | "s3:List*", 23 | "s3:Put*", 24 | "s3:Head*", 25 | "sqs:DeleteMessage", 26 | "sqs:DeleteMessageBatch", 27 | "sqs:ReceiveMessage", 28 | ] 29 | resources = ["*"] 30 | } 31 | } ...
ホストを保護することは、コンテナを保護することと同様に重要です。コンテナが実行されるホストは、通常、Linuxカーネル、一連のライブラリー、コンテナランタイム、その他の一般的なサービスやヘルパーがバックグラウンドで動作するオペレーティングシステムで構成されています。これらのコンポーネントには脆弱性や設定ミスがある可能性があり、実行中のコンテナにアクセスするためのエントリーポイントとして使用されたり、サービス拒否攻撃を受けたりする可能性があります。
例えば、今回のDoS攻撃のように、コンテナランタイム自体に問題があると、ホスト内で新しいコンテナを作成できなくなるなど、稼働中のコンテナに影響が出てしまうことがあります。
ホストの構成を強化することについては、「安全でない構成」のセクションですでに説明しました。しかし、脆弱なコンポーネントをどのようにして検出するのでしょうか。ホストスキャンツールは、カーネル、glibcなどの標準ライブラリ、サービス、さらにはホスト内のコンテナランタイムに存在する既知の脆弱性を検出することができます(コンテナイメージに対してイメージスキャンが行うのとよく似ています)。
Sysdig Host Analyzerは、ホストを透過的にスキャンし、発見された脆弱性をレポートします。 次の図は、ダッシュボード上で一目でリスクを検出することができることを示しています。
この情報を使って、OS、カーネル、パッケージなどをアップデートします。最も重要で悪用されやすい脆弱性を取り除くか、少なくともそれを認識し、ファイアウォール、ホストへのユーザーアクセスの制限、使用されていないサービスの停止など、他の保護メカニズムを適用してください。
最終的な防御策として、Kubernetes Admission Controllerは、安全でないコンテナがクラスター内で実行されるのをブロックすることができます。
Sysdig アドミッションコントローラーでは、スキャン結果に基づいて、セキュリティポリシーに合格しないイメージを実行しているポッドの作成を拒否することができます。
Gatekeeperには強力な言語が用意されており、ポッドの仕様(アノテーションの強制、特権ポッドの検出、ホストパスの使用など)やクラスターの状態(すべてのingressホストがクラスター内でユニークであることを要求するなど)に基づいて、コンテナの受け入れや拒否を行う柔軟なルールを定義することができます。
例として、以下のGatekeeper ConstrainsTemplate (一部のデータは省略されています)は、必要なアノテーションを検出するためのテンプレートを定義しています。
apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8srequiredannotations annotations: description: Requires all resources to contain a specified annotation(s) with a value matching a provided regular expression. spec: ... targets: - target: admission.k8s.gatekeeper.sh rego: | package k8srequiredannotations violation[{"msg": msg, "details": {"missing_annotations": missing}}] { provided := {annotation | input.review.object.metadata.annotations[annotation]} required := {annotation | annotation := input.parameters.annotations[_].key} missing := required - provided count(missing) > 0 msg := sprintf("you must provide annotation(s): %v", [missing]) } violation[{"msg": msg}] { value := input.review.object.metadata.annotations[key] expected := input.parameters.annotations[_] expected.key == key expected.allowedRegex != "" not re_match(expected.allowedRegex, value) msg := sprintf("Annotation <%v: %v> does not satisfy allowed regex: %v", [key, value, expected.allowedRegex]) }
このテンプレートを使用して、すべてのサービスがいくつかのアノテーションを持つことを強制することができます:
apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sRequiredAnnotations metadata: name: all-must-have-certain-set-of-annotations spec: match: kinds: - apiGroups: [""] kinds: ["Service"] parameters: message: "All services must have a `a8r.io/owner` and `a8r.io/runbook` annotations." annotations: - key: a8r.io/owner # Matches email address or github user allowedRegex: ^([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}|[a-z]{1,39})$ - key: a8r.io/runbook # Matches urls including or not http/https allowedRegex: ^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$
他にもたくさんの例が、OPA Gatekeeperライブラリープロジェクトで公開されています。
コンテンツの信頼性を確保し、信頼できるソースから署名されていないイメージを拒否する方法として、Connaisseur Admission Controllerを紹介しました。
ビルド時や構成時のコンテナセキュリティのベストプラクティスをランタイムの直前まで遵守しても、コンテナを100%安全にすることはできません。コンテナの新しい脆弱性は日々発見されているため、現在は安全な実際のコンテナも、明日には新たに公開されたエクスプロイトの被害者になる可能性があります。
このセクションでは、コンテナの脆弱性管理と保護対策をワークロードに組み込むための、コンテナセキュリティのベストプラクティスを紹介します。
お使いのコンテナやホストには脆弱性が含まれているかもしれませんし、新しい脆弱性は絶えず発見されています。しかし、危険なのはホストやコンテナの脆弱性そのものではなく、攻撃ベクトルや悪用可能性にあります。
例えば、ネットワークを悪用できる脆弱性の場合、実行中のコンテナや脆弱なサービスへの接続を妨げることで防御することができます。また、攻撃ベクトルがホストへのローカルアクセス(ホストにログインしていること)を必要とする場合、そのホストへのアクセスを制限することができます。
そこで、ホストやクラウドアカウント、リソースにアクセスできるユーザー数を制限し、さまざまな仕組みを使って不要なネットワークトラフィックを遮断します。
イメージコンテンツの信頼性で述べたように、イメージ署名は、イメージが改ざんされていないことを保証する保護メカニズムです。また、イメージ署名を検証することで、タグが発行者によって署名された特定のダイジェストに対応していることを保証し、タグの可変型攻撃の一部を防ぐことができます。下図はこの攻撃の一例です。
コンテナ内で悪用された脆弱性の範囲または「爆発半径」は、コンテナの権限と、ホストや他のリソースからの隔離レベルに大きく依存します。ランタイム時の設定は、以下の方法で既存および将来の脆弱性の影響を軽減することができます。
脆弱性を賢く管理・評価しましょう。すべての脆弱性に修正プログラムが用意されているわけではありませんし、今なら簡単に適用できるかもしれません。
しかし、すべての脆弱性が簡単に悪用できるとは限りませんし、悪用するためにはホストへのローカルまたは物理的なアクセスが必要な場合もあります。
など、しっかりとした戦略を立てる必要があります:
あなたの戦略は、コンテナの脆弱性スキャナーが、いくつかの基準に従って検出された脆弱性に対して警告を発し、次のような異なるレベルで予防と保護を適用するために使用できるポリシーに反映されるべきです:
また、継続的な脆弱性スキャンと再評価を行い、ランタイム中のコンテナに適用される新しい脆弱性が発見されたときにアラートを受け取るようにすることも重要です。Sysdig Secureは、脆弱性のフィードが更新されるたびにスキャンポリシーを再評価するので、ここでも役に立ちます。
ここまでは、予防と保護に焦点を当て、コンテナを可能な限り最高の状態で稼働させ、潜在的な攻撃や既知の攻撃を予測してきました。コンテナのビルド、配布、ランタイム時に予防技術を適用して、正しい権限と保護機能を持たせたり、基盤となるスタックを確保したりすることで、攻撃者の行動範囲を制限することができます。しかし、だからといって、コンテナの実行を忘れて、適用されたセキュリティ対策を信用することはできません。セキュリティ対策が実行されると、攻撃される可能性が出てきます。是正措置を講じてセキュリティインシデントの再発を防ぐためには、アプリケーションの異常な動作や予期せぬ動作を検知する必要があります。
さまざまな攻撃ベクターが存在します。例えば、MITRE ATT&CK は、「実世界での観察に基づく」戦術と技術の広範なリストを提供しており、これを使用して防止策を適用することも、活動を分析して攻撃や侵入が行われていることを意味する異常な動作を検出することもできます。MITRE ATT&CK Matrix for Containersは、特にコンテナ技術を対象とした技術をカバーしています。Mitre Schema
コンテナセキュリティへの脅威は、さまざまなログやイベントのソースを監査し、異常なアクティビティを分析することで検出できます。イベントのソースには次のようなものがあります。
Falcoは、実行されたシステムコールを監視し、不審なアクティビティに対するアラートを生成することができます。コミュニティに寄贈されたルールのライブラリが含まれており、簡単な構文を使って独自のルールを作成することができます。また、Kubernetesの監査ログにも対応しています。
Falcoの動作例は、Detecting MITRE ATT&CKの記事で見ることができます:
Sysdig SecureはFalcoの機能を拡張し、異なるクラウドプロバイダーからのイベントを取り込むこともできます。
例として、以下のルールは、新しいECSタスクがアカウントで実行されるたびにアラートをトリガします:
rule: ECS Task Run or Started condition: aws.eventSource="ecs.amazonaws.com" and (aws.eventName="RunTask" or aws.eventName="StartTask") and not aws.errorCode exists output: A new task has been started in ECS (requesting user=%aws.user, requesting IP=%aws.sourceIP, AWS region=%aws.region, cluster=%jevt.value[/requestParameters/cluster], task definition=%aws.ecs.taskDefinition) source: aws_cloudtrail description: Detect a new task is started in ECS.
また、Sysdigは、対応するコンプライアンス標準とコントロールでタグ付けされた増え続けるルールのセットを含み、インフラストラクチャーのすべてのセキュリティイベントを調査するための一元化されたダッシュボードを提供しています。
過剰なリソース使用量(CPU、メモリ、ネットワーク)、使用可能なディスク容量の急激な減少、平均以上のエラーレート、遅延の増加などは、システムで何か異変が起きていることを示すシグナルかもしれません。
Prometheusのようにメトリクスを収集してください。値が予想されるしきい値を超えたときに、すぐに通知されるようにアラートを設定します。意味のあるダッシュボードを使用して、メトリクスの変化を調べ、他のメトリクスの変化やシステムで発生しているイベントと関連付けることができます。Sysdigモニターのメトリクス
この例では、リクエストレイテンシーが急激に増加し、リクエストレートが低下していることがわかります。これは、コンテナ内で何かが起こっていることを意味しています(例えば、クリプトマイナーが利用可能なCPUをすべて消費しているなど)。または、レスポンスの低下や潜在的なDoSを引き起こすエクスプロイトがあることを意味しています。同時期に発生した関連するクラスターイベントを確認すると、ポッドが交換されているので、悪意のあるバージョンや単に設定が間違っているバージョンがデプロイされた可能性もあります。
システムでセキュリティインシデントが発生していることを検知したら、脅威を止め、さらなる被害を抑えるために行動を起こします。単にコンテナを停止したり、ホストをシャットダウンしたりするのではなく、コンテナを隔離したり、一時停止したり、スナップショットを取ったりすることを検討します。優れたフォレンジック分析は、多くの手がかりを提供し、何が、いつ、どのように起こったかを明らかにします。特定することが重要です。
セキュリティインシデントが検出されたら、それ以上の被害を抑えるために、まず迅速に停止させる必要があります。
フォレンジック調査の素晴らしい例を「脅威警報:人気のDiscordボットであるRinBotのサーバーを巻き込んだCrypto miner攻撃」でご覧ください。
調査では、攻撃を可能にした原因を明らかにする必要があります。攻撃原因が判明したら、再発防止のためのセキュリティ対策を行いましょう。ホスト、コンテナ、アプリケーションが危険にさらされる原因は、過剰なパーミッション、露出したポートやサービスなどの悪い設定、または悪用された脆弱性の場合があります。
前者の場合は、誤った設定を修正して、二度と起こらないようにします。後者の場合は、ファイアウォールなどの設定を変更したり、より制限の厳しいユーザーを使用したり、追加のパーミッションやACLなどでファイルやディレクトリを保護したりすることで、脆弱性が悪用されるのを防ぐ(あるいは少なくともその範囲を制限する)ことができるかもしれません。
この問題が環境内の他の資産にも適用される場合は、すべての資産に修正プログラムを適用してください。特に、リモートネットワーク接続を介してエクスプロイトを実行できる場合には、インターネットからアクセス可能なアプリケーションなど、公開される可能性があるものについては、修正を行うことが重要です。
可能な限り、脆弱性そのものを修正してください:
影響を受けるパッケージに適用できる修正プログラムがない場合でも、設定や保護手段(ファイアウォール、隔離など)によって脆弱性の悪用を防ぐことができるかもしれません。また、複雑で脆弱性に関する深い知識が必要になるかもしれませんが、自分のコードで追加のチェックを加えることができます。例えば、Web APIサーバで使用されているJSON処理ライブラリのオーバーフローによる脆弱性は、HTTPリクエストレベルでいくつかのチェックを追加し、オーバーフローにつながる可能性のある文字列を含むリクエストをブロックすることで防ぐことができます。
残念ながら、ホストとコンテナのセキュリティは、一連のセキュリティコンテナのグッドプラクティスを一度適用するだけで永遠に忘れることができるような一方通行のものではありません。ソフトウェアやインフラは日々進化しているため、複雑さが増し、新たなエラーが発生します。これは、脆弱性や構成上の問題につながります。また、新たな攻撃や悪用方法も絶えず発見されています。
まずは予防とセキュリティのベストプラクティスを盛り込むことから始めましょう。そして、ホストやワークロードだけでなく、クラウドサービスも含めたリソースに保護対策を施します。監視を継続し、異常な動作を検出して、発見されたインシデントに対処、対応、調査、報告します。フォレンジックの証拠があれば、発見された脆弱性を修正し、保護対策を改善して、イメージの再ビルド、パッケージの更新、リソースの再設定を行い、将来のセキュリティインシデントに備えてインシデントレポートを作成する、というループを閉じることができます。
中間では、リスクを評価し、脆弱性を管理する必要があります。複雑で大きな環境で管理すべきインプットの数は圧倒的に多いので、分類して優先順位をつけ、最もリスクの高いものから集中的に管理します。
コンテナセキュリティのベストプラクティスが、DevOpsのワークフローに簡単に適用できることを確認しました。特に、以下のことを覚えておいてください:
コンテナセキュリティのベストプラクティスは、配信されるアプリケーションやコンテナイメージそのものだけではないことを忘れないでください。また、コンテナのビルド、配布、実行に使用される完全なコンポーネントスタックも含める必要があります。
54%のコンテナの稼働時間は5分以内であり、異常な動作や違反を調査することは非常に困難です。
クラウドネイティブセキュリティの重要なポイントの1つは、コンテナのセキュリティリスクにできるだけ早く対処することです。開発ライフサイクルの後半に行うと、クラウド導入のペースが遅くなるだけでなく、セキュリティやコンプライアンスのリスクが高まります。
Sysdig Secureは、これらのコンテナセキュリティのベストプラクティスに従うことを支援します。脆弱性や設定ミスをチェックすることで、セキュリティをシフトレフトさせ、脅威が展開される前に行動できるようになります。わずか数分で設定が完了します。今すぐお試しください!