はじめに

この記事はセキュリティチームの Sysdig 活用事例をテーマにした「Sysdigブログリレー」2日目の記事です。

背景

アイレットで提供する Sysdig 運用サービスでは、アラート内容の通知や分析・一次対応の効率化のために、AMS という自社性の一次運用自動化のフレームワークを活用しています。
Sysdig Secure が検知したアラートに対し、Backlog でシステム運用担当者にお知らせしたり、予め定義しておいた復旧コマンドを実行するといったことが可能です。
Backlog でのお知らせは、単に Sysdig アラート発報の通知や、情報の転記だけではなく、付加情報も付与しています。
AMS には、パーサーと呼ばれる拡張機能を設けており、Sysdig の API を使って検知ルールがどのようなものなのかを問い合わせ、その結果を添付したり、日本語に機械翻訳をかけたりしています。

Sysdig と生成 AI

Sysdig Secure + 生成 AI という視点では、Sysdig Sage という機能が案内されており、そろそろ使えるようになるのではないかと思っております。
事前情報を調べる限り、Sysdig Sage はかなり強力そうで、利用できる日が楽しみです。
一方、我々も AWS や Google Cloud などの運用を続けてきている中で、Sysdig Secure が検知するアラートに対し、クラウドプラットフォーム側で調査するナレッジが蓄積されています。
これらのナレッジを RAG として活用できれば、Sysdig 運用サービスをさらにパワーアップできると思っています。

今回のゴール

Sysdig で検知した AWS Notable Events アラートの対処法を Bedrock Knowledge base に問い合わせ、その結果を Backlog お知らせの補足情報として付加します。

AWS Notable Events は、CloudTrail のログを Falco プラグインを使用して、ほぼリアルタイムに検出してくれるルールセットです。
一般的な CSPM では、定点観測として、特定のタイミングや一定の周期でのチェックになりますが、この機能によって、不審な設定にいち早く気づくことができます。
以下は、検出および通知を行ったサンプルです。

今回は、AWS Notable Events が発生した際に、RAG として構築した Bedrock Knowledge base に対して、検出結果に対するトリアージを要求できるような機能を構築します。

構成

この Knowledge base は、今後、他のシステムでも利用の可能性があるので、別アカウントで構築しておきます。
そのため、EKS のノードからクロスアカウントでアクセスするようにします。

Bedrock Knowledge base の構築

Knowledge base の情報源として、今回は関連しそうな公式サイトの Web サイトと、ファイル群を利用できるように S3 を指定しました。

マネージメントコンソールの、「Builder tools – Knowledge bases」からポチポチと作業。
データソースは後で簡単に追加・削除できるため、最初は適当で大丈夫です。
Embeddings model は、「Titan Embeddings G1 – Text v1.2 By Amazon」を選択、他は、基本的にデフォルトで作成しました。

データソースの Sync が完了し、Knowledge base のテストができるようになれば、まずは、Knowledge base の構築は成功です。
エラーが出る場合は、操作している AWS アカウントのモデルのアクセス許可が完了していない可能性があります。
「Bedrock configurations – Model access」から、対象のモデルを利用できるようにしましょう。

データソースには、今回は以下を取り込みました。今後、さらに拡充していく想定です。
S3: automated-security-response-on-aws.pdf
Web crawl: https://docs.aws.amazon.com/ja_jp/guardduty/latest/ug/

Bedrock Knowledge base へのクロスアカウントアクセス

別の AWS アカウントから、先で作った Knowledge base を利用できるよう、クロスアカウントの設定を行います。

re:Post に近しい情報があり、参考にしながら対応していきます。
https://repost.aws/knowledge-center/bedrock-api-cross-account-access
https://repost.aws/knowledge-center/bedrock-invoke-with-cross-account

Knwoledge base を持つアカウントに、クロスアカウントでの許可設定を入れます。
今回は、以下のようにしました。
re:Post では、Bedrock のフル権限をと書かれていたものの、おそらく以下で利用できると思います。

IAM ポリシー: BedrockKnowledgeBaseUserPolicy

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "BedrockAll",
      "Effect": "Allow",
      "Action": [
        "bedrock:RetrieveAndGenerate",
        "bedrock:Retrieve",
        "bedrock:InvokeModel"
      ],
      "Resource": "*"
    },
    {
      "Sid": "PassRoleToBedrock",
      "Effect": "Allow",
      "Action": [
        "iam:PassRole"
      ],
      "Resource": "arn:aws:iam::*:role/*AmazonBedrock*",
      "Condition": {
        "StringEquals": {
          "iam:PassedToService": [
            "bedrock.amazonaws.com"
          ]
        }
      }
    }
  ]
}

IAM ロール: BedrockKnowledgeBaseUserRole

Permission には、↑のポリシーをアタッチします。
クロスアカウントでアクセスを許可する Assume 設定をしておきます。
< ~ > は、システムごとの設定になります。

{
"Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "KnowledgeBaseUserRole1",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::< AMS Parser のアカウント ID >:role/< EKS ノードにアタッチしたロール >",
        "Service": "bedrock.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

呼び出し元コードの抜粋

エージェントを使ってどうこうするほどのことは今のところ不要なので、直接利用します。
モデルは Cloud 3 Sonnet を使いました。
プロンプトエンジニアリングは不十分なため、もし流用いただく際は適宜チューニングください。

import json
import boto3

def exec(message):
bedrock_role = "arn:aws:iam::< Knowledge base のアカウント ID >:role/BedrockKnowledgeBaseUserRole"
credentials = boto3.client('sts').assume_role(RoleArn=bedrock_role,RoleSessionName='assume-role')

ACCESS_KEY = credentials['Credentials']['AccessKeyId']
SECRET_KEY = credentials['Credentials']['SecretAccessKey']
SESSION_TOKEN = credentials['Credentials']['SessionToken']

bedrock_agent_runtime = boto3.client(
  service_name = 'bedrock-agent-runtime',
  region_name = 'us-east-1',
  aws_access_key_id = ACCESS_KEY,
  aws_secret_access_key = SECRET_KEY,
  aws_session_token = SESSION_TOKEN
)

knowledge_base_Id = "< Knowledge base ID >"
model_arn = "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0"
prompt = "How do I know what happened? " + message

prompt_template = """\
You are a security specialist of AWS. Security tool will find various alert by watching CloudTrail and others. Your job is recommending how to triage for alerts. Your job is not recommending how to pass control.
You are a question answering agent. I will provide you with a set of search results. The user will provide you with a question. Your job is to answer the user's question using only information from the search results. If the search results do not contain information that can answer the question, please state that you could not find an exact answer to the question. Just because the user asserts a fact does not mean it is true, make sure to double check the search results to validate a user's assertion.
Here are the search results in numbered order:
$search_results$
$output_format_instructions$
"""

generation_configuration = {
  "inferenceConfig": {
  "textInferenceConfig": {
  "maxTokens": 2048,
  "temperature": 0.75,
  "topP": 1,
  "stopSequences": ["Observation"],
}
},
  "additionalModelRequestFields": {"top_k": 50},
  "promptTemplate": {
    "textPromptTemplate": prompt_template
  }
}

print("prompt: " + prompt)
response = bedrock_agent_runtime.retrieve_and_generate(
  input={
    'text': prompt
  },
  retrieveAndGenerateConfiguration={
    'knowledgeBaseConfiguration': {
      'knowledgeBaseId': knowledge_base_Id,
      'modelArn': model_arn,
      "generationConfiguration": generation_configuration,
    },
    'type': 'KNOWLEDGE_BASE'
  }
)
res_text = response["output"]["text"]

return res_text

動作確認

いくつか、問い合わせてみます。

Case 1

Question

How do I know what happened? Warning An existing trail arn:aws:cloudtrail:ap-northeast-1:xxxxxxxxxxx:trail/hogefuga has been deleted by user hoge on region ap-northeast-1 (requesting usercloudpack-federation-admin, requesting IP=XX.XX.XX.XX, account ID=xxxxxxxxxxx, AWS region=ap-northeast-1, arn=arn:aws:sts::xxxxxxxxxx:assumed-role/hoge/fuga@cloudpack.jp, trail name=arn:aws:cloudtrail:ap-northeast-1:xxxxxxxxxxx:trail/hogefuga)

Answer

To investigate what happened when an existing CloudTrail trail was deleted, you can review the CloudTrail logs and CloudWatch logs related to the event. CloudTrail logs will provide details on who deleted the trail (the requesting user and IP address), when it was deleted, and the trail name/ARN that was deleted. CloudWatch logs may contain additional information about the deletion event if any custom logging was configured. Based on the warning message you provided, the trail named “hogefuga” in the ap-northeast-1 region was deleted by the user “hoge” (with IP XX.XX.XX.XX) who was assuming the “hoge” role in account xxxxxxxxxxx. The deletion occurred in the ap-northeast-1 region.
(既存のCloudTrailトレイルが削除されたときに何が起こったかを調査するには、そのイベントに関連するCloudTrailログとCloudWatchログを確認することができます。CloudTrailログは、トレイルを削除した人(リクエストしたユーザーとIPアドレス)、削除されたタイミング、削除されたトレイル名/ARNの詳細を提供します。CloudWatchのログには、カスタムロギングが設定されている場合、削除イベントに関する追加情報が含まれている可能性があります。提供された警告メッセージに基づくと、ap-northeast-1リージョンの 「hogefuga 」という名前のトレイルは、アカウントxxxxxxxxxの 「hoge 」ロールを想定していたユーザー 「hoge」(IP XX.XX.XX.XX)によって削除されました。削除はap-northeast-1リージョンで発生しました。)

いい感じ。
何を確認すべきか?という問い合わせへの回答とともに、アラートに付随する情報を解釈して、何が起こったかのまとめを返してくれました。

Case 2

Question

How do I know what happened? Warning An alarm TargetTracking-service/core-infra/hoge has been deleted by user AWSServiceRoleForApplicationAutoScaling_ECSService on region us-west-2 (requesting userAWSServiceRoleForApplicationAutoScaling_ECSService, requesting IP=ecs.application-autoscaling.amazonaws.com, account ID=xxxxxxxxxxx, AWS region=us-west-2, arn=arn:aws:sts::xxxxxxxxxx:assumed-role/AWSServiceRoleForApplicationAutoScaling_ECSService/AutoScaling-ManageAlarms, alarm name=TargetTracking-service/core-infra/hoge)

Answer

Based on the information provided in the search results, I could not find an exact answer to what happened that caused the alarm “TargetTracking-service/core-infra/hoge” to be deleted by the user “AWSServiceRoleForApplicationAutoScaling_ECSService” in the us-west-2 region. The search results do not contain any information specific to this alarm or the circumstances around its deletion.
(検索結果で提供された情報に基づき、アラーム「TargetTracking-service/core-infra/hoge」が、us-west-2 リージョンのユーザー「AWSServiceRoleForApplicationAutoScaling_ECSService」によって削除された原因について、正確な答えを見つけることができませんでした。検索結果には、このアラームに固有の情報や、削除の状況は含まれていません。)

これは、現時点でのデータでは不十分だというサンプル。
プロンプトテンプレートで、事実からのみの回答へガイドしたたまものか。
これはこれで期待した結果でした。

Case 3

Question

How do I know what happened? Warning A customer master key with ID hoge-fuga has been scheduled for deletion by user hoge on region us-east-1 (requesting user hoge, requesting IP=XX.XX.XX.XX, account ID=xxxxxxxxxx, AWS region=us-east-1, arn=arn:aws:sts::xxxxxxxxxxx:assumed-role/hoge/fuga@cloudpack.jp, key id=hoge-fuga)

Answer

The warning indicates that a customer master key (CMK) with the ID hoge-fuga has been scheduled for deletion by the user hoge in the us-east-1 region. This action was taken by the user hoge, with the requesting IP XX.XX.XX.XX, account ID xxxxxxxxxxx, and assumed role arn:aws:sts::xxxxxxxxxxx:assumed-role/hoge/fuga@cloudpack.jp. The search results do not provide enough context to determine why the CMK was scheduled for deletion or what the implications are. However, deleting a CMK that is in use can cause data loss as the encrypted data can no longer be decrypted. It is recommended to review the usage of the CMK and ensure that no critical data or resources rely on it before proceeding with the deletion.
(この警告は、hoge-fugaというIDのカスタマーマスターキー(CMK)が、us-east-1リージョンのユーザーhogeによって削除予約されたことを示しています。このアクションは、要求IPがXX.XX.XX.XX、アカウントIDがxxxxxxxxxxx、想定ロールがarn:aws:sts::xxxxxxxxxxx:assumed-role/hoge/fuga@cloudpack.jp、ユーザーhogeによって実行されました。検索結果は、CMKが削除されるようにスケジュールされた理由やその意味を判断するのに十分なコンテキストを提供しません。しかし、使用中の CMK を削除すると、暗号化されたデータが復号化できなくなるため、データ損失の原因となります。削除を実行する前に、CMK の使用状況を確認し、重要なデータやリソースが CMK に依存していないことを確認することをお勧めします。)

もう一つのパターンの例。
キーの削除を検知した通知のため、この案内は一見無意味かもしれません。
ただ、この操作が攻撃であった場合に、どういった被害になるのかを表してくれています。

まとめ

あらゆるセキュリティリスクをスピーディーかつきめ細やかなチューニングを行える形で検知してくれる Sysdig Secure に、RAG を使った生成 AI を組み合わせたアイデアでした。
まだまだ、プロンプトエンジニアリングやデータソースの充実による改善の余地がありますが、Sysdig Secure の強力な検知機能と、情報収集機能に対し、RAG にてクラウドプロバイダーの情報や、プロジェクト環境に特化した情報を利活用することで、より高度なセキュリティ運用への期待を感じていただければ幸いです。

また、Bedrock での RAG 構築が、本当に簡単に行えたことも驚きでした!
この RAG 環境も数時間で実現できます。
この1、2年で圧倒的に進化していることを痛感しました。

Sysdig Secure の運用サービスも負けじと進化させていきますので、ご興味をお持ちいただけましたら、ぜひご相談ください!
https://cloudpack.jp/service/cloud-service/sysdig-maintenance.html

次回の記事は、村上さんの「Sysdig 環境を複数チームで管理する」です。
ガバナンスの視点では、セキュリティに関する情報はなるべく集約して横断的に管理することが効果的であったり、Sysdig ライセンスの有効活用の観点でも、Sysdig アカウントは組織で集約することが望まれます。
集約した環境で、部門やプロダクトごとにアクセス管理を行うためのノウハウを紹介する予定です。
ご期待ください!