Google Cloudとコンテナの継続的なセキュリティ
本文の内容は、2019年1月12日にSysdigのMateo Burilloが投稿したブログ(https://sysdig.com/blog/oss-container-security-runtime/)を元に日本語に翻訳・再構成した内容となっております。
DockerとKubernetesを採用しているすべての組織にとって、コンテナーのセキュリティは最も重要です。このオープンソースセキュリティガイドは、DockerとKubernetesのための完全なオープンソースコンテナーセキュリティスタックの実装方法を学びたい人のための理解を深めるためのガイドです。
コンテナプラットフォームの保護は、開発からプロダクション化までの複数ステップのプロセスで考えます。
セキュリティは、ホスト、Docker、Kubernetesなどのインフラストラクチャ層で実装する必要があると、アプリをコンテナとしてパッケージ化するためのDockerセキュリティベストプラクティスで述べました。Kubernetesセキュリティガイドでは、RBAC、TLS、podセキュリティポリシー、ネットワークポリシーなど、Kubernetesのクラスタ、コンポーネントを保護し、Kubernetesの機能を使用してアプリのセキュリティを強化する方法について説明しています。
しかし下記のようなセキュリティがさらに必要です:
以下の記事は、有用な情報ですので是非ご覧ください:
ランタイムセキュリティは、すべての事象の一部分です、すなわち、コンテナとその内部プロセスが実行されると発生します。
コンテナが予期した通りに実行されていない場合、既知の脆弱性を悪用する攻撃である可能性があります - そしてこれはコンテナイメージスキャンで潜在的に捕らえられることができます - がこのアプローチ以外に考えられる理由があります。 以下から保護するためにランタイムコンテナのセキュリティが必要です:
ランタイムコンテナセキュリティは、実行時に動作を監視することで実装できます。 コンテナは単純(通常は必要な依存関係とライブラリだけを持ち、多くの場合はマイクロサービスアプリケーションの一部として、単一タスクを実行する単一プロセス)なので、標準的な動作から逸脱している行動を検出する、すなわち、厳密なホワイトリストを使用して動作パターンを定義するのは比較的簡単です:
ブラックリスト、つまり決して起こらないことがわかっている行動パターンによって、セキュリティ侵害の指標を特定することもできます:
セキュリティランタイムフレームワークを構成するコンポーネント:
コンテナの異常な動作を検出することはステップ1であり、ステップ2は自動化された方法で攻撃に対応したり軽減することです。 DockerとKubernetesの世界では、次の点に留意することが重要です。
さまざまなLinuxランタイムセキュリティのオープンソースツールがあります。 Seccomp、SELinux / Auditd、およびAppamorは、コンテナに適用できる従来のシステムコール監査およびエンフォースメントツールです。
Sysdig Falcoは、ビヘイビアモニタリングにフォーカスしています:
他のランタイムセキュリティツールとFalcoとの比較については、「SELinux, Seccomp, Sysdig Falco, and you: A technical discussion」をご覧ください。
Falcoは、そのルールがDockerコンテナーまたはKubernetesオーケストレーションメタデータ(コンテナー情報、namespaces、deployment、podなど)と一緒に低レベルのオペレーティングシステムインターフェイス(syscalls)からのコンテキストを使用できるため、非常に効率的です。
たとえば、以下のような想定しているソケット以外のリスニングソケットを検出するFalcoルールを作成できます。
それ以外の場合は、アラートがトリガーされます:
condition: evt.type in (accept,listen) and (container.image!=myregistry/nginx or proc.name!=nginx or k8s.ns.name!="load-balancer")
これは、さまざまなソースからの条件を組み合わせた例です。
運用エンティティを完全に理解する正確なセキュリティルールを作成するために必要な柔軟性と表現力を兼ね備えています。
Falcoはコンテナ内で何が起こっているのかを詳細に可視化しますが、完全なコンテナセキュリティスタックを作成するには追加のコンポーネントが必要です。 Kubernetesランタイムセキュリティスタックを構築するために結び付けることができるオープンソースコンポーネントがあります:
Kubernetesアプリケーションの管理にすでにHelmを使用している場合は、Falco Helmチャートを使用して簡単なコマンドでFalcoを数秒でインストールできます。
$ helm install --name sysdig-falco-1 --set integrations.natsOutput.enabled=true stable/falco
この方法はいくつかのアドバンテージがあります:
このインストール方法の詳細については、「Automate Sysdig Falco Deployment Using Helm Charts」を参照してください。
私たちのほとんどは、オープンソースコンポーネントを使ってCloud Nativeアプリケーションを構築しています。 このようにして、最も人気のあるコンテナイメージ用のFalcoデフォルトルールセットライブラリを作成しました。
これらのイメージを使用してサービスを構築したり、アプリケーションをコンテナ化するための基本イメージとして使用している場合は、単にボリュームパスとネットワーク接続を調整して開始することができます。 GitHubレポジトリ:falco-extrasには、次のルールがあります。
例として、Nginxルールセットがどのようにlsコマンドを検出するのかを見てみましょう。
$ sudo cp ~/falco-extras/rules/rules-nginx.yaml /etc/falco/falco_rules.local.yaml
$ sudo service falco restart
$ docker run -d -P --name mynginx nginx
$ docker exec mynginx ls
$ cat /var/log/falco.log
11:03:13.464648222: Notice Unexpected process spawned in nginx container (command=ls pid=26942 user=root mynginx (id=4f94bdd87187) image=nginx)
lsコマンドは、このテンプレートのホワイトリストバイナリではありません。
これらのデフォルトのFalcoランタイムセキュリティルールセットを使用すると、そうでなければ一般的なイメージ用のランタイムセキュリティポリシーの作成に費やす時間を節約できます。 ただし、Dockerコンテナーイメージのすべてのバージョンまたはタグでさえも一意であり、ユーザー定義のデータディレクトリ、バイナリパス、外部ポートやデバイスにアクセスする必要があるスクリプト、または設定が異なる場合があります。 実際に本番環境で使用する前に、テンプレートをあなたの仕様に合わせる必要があります。
ライブラリからこれらのルールセットを使用し、さらにHelmチャートを使用してカスタマイズしたい場合は、このスクリプトを使用してHelm設定を生成します。
$ git clone https://github.com/draios/falco-extras.git
$ cd falco-extras
$ ./scripts/rules2helm rules/rules-traefik.yaml rules/rules-redis.yaml > custom-rules.yaml
$ helm install --name sysdig-falco-1 -f custom-rules.yaml stable/falco
「Implementing Docker / Kubernetesランタイムセキュリティ」には、Falcoのデフォルトルールセットのライブラリに関する詳しい説明、実用的な例、および詳細情報があります。
Kubernetes Response Engineコンポーネントのデプロイ:NATSとKubelessフレームワーク
NATSおよびKubelessコンポーネントをKubernetesクラスタにインストールするには、次の前提条件を満たす必要があります:
$ pip install -user pipenv
上記のリストを確認したら、Falcoリポジトリを複製してから、次の手順を実行します。
$ git clone https://github.com/draios/falco.git
$ cd integrations/kubernetes-response-engine
$ cd deployment/cncf
$ make
makeは、KubernetesオペレータとKubernetesカスタムリソースを利用するKubelessフレームワークを使用してNATSをデプロイするためにkubectlを使用します。nats-operatorは、デプロイを完了してオブジェクトの処理を開始するために追加の時間がかかる場合があります。kind: NatsClusterです。 デプロイが完了したら、さまざまなKubernetesセキュリティプレイブックを設定できます。
レスポンスエンジンはセキュリティイベントを分類して保存し、信頼できるタイムスタンプ、発行、キューイング、およびサブスクウリプションメカニズムを提供します。 今、私たちは1つまたは複数のイベントをサブスクリプションしていて、望ましい行動、反応、または軽減を引き起こすコンシューマーを必要としています。これが「Kubernetesセキュリティプレイブック」と呼ばれるものです。
私たちのプレイブックは現在、Kubeless関数を使って実装されています。 Kubelessは私達が機能を展開してNATSトピックをサブスクライブすることを可能にします、それでそれは完全にマッチしています。
一致するNATSメッセージを受信するたびに、Kubeless関数が実行されます。 この設計により、モジュール性と構成可能性が可能になり、各トピックフィルタまたはカテゴリ全体に反応する独立した機能を実行できます。
プレイブック機能がトリガーされるまでのFalcoアラートのシーケンスは、システムのさまざまなコンポーネントを巡る旅(ジャーニー)の後に続きます:
falco.{severity}.{rule name slugified} i.e. falco.error.write_below_etc
3. Kubeless関数はさまざまなNATSトピックをサブスクライブすることができます。これにより、必要に応じてさまざまなアラートをグループ化、フィルタ処理、または無視し、宣言したグループ/フィルタごとに異なるアクションを実行できます。たとえば、falco.warning.* に関するメッセージは通知をトリガーしますが、特にfalco.error.write_below_etcはコンテナーの削除をトリガーします。
Webhookを使って通知を送信してみましょう!
たとえば、Slackアプリを作成し、詳細を承認して設定したら、カスタムURLを使用してメッセージをチャンネルに投稿できます。
簡単に "catch-all"通知機能を作成することができます。
$ cd reactions
$ ./deploy_playbook -r slack -e SLACK_WEBHOOK_URL=https://<custom_slack_app_url> -t "falco.*.*"
これは、NATS falco.*.* topic(s)をサブスクライブするKubeless関数をデプロイします。
複数のオプションを指定する必要がある場合は、-eパラメーターを複数回使用できます。 -tパラメーターを複数回使用して、Kubeless関数を複数のトピックにサブスクライブすることもできます。
テストを行うだけの場合は、Falcoにはデフォルト設定に含まれるいくつかのFalcoアラート条件を意図的に起動するfalco-event-generator podが含まれています。数秒以内にあなたのSlackチャンネルでこれらのイベントを受け取ることができます:
インシデントに対応するためのより厳密な反応は、セキュリティ警告を引き起こしたPodを直接 killすることです。 これはKubernetes APIに接続してそのPodを削除することで行われます。
同様のコマンドを使用して、この機能をKubelessにデプロイすることもできます。
$ ./deploy_playbook -r delete -t "falco.notice.terminal_shell_in_container"
FalcoからTerminal shell in container alertを受け取るたびに、このリアクションはKubernetes APIを介してPodを停止しているコンテナーをkillします。
非常に興味深いレスポンスは、問題となっているコンテナが実行されていたノードを脇に置くことです。そのため、他に何もスケジュールされていません。 アラートが発生したKubernetesノードにさまざまな効果を得るためにフラグ(taintsとtolerations)を割り当てることができます。
$ ./deploy_playbook -r taint -t "falco.notice.contact_k8s_api_server_from_container" [-e PARAMETER]
パラメーター:
この例では、パラメータなしで実行しています。デフォルトのtaint falco/alert=true:NoScheduleを使用します。そのため、特定の感染を許容できない限り、このノードにニュースポッドはスケジュールされません。 より積極的なアプローチを使用して、-e TAINT_EFFECT=NoExecuteを設定すると、影響を受けるノードをドレインできます。
攻撃者が近くのリソースを乗っ取ってクラスタに拡散しようとしていると思われる場合(ネットワークスキャン、脆弱性調査、外部IPアドレスへの接続など)、Podをネットワークから分離することができます。
「分離」対応は、ポッドからのすべての入力/出力トラフィックを拒否します。 この対応には、KubernetesネットワークポリシーをサポートするKubernetesクラスタ/ Podオーバーレイネットワークが必要です。
$ ./deploy_playbook -r isolate -t "falco.notice.unexpected_network_connection"
そのため、予期しないネットワーク接続に気付くとすぐに、そのPodを切り離して、それ以上のネットワークアクティビティを回避します。
プレイブックを実行することに加えて、セキュリティイベントのレポート、履歴トレンドの視覚化、またはデータマイニングを可能にするために、長期的なイベントストレージを用意することをお勧めします。
FluentdはデフォルトでいくつかのKubernetesディストリビューションにデプロイされているので、ここではEFK(Fluentd、Elastic、Kibana)スタックを使用することにします。
FalcoのJSON形式のイベント出力をstdoutに有効にすると、Fluentdはそこから取得します。 以下の方法については、「FalcoおよびFluentdを使用したKubernetesセキュリティログ」に詳細なデプロイメント手順と設定オプションがあります:
KibanaにおけるFacloセキュリティイベント
しかし、すでにSIEM製品を使用しているのであれば、Falcoアラートを統合することも非常に簡単です。 例として、Google Cloud Security Command Center用のFalcoコネクタを作成しました。
SCCのKubernetes情報におけるFalcoセキュリティイベント例
ランタイムコンテナセキュリティはDockerとKubernetesのセキュリティ戦略にとって非常に重要であり、オープンソースツールを使って実装することもできます。
この記事では、FalcoランタイムセキュリティツールをHelm、NATS、Kubelessなどの典型的なCloud Native Kubernetesツールと統合して、包括的なオープンソースコンテナセキュリティスタックを構築する方法を説明しました。
面白そうですか? これをオープンソースコンテナのセキュリティスタック全体として使うことができればいいのですが、もっと自分に役立つアイディアやツールを選んで、それらをあなたのユースケースに合わせてカスタマイズするのもいいでしょう。
しかし、ランタイムセキュリティに加えて、まだ完了していません。Dockerイメージスキャンを統合し、「オープンソースコンテナセキュリティを実装する方法:第2部Dockerイメージスキャン」に進んでいきます。
もし、好きになっていただいたあなたがこのプロジェクトに貢献する方法が多くあります:
SysdigのオープンソースSlackコミュニティ、#open-source-sysdigに関するディスカッションに参加するか、または@sysdigでTwitter経由で私たちに連絡してください!