Google Cloudとコンテナの継続的なセキュリティ
本文の内容は、2019年10月30日にSysdigのNéstor Salcedaが投稿したブログ(https://sysdig.com/blog/multi-cluster-security-firelens/)を元に日本語に翻訳・再構成した内容となっております。
このブログ投稿では、AWSコンテナサービス全体ですべてのKubernetesセキュリティイベントを集約する方法をお話します。AWS FireLensを使用してFalco通知をルーティングし、AWS CloudWatchなどのすべてのセキュリティイベントを1つのサービスに集中させます。
これから下記を試します:
そうすることで、いくつかの重要なベネフィットを得ます。
マルチクラスターセキュリティのためのFalcoの紹介
定義:
FireLensは、AWSコンテナサービスから複数の宛先にログをルーティングするAmazonが作成したプロジェクトです。FireLensは、ECS、EKS、またはFargateクラスターで簡単な構成を行うだけで、任意のコンテナーログをAWS CloudWatchおよびS3、Elasticsearch、Kinesis Firehoseなどのサービスにルーティングできます。
Falcoは、コンテナおよびクラウドネイティブアプリの侵入および異常検出のためのCNCFオープンソースプロジェクトです。 Falcoは、カスタマイズ可能な一連のルールによって定義される異常な動作を検出すると、セキュリティイベントを生成します。
CloudWatchは、AWS環境用の監視および可観測サービスです。インシデント対応を行う場合、CloudWatchを使用して複数のログを一度にクエリし、情報を横断してデバッグと事後分析をより迅速かつ効果的に行うことができます。 CloudWatchはログを処理して、アラームの設定やダッシュボードの傾向の視覚化に使用できるメトリクスを作成します。
各クラスターノードでFalcoを使用してランタイムセキュリティイベントを検出し、CloudWatchをデプロイしてインフラストラクチャを監視します。
Falcoはイベントを標準出力に出力するため、FireLensを利用してそれらを収集し、CloudWatchに送信できます。ここにAWS FireLensの強みがあります。互いに話す方法がわからない、または異なるチャネルで話している2つのサービスを接続できます。
内部では、FireLensは、Fluent Bitやfluentdなどのオープンソースログ収集ツールと、CloudWatchやKinesis FirehoseなどのAWSサービス用の特定の出力プラグインをバンドルしています。
ツールが導入されたので、次は実装計画をたどります。FireLensをデプロイするにはいくつかの方法があり、それぞれが異なる種類のクラスターまたは使用するAWSコンテナサービスに適合させます。
これは、FalcoセキュリティイベントがCloudWatchに向かって進む道のりです。
FireLensは、Amazonが配布するFluent Bitコンテナーイメージを使用してEKSに、またAmazonが提供するサイドカーコンテナーを使用してECSに展開します。
手順をステップごとに文書化し、スクリプト化してお客様の便宜を図っています。
sysdiglabs/falco-aws-firelens-integration GitHubリポジトリにスターを付けることを忘れないでください。さあ、始めましょう!
最初に、sysdiglabs/falco-aws-firelens-integrationのクローンを作成し、次の前提条件を満たしていることを確認する必要があります。
$ git clone https://github.com/sysdiglabs/falco-aws-firelens-integration
$ cd falco-aws-firelens-integration/eks
EKSクラスターをデプロイしたら、EKSワーカーノードがログをCloudWatchに送信できることを確認してください。そのためには、各ノードに使用されているIAMロールを見つけて、CloudWatchにログを送信する権限があることを確認します。aws cliを使用すると、次のようになります。
$ aws iam create-policy --policy-name EKS-CloudWatchLogs --policy-document file://./fluent-bit/aws/iam_role_policy.json
$ aws iam attach-role-policy --role-name <EKS-NODE-ROLE-NAME> --policy-arn `aws iam list-policies | jq -r '.[][] | select(.PolicyName == "EKS-CloudWatchLogs") | .Arn'`
EKS-NODE-ROLE-NAMEを、ノードが使用しているIAMロールに置き換えることを忘れないでください。この値はEC2ダッシュボードから取得できます。EKSノードを実行するEC2インスタンスを見つけて選択し、IAMロールに関する詳細を確認します。
ノードレベルでIAMロールを使用することにより、ノードで実行されているすべてのポッドが同じアクセス許可を共有します。 EKSがデプロイされたクラスターの場合、Amazonは2019年9月に別の興味深いオプション、サービスアカウント(IRSA)のIAMロールを発表しました。 IRSAを使用すると、ポッドレベルで詳細なアクセス許可を設定できます。これは、攻撃対象領域を減らすため、セキュリティに最適です。
次の手順では、Fluent Bit daemonSetをインストールします。
$ kubectl apply -f fluent-bit/
これにより、serviceAccount、configMap、daemonSet自体が作成されます。
Fluent Bit構成を含むconfigMapを見てみましょう。
apiVersion: v1 kind: ConfigMap metadata: name: fluent-bit-config labels: app.kubernetes.io/name: fluentbit data: fluent-bit.conf: | [SERVICE] Parsers_File parsers.conf [INPUT] Name tail Tag falco.* Path /var/log/containers/falco*.log Parser falco DB /var/log/flb_falco.db Mem_Buf_Limit 5MB Skip_Long_Lines On Refresh_Interval 10 [OUTPUT] Name cloudwatch Match falco.** region eu-west-1 log_group_name falco log_stream_name alerts auto_create_group true parsers.conf: | [PARSER] Name falco Format json Time_Key time Time_Format %Y-%m-%dT%H:%M:%S.%L Time_Keep Off # Command | Decoder | Field | Optional Action # =============|==================|=================
Decode_Field_As json log
この設定は、FlucoコンテナのSTDOUTを読み取り、JSONパーサーでエントリをデコードし、CloudWatchストリームに送信するようFluent Bitに指示します。
CloudWatchは、ストリームを含むロググループにログを整理します。グループは、各タイプのログ(セキュリティイベント、デバッグ情報など)ごとに1つのストリームを含むアプリケーションを表すことができます。alertsという名前のストリームでイベントをFalcoロググループに送信します。
最後に、Falcoをインストールする必要があります。Helmチャートを使用してインストールします。
$ helm install --name=falco --set falco.jsonOutput=true stable/falco
このデプロイメントが完了すると、Falcoは異常な動作についてKubernetesクラスターをスキャンし、JSON形式のイベントをSTDOUTに出力します。
ECSでのFalcoとFireLensのデプロイメントは、EKSでも非常によく似たプロセスですが、いくつかの特殊性があります。
前と同様に、ECSノードはアラートをCloudWatchに送信する必要があります。ノードにsysdiglabs/falco-aws-firelens-integrationリポジトリのfalco-aws-firelens-integration/ecsフォルダーからこれらのコマンドを実行する権限があることを確認してください。
$ aws iam create-policy --policy-name ECS-CloudWatchLogs --policy-document file://./fluent-bit/iam_role_policy.json
$ aws iam attach-role-policy --role-name <ECS-NODE-ROLE-NAME> --policy-arn `aws iam list-policies | jq -r '.[][] | select(.PolicyName == "ECS-CloudWatchLogs") | .Arn'`
EKSデプロイメントと同様に、EC2ダッシュボードからその値を取得できます。 ECSノードを実行するEC2インスタンスを見つけて選択し、IAMロールの詳細を確認します。
前述したように、AWSが提供するFluent Bitサイドカーコンテナーを使用してFalcoサービスでFireLensをデプロイします。タスク定義で、awsfirelensログドライバーを使用していることを確認します。
... { "essential": true, "image": "amazon/aws-for-fluent-bit:latest", "name": "log_router", "firelensConfiguration": { "type": "fluentbit", "options": { "enable-ecs-log-metadata": "true" } }, "memory": 128 }, { "name": "falco", "image": "falcosecurity/falco:0.17.1", "essential": true, "cpu": 10, "memory": 512, "privileged": true, "command": [ "/usr/bin/falco", "-pc", "-o", "json_output=true" ], "logConfiguration": { "logDriver":"awsfirelens", "options": { "Name": "cloudwatch", "region": "eu-west-1", "log_group_name": "falco", "log_stream_name": "alerts", "auto_create_group": "true" } },
...
ログにクラスターメタデータを含める必要があります。これは、アラートの発生元を把握し、セキュリティイベントをフィルター処理できるようにするためです。 enable-ecs-log-metadataパラメーターを使用すると、Fluent Bitはecs_cluster、ecs_task_definition、ec2_instance_idなどのフィールドでログを強化します。
最後に、logDriver:awsfirelensおよびName:cloudwatchを使用して、セキュリティイベントをCloudWatchの適切なログストリームにルーティングするようFluent Bitに指示します。
最後に、タスク定義とサービスをデプロイするには、次を実行します。
$ aws ecs register-task-definition --cli-input-json file://./falco/task-definition.json
$ aws ecs create-service --cluster "<CLUSTER_ARN>" --service-name falco --task-definition `aws ecs list-task-definitions | jq -r '.taskDefinitionArns[] | select(. | contains("Falco"))'` --scheduling-strategy DAEMON
CLIからECSクラスターを一覧表示し、Falcoをデプロイするクラスターを探して、CLUSTER_ARN値を取得できます。
$ aws ecs list-clusters { "clusterArns": [ "arn:aws:ecs:eu-west-1:845153661675:cluster/nestor-sysdig-ecs-firelens-demo" ]
}
AWSでは、ECSのカスタムログルーティングに関する素晴らしいドキュメントをすでに公開しています。 Amazon Elastic Container ServiceのFireLensについて詳しく知りたい場合は、お見逃しなく。
すべてがデプロイされたら、CloudWatchに進み、Falcoロググループとアラートログストリームを確認できます。クラスターからのすべてのセキュリティイベントが、同じツールに集中して表示されます。
Falcoから読み取ったJSONメッセージを表示するCloudWatch
JSON形式でfalcoから読み取られた1つのメッセージの詳細
これで、これらのセキュリティイベントを修正する自動応答をセットアップする準備ができました。AWSLambda関数を使用して、LambdaとFalcoを使用したAmazon EKSの保護をご覧ください。
Falcoは、ホストとクラスターの検出の先を行う事できます。集中化されたイベント転送と1つの集約ソリューションにより、ECS、EKS、EC2のセルフホストKubernetesなど、AWSコンテナーサービスのすべてのクラスターのコンテナーで発生していることに関する情報を取得できます。
AWS FireLensは、異なるクラスターおよびECSやEKSなどのAWS管理コンテナプラットフォーム全体でログを収集する簡単な方法を提供します。CloudWatchでそれらを集約することにより、ログ管理を簡素化し、インシデント対応を迅速化する事が可能です。