オープンソースでランタイムコンテナセキュリティをKubernetes上に実装する (パート 1)
本文の内容は、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の機能を使用してアプリのセキュリティを強化する方法について説明しています。
しかし下記のようなセキュリティがさらに必要です:
- イメージの脆弱性:アプリ用のイメージを作成している場合、または変更されていないサードパーティのイメージを使用している場合は、それらのイメージに存在する既知の脆弱性をすべて追跡する必要があります。 これは、いわゆるDockerイメージスキャンです。 Docker image scanning – How to implement open source container security (part 2)で説明しました。
- ランタイムコンテナセキュリティ:プロダクション環境は、コンテナライフサイクルにおいて最も期間が長くなります。デプロイメント後にセキュリティインシデントとして何が起きるのでしょうか?デプロイメント後のコンテナに対して何か保護を実施しているのでしょうか? 初めに、オープンソースツールを使用してランタイムコンテナセキュリティを実装する方法について説明します。
以下の記事は、有用な情報ですので是非ご覧ください:
- Runtime Container Security (what it is and how to implement it)
- Understanding Response Engine and Security Playbooks
- Runtime Container Security Open Source Tools
- Building a Kubernetes Runtime Security Stack with Open Source Tools
- Gain Visibility Inside your Containers and Applications with Sysdig Falco (installation steps included)
- Define your Runtime Container Security Policy for Applications, Services and the Cluster with Falco Default Ruleset Library
- Kubernetes Incident Response
- Deploying Kubernetes Response Engine Components: NATS and Kubeless framework
- Deploying Kubernetes Security Playbooks on Kubeless
- Slack Webhook Notification
- Delete Offending Pod
- Taint a Node and Stop Scheduling
- Pod Network Isolation
- Kubernetes Security Logging with Falco & Fluentd
ランタイムコンテナセキュリティ
ランタイムセキュリティは、すべての事象の一部分です、すなわち、コンテナとその内部プロセスが実行されると発生します。
コンテナが予期した通りに実行されていない場合、既知の脆弱性を悪用する攻撃である可能性があります - そしてこれはコンテナイメージスキャンで潜在的に捕らえられることができます - がこのアプローチ以外に考えられる理由があります。 以下から保護するためにランタイムコンテナのセキュリティが必要です:
- 模擬の構成、意図的であろうとなかろうと、データの損失、セキュリティ侵害、そして最終的には情報漏えいにつながります。
- ゼロデイ攻撃、もしくは、ソフトウェア自身の脆弱性
- 弱い、もしくは漏洩したクレデンシャル情報、キー、他のセンシティブな情報は、リモートアクセスに繋がる可能性があります。
- 仮想通貨マイニングまたは単純なDoSに対するリソースの悪用 これについては、「Fishing for Miners – Cryptojacking Honeypots in Kubernetes」の記事をご覧ください。
ランタイムコンテナセキュリティの実装
ランタイムコンテナセキュリティは、実行時に動作を監視することで実装できます。 コンテナは単純(通常は必要な依存関係とライブラリだけを持ち、多くの場合はマイクロサービスアプリケーションの一部として、単一タスクを実行する単一プロセス)なので、標準的な動作から逸脱している行動を検出する、すなわち、厳密なホワイトリストを使用して動作パターンを定義するのは比較的簡単です:
- アクセスおよび/または書き込みが可能なファイルディレクトリとパス
- 実行されるべきであるバイナリ
- 一般的なネットワーク接続でコミュニケーションをとるべき外部サービス
- 実行可能なシステムコール
ブラックリスト、つまり決して起こらないことがわかっている行動パターンによって、セキュリティ侵害の指標を特定することもできます:
- バイナリパスにファイルを書き込む コンテナは不変であることを意図しており、インプレースアップグレードが生じることは通常ありえません。
- /etcのような設定パスにファイルを書き込む。 同じ理由で、実行中にサービスを再設定を行うことは通常ありません。
レスポンスエンジンとセキュリティプレイブックについて
セキュリティランタイムフレームワークを構成するコンポーネント:
- ランタイム可視化エージェントは、コンテナの内部動作(ファイルを開く、ネットワーク接続を開く、実行されたプロセスなど)のリアルタイムの可視性と観測性を実現します。
- ビヘイビアルールは、コンテナに対して何が「正常」と見なされ、何を通知する必要があるかを識別します。
- セキュリティ侵害の指標は、潜在的なセキュリティ上の侵入の兆候である可能性のある異常な活動を識別に役立てます。
- レスポンスエンジンは、モニタリングエージェントのイベントに対して反応し、予防アクションとして攻撃を阻止、軽減するために、警告メッセージを通知チャネルやロギング、監査システムにルーティングを行います。
- セキュリティプレイブックには、セキュリティインシデントに対応するための手順が含まれています。 これらは手動プロセスでも自動化された方法(コードとして)でも実行できます。
コンテナの異常な動作を検出することはステップ1であり、ステップ2は自動化された方法で攻撃に対応したり軽減することです。 DockerとKubernetesの世界では、次の点に留意することが重要です。
- Kubernetesクラスタは多数のノードとコンテナの配置にまたがっているため、実行時の警告と送信元のコンテナを関連付けることは困難です。
- セキュリティインシデントへの対応は迅速である必要があります。 コンテナの寿命は短いため、コンテナが実際の損傷を引き起こすか、単に消えるか他の場所に移動する前に、犯人を見つけることが不可欠です。 自動化はこれまで以上に重要であり、コードプレイブックとして対応手順を書くことが最善の方法です。
ランタイムコンテナセキュリティオープンソースツール
さまざまなLinuxランタイムセキュリティのオープンソースツールがあります。 Seccomp、SELinux / Auditd、およびAppamorは、コンテナに適用できる従来のシステムコール監査およびエンフォースメントツールです。
Sysdig Falcoは、ビヘイビアモニタリングにフォーカスしています:
- Falcoはシステムコールインスツルメンテーションを通じて、優れたパフォーマンスと非常に少ないオーバーヘッドでコンテナ内の可視性を獲得しているため、プロダクションシステムで実行できます。
- システムコールインスツルメンテーションはコンテナに対して完全に透過的なので、コード、コンテナイメージを変更したり、ライブラリを挿入したりプリロードしたりする必要はありません。 システムコールの傍受は、DKMSで動的にコンパイルされた単純なカーネルモジュールまたはeBPFプローブを通じて行われます。
- 異常なアクティビティが検出されると、警告などのセキュリティイベントが発生します。 アラートを発生させる条件は、ポリシー、つまり構文が簡単、単純、およびtcpdumpとSysdigに非常によく似たルールの集まりによって定義されます。 気づく前に、自分でルールを書いているのがわかるでしょう。
- Falcoはコンテナネイティブですので、ルールやアラートを理解することは、プロセスとは何か、コンテナやKubernetesポッドとは何かを理解する事に繋がります。
他のランタイムセキュリティツールとFalcoとの比較については、「SELinux, Seccomp, Sysdig Falco, and you: A technical discussion」をご覧ください。
Falcoは、そのルールがDockerコンテナーまたはKubernetesオーケストレーションメタデータ(コンテナー情報、namespaces、deployment、podなど)と一緒に低レベルのオペレーティングシステムインターフェイス(syscalls)からのコンテキストを使用できるため、非常に効率的です。
たとえば、以下のような想定しているソケット以外のリスニングソケットを検出するFalcoルールを作成できます。
- コンテナイメージがmyregistry/nginx
- リスニングプロセスは、nginxコンテナの内
- Kubernetesのnamespaceは、load-balancer
それ以外の場合は、アラートがトリガーされます:
condition: evt.type in (accept,listen) and (container.image!=myregistry/nginx or proc.name!=nginx or k8s.ns.name!="load-balancer")
これは、さまざまなソースからの条件を組み合わせた例です。
- システムコールイベント:
- i.e. evt.type = listen, evt.type = mkdir, evt.type = setns, etc.
- Docker メタデータ:
- i.e. container.image, container.privileged, container.name, etc.
- プロセスツリー情報:
- i.e. proc.pname, proc.cmdline, etc.
- Kubernetes namespace メタデータ:
- i.e. k8s.ns.name, k8s.pod.name, etc.
運用エンティティを完全に理解する正確なセキュリティルールを作成するために必要な柔軟性と表現力を兼ね備えています。
オープンソースツールでKubernetesランタイムセキュリティスタックを構築する
Falcoはコンテナ内で何が起こっているのかを詳細に可視化しますが、完全なコンテナセキュリティスタックを作成するには追加のコンポーネントが必要です。 Kubernetesランタイムセキュリティスタックを構築するために結び付けることができるオープンソースコンポーネントがあります:
- ユースケース:Kubernetesで実行されているコンテナやアプリケーション(クラスタサービスを含む)の内部の可視性を高めます。
- ツール:Sysdig Falcoは優れた可視性を提供し、DockerとKubernetesをネイティブでサポートしています。 FalcoをKubernetesにインストールするのは本当に簡単です。Daberコンテナとして(他のオプションの中でもdeb/rpmのように)配布されていますが、設定とデプロイメントプロセスを合理化するためにHelmチャートもあります。
- ユースケース:アプリケーション、サービス、およびクラスタに対するランタイムセキュリティポリシーを定義
- ツール:最も人気のあるDockerイメージのFalcoデフォルトルールセットライブラリ。 Falcoのルールを作成するのは難しいことではありませんが、ランタイムセキュリティに不慣れなユーザーにとっては厄介なことです。 デフォルトのルールセットのライブラリを利用して、kube-systemコンポーネント、Nginx、HAproxy、Apache、Redis、MongoDB、Elastic、PostgreSQLなどを含む最も人気のあるDockerイメージを利用できます。
- ユースケース:ポリシー違反に基づいてセキュリティイベントを転送するためのレスポンスエンジン。
- ツール:NATS Falcoがルールを評価し、アラートをトリガーします。 同じポッド内のコンテナにある小さなフォワーダは、名前付きパイプを介してアラートを読み取り、TLSを使用してそれらをNATSに送信します。 NATSはメッセージングブローカーであるため、他の当事者がセキュリティイベントを消費する可能性があります。
- ユースケース:セキュリティプレイブックによるインシデント対応
- ツール:Kubeless for FaaSスクリプト- KubelessはKubernetesのためのサービスとしての機能フレームワークです。 NATSでイベントをサブスクライブ・リッスンし、インシデント対応と攻撃の軽減、コードとして記述された自動アクションのためのさまざまなプレイブックを実行します。 たとえば、Slackに通知を送信したり、Kubernetes APIサーバーに接続してポッドを停止したり、ポッドをネットワークから分離するネットワークポリシーを作成したりします。
- ユースケース:ロギング、監査、レポーティング
- ツール:EFK- Falcoは永続ストレージを実装していません。 過去のイベントログを確認し、データ分析、レポート作成などを実行する必要がある場合は、FalcoをEFKのようなサードパーティのロギングツールFluentd + Elastic + Kibanaと簡単に統合できます。
Sysdig Falcoを使ってコンテナやアプリケーションの内部を見やすくする(インストール手順も含む)
Kubernetesアプリケーションの管理にすでにHelmを使用している場合は、Falco Helmチャートを使用して簡単なコマンドでFalcoを数秒でインストールできます。
$ helm install --name sysdig-falco-1 --set integrations.natsOutput.enabled=true stable/falco
この方法はいくつかのアドバンテージがあります:
- FalcoをKubernetes DaemonSetとしてインストールすることのすべての利点。したがって、新しいノードを追加するときにFalcoは自動的に取得するので繰り返す必要はありません。
- より簡単、より速く、自動化されています。
- 構成とルールセットはチャートによって管理され、ポータブルで再現可能な構成を作成します。
- Kubernetes RBAC permissionのように、箱から出してすぐに統合できるものがいくつかバンドルされています。
このインストール方法の詳細については、「Automate Sysdig Falco Deployment Using Helm Charts」を参照してください。
Falcoのデフォルトルールセットライブラリを使用して、アプリケーション、サービス、およびクラスタに対するランタイムセキュリティポリシーを定義する
私たちのほとんどは、オープンソースコンポーネントを使ってCloud Nativeアプリケーションを構築しています。 このようにして、最も人気のあるコンテナイメージ用のFalcoデフォルトルールセットライブラリを作成しました。
これらのイメージを使用してサービスを構築したり、アプリケーションをコンテナ化するための基本イメージとして使用している場合は、単にボリュームパスとネットワーク接続を調整して開始することができます。 GitHubレポジトリ:falco-extrasには、次のルールがあります。
- Kubernetes 1.10 cluster components:
- apiserver
- controller-manager
- kube-dns
- kube-scheduler
- dashboard
- Google Kubernetes Engine components
- Apache
- Consul
- ElasticSearch
- etcd
- Fluentd
- HAproxy
- MongoDB
- Nginx
- PHP-FPM
- PostgreSQL
- Redis
- Traefik
例として、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 インシデントレスポンス
Kubernetes Response Engineコンポーネントのデプロイ:NATSとKubelessフレームワーク
NATSおよびKubelessコンポーネントをKubernetesクラスタにインストールするには、次の前提条件を満たす必要があります:
- kubectlコマンド。Kubernetesクラスタにアクセスするように設定されています。
- pipenv pythonパッケージ まだインストールしていない場合は、pipを使用できます。
$ pip install –user pipenv
- kubelessコマンド、インストール方法については、Kubelessクイックスタートガイドをご覧ください。
上記のリストを確認したら、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セキュリティプレイブックを設定できます。
KubelessセキュリティプレイブックをKubelessにデプロイする
レスポンスエンジンはセキュリティイベントを分類して保存し、信頼できるタイムスタンプ、発行、キューイング、およびサブスクウリプションメカニズムを提供します。 今、私たちは1つまたは複数のイベントをサブスクリプションしていて、望ましい行動、反応、または軽減を引き起こすコンシューマーを必要としています。これが「Kubernetesセキュリティプレイブック」と呼ばれるものです。
私たちのプレイブックは現在、Kubeless関数を使って実装されています。 Kubelessは私達が機能を展開してNATSトピックをサブスクライブすることを可能にします、それでそれは完全にマッチしています。
一致するNATSメッセージを受信するたびに、Kubeless関数が実行されます。 この設計により、モジュール性と構成可能性が可能になり、各トピックフィルタまたはカテゴリ全体に反応する独立した機能を実行できます。
プレイブック機能がトリガーされるまでのFalcoアラートのシーケンスは、システムのさまざまなコンポーネントを巡る旅(ジャーニー)の後に続きます:
- Falcoはリアルタイムでルールを評価し、トリガーされたアラートをLinuxパイプに書き込むので、そのKubernetesポッドに永続的なストレージを必要としません。
- サイドカーコンテナ falco-nats はパイプを通してこれらのイベントを受け取り、メタデータの抽出を容易にするためにいくつかの基本的なフォーマットを実行します。 次の形式のトピックで公開されているNATSの通知をキューに入れます:
falco.{severity}.{rule name slugified} i.e. falco.error.write_below_etc
3. Kubeless関数はさまざまなNATSトピックをサブスクライブすることができます。これにより、必要に応じてさまざまなアラートをグループ化、フィルタ処理、または無視し、宣言したグループ/フィルタごとに異なるアクションを実行できます。たとえば、falco.warning.* に関するメッセージは通知をトリガーしますが、特にfalco.error.write_below_etcはコンテナーの削除をトリガーします。
Kubernetes セキュリティプレイブック: Slack Webhook通知
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チャンネルでこれらのイベントを受け取ることができます:
Kubernetres セキュリティプレイブック:問題のあるpodを削除
インシデントに対応するためのより厳密な反応は、セキュリティ警告を引き起こした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 セキュリティプレイブック:感染したノードのスケジューリングを停止する
非常に興味深いレスポンスは、問題となっているコンテナが実行されていたノードを脇に置くことです。そのため、他に何もスケジュールされていません。 アラートが発生したKubernetesノードにさまざまな効果を得るためにフラグ(taintsとtolerations)を割り当てることができます。
$ ./deploy_playbook -r taint -t "falco.notice.contact_k8s_api_server_from_container" [-e PARAMETER]
パラメーター:
- TAINT_KEY: これは、taint keyです。デフォルト値: falco/alert
- TAINT_VALUE: これは、taint keyです デフォルト値: true
- TAINT_EFFECT: これは、taint effectです。デフォルト値: NoSchedule
この例では、パラメータなしで実行しています。デフォルトのtaint falco/alert=true:NoScheduleを使用します。そのため、特定の感染を許容できない限り、このノードにニュースポッドはスケジュールされません。 より積極的なアプローチを使用して、-e TAINT_EFFECT=NoExecuteを設定すると、影響を受けるノードをドレインできます。
Kubernetes セキュリティプレイブック:Podネットワークの分離
攻撃者が近くのリソースを乗っ取ってクラスタに拡散しようとしていると思われる場合(ネットワークスキャン、脆弱性調査、外部IPアドレスへの接続など)、Podをネットワークから分離することができます。
「分離」対応は、ポッドからのすべての入力/出力トラフィックを拒否します。 この対応には、KubernetesネットワークポリシーをサポートするKubernetesクラスタ/ Podオーバーレイネットワークが必要です。
$ ./deploy_playbook -r isolate -t "falco.notice.unexpected_network_connection"
そのため、予期しないネットワーク接続に気付くとすぐに、そのPodを切り離して、それ以上のネットワークアクティビティを回避します。
FalcoとFluentdを用いたKubernetes セキュリティロギング
プレイブックを実行することに加えて、セキュリティイベントのレポート、履歴トレンドの視覚化、またはデータマイニングを可能にするために、長期的なイベントストレージを用意することをお勧めします。
FluentdはデフォルトでいくつかのKubernetesディストリビューションにデプロイされているので、ここではEFK(Fluentd、Elastic、Kibana)スタックを使用することにします。
FalcoのJSON形式のイベント出力をstdoutに有効にすると、Fluentdはそこから取得します。 以下の方法については、「FalcoおよびFluentdを使用したKubernetesセキュリティログ」に詳細なデプロイメント手順と設定オプションがあります:
- KubernetesクラスタにEFKスタックをデプロイする
- Fluentdによってスクレイプされる、互換性のあるFalco DaemonSetをデプロイする
- バルク入力から関連するFalcoイベントをフィルタリングする
- Kibanaで素晴らしいイベントの視覚化を設定する
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イメージスキャン」に進んでいきます。
もし、好きになっていただいたあなたがこのプロジェクトに貢献する方法が多くあります:
- このガイドを改善し、より多くのドキュメントを作成するのを手伝ってください。
- デフォルトのFalcoルールのライブラリを拡張します。
- Kubeless FaaSや他のNATSオブザーバーとしてより多くのセキュリティプレイブックを寄付してください。
- またはより多くのツールを統合する、PRは常に素晴らしいです!
SysdigのオープンソースSlackコミュニティ、#open-source-sysdigに関するディスカッションに参加するか、または@sysdigでTwitter経由で私たちに連絡してください!