📑

AWS Security HubとBedrock AIで実現するセキュリティ通知システム

2024/07/01に公開

はじめに

クラウドセキュリティの重要性が日々高まる中、効果的な脅威検知と迅速な対応は企業のデジタルアセットを守る上で不可欠です。本記事では、AWS Security Hubの検出結果を自動的に分析し、AI技術を用いて解釈を加え、即座にSlackへ通知するシステムの構築方法を詳細に解説します。

このシステムは、AWS Lambda、Amazon EventBridge、Amazon Bedrock(Claude 3.5 Sonnet AIモデル)、そしてSlack Webhookを巧みに組み合わせることで実現しています。セキュリティエンジニアやクラウドアーキテクトの方々にとって、本記事は高度なセキュリティ自動化の実践的なガイドとなるでしょう。

本プロジェクトの主な目的は、AWS Security Hubが検出した重要なセキュリティ問題を、人間が即座に理解し行動できる形で通知することです。具体的には以下の機能を実現しています。

  • Security Hubの「CRITICAL」または「HIGH」重要度の検出結果をリアルタイムで監視

  • EventBridgeルールを使用して特定の条件に合致する検出結果を効率的にフィルタリング

  • Lambda関数を使用して検出結果を処理し、AIによる解析を実行

  • Amazon Bedrock(Claude 3.5 Sonnet)を活用し、高度なAI解釈を生成

  • 解析結果をSlackチャンネルにリアルタイムで通知、即時対応を可能に

この一連のプロセスにより、セキュリティチームは重要な脅威を迅速に把握し、適切な対策を講じることが可能となります。

使用する主な技術スタック:

  1. AWS Security Hub: 包括的なセキュリティ状態の可視化

  2. Amazon EventBridge: イベントのリアルタイム処理とルーティング

  3. AWS Lambda: サーバーレスでのコード実行環境

  4. Amazon Bedrock: 最先端AI基盤モデルの活用

  5. Slack Webhook: チーム通知の効率化

  6. Terraform: インフラストラクチャのコード化と自動管理

システムアーキテクチャの詳細

本システムのアーキテクチャは、効率性、スケーラビリティ、そして堅牢性を考慮して設計されています。以下に、各コンポーネントの役割と相互作用を詳しく説明します。

  1. AWS Security Hub: セキュリティの中枢として機能し、AWS環境全体からセキュリティ関連の情報を収集・分析します。様々なAWSサービスやサードパーティのセキュリティ製品からの検出結果を一元管理し、重要度に基づいて分類します。

  2. Amazon EventBridge: Security Hubからのイベントをリアルタイムでキャプチャし、事前に定義されたルールに基づいてフィルタリングします。要件次第ですが、今回は「CRITICAL」または「HIGH」重要度の新しい検出結果のみを、処理のためにLambda関数にルーティングします。

  3. AWS Lambda: EventBridgeからトリガーされ、Security Hubの検出結果を受け取ります。この関数は以下の主要なタスクを実行します。

  • 検出結果のパース

  • Bedrock AIの呼び出しによる高度な解釈の生成

  • 解釈結果のフォーマット

  • Slack Webhookを通じた通知の送信

  1. Amazon Bedrock (Claude 3.5 Sonnet): 最先端の自然言語処理能力を持つAIモデルを提供します。Lambda関数から呼び出され、Security Hubの検出結果を人間が理解しやすい形に解釈し、潜在的な影響や推奨される対応策を提示します。

  2. Slack Webhook: Lambda関数からの解釈済み検出結果を受け取り、指定されたSlackチャンネルにリアルタイムで通知を送信します。これにより、セキュリティチームは即座に重要な脅威を認識し、対応を開始できます。

このアーキテクチャの利点:

  • サーバーレス設計:インフラ管理の負担を最小限に抑え、スケーラビリティを確保

  • イベントドリブン:リアルタイム処理により、セキュリティインシデントへの迅速な対応を実現

  • AI活用:高度な解釈により、人間のセキュリティアナリストの負担を軽減

  • 自動化:手動での監視・分析作業を削減し、チームの効率を向上

アーキテクチャ図は以下の通りです。

alt text

Terraformを使用したインフラストラクチャのコード化

インフラストラクチャをコードとして管理することで、一貫性、再現性、そしてバージョン管理が可能になります。本プロジェクトでは、Terraformを使用してAWSリソースをプロビジョニングします。

プロジェクトの基本構造

.
├── environments/
│   └── prod/
│       ├── main.tf
│       ├── variables.tf
│       ├── outputs.tf
│       └── prod.tfvars
├── modules/
│   ├── eventbridge/
│   ├── iam/
│   └── lambda/
├── src/
│   └── lambda_function.py
└── README.md

この構造により、環境ごとの設定を分離し、再利用可能なモジュールを作成することができます。

environments/prod/main.tfの主要部分は以下の通りです。

module "eventbridge" {
  source              = "../../modules/eventbridge"
  lambda_function_arn = module.lambda.function_arn
}

module "lambda" {
  source            = "../../modules/lambda"
  slack_webhook_url = var.slack_webhook_url
  bedrock_model_id  = var.bedrock_model_id
  bedrock_region    = var.bedrock_region
}

module "iam" {
  source              = "../../modules/iam"
  lambda_function_name = module.lambda.function_name
  bedrock_region      = var.bedrock_region
  bedrock_model_id    = var.bedrock_model_id
}

このコードは、各モジュールを呼び出し、必要な変数を渡しています。モジュール化により、コードの再利用性と保守性が向上します。

Lambda関数の実装:Bedrock AIによる脅威分析

Lambda関数は、このシステムの中核となる部分です。Security Hubの検出結果を受け取り、Bedrock AIを使用して解釈を生成し、その結果をSlackに送信します。以下に、lambda_function.pyの主要な部分を示します。

import json
import os
import boto3
import requests
from botocore.exceptions import ClientError

SLACK_WEBHOOK_URL = os.environ['SLACK_WEBHOOK_URL']
SLACK_CHANNEL = os.environ['SLACK_CHANNEL']
BEDROCK_MODEL_ID = os.environ['BEDROCK_MODEL_ID']
BEDROCK_REGION = os.environ['BEDROCK_REGION']

bedrock = boto3.client('bedrock-runtime', region_name=BEDROCK_REGION)

def lambda_handler(event, context):
    print(f"Received event: {json.dumps(event)}")
    
    findings = event['detail']['findings']
    
    for finding in findings:
        interpreted_finding = interpret_finding(finding)
        send_slack_notification(interpreted_finding)

    return {
        'statusCode': 200,
        'body': json.dumps('Processing complete')
    }

def interpret_finding(finding):
    system_message = "あなたはセキュリティ専門家です。Security Hub の検出結果を解釈し、開発者向けに簡潔な説明と推奨される対応方針を提示してください。"
    
    human_message = f"""以下のSecurity Hub Findingを解釈し、開発者向けに簡潔な説明と推奨される対応方針を提示してください:

    {json.dumps(finding, indent=2)}

    回答は以下の形式で提供してください:
    - 検出内容の要約:
    - 重要度: [CRITICAL/HIGH]
    - 影響:
    - 推奨される対応:
    """

    try:
        response = bedrock.invoke_model(
            modelId=BEDROCK_MODEL_ID,
            body=json.dumps({
                "anthropic_version": "bedrock-2023-05-31",
                "max_tokens": 500,
                "messages": [
                    {"role": "user", "content": f"{system_message}\n\n{human_message}"}
                ]
            })
        )
        response_body = json.loads(response['body'].read())
        return response_body['content'][0]['text']
    except ClientError as e:
        print(f"Error calling Bedrock: {e}")
        return "Bedrockの呼び出しに失敗しました。原文を確認してください。"

def send_slack_notification(message):
    slack_message = {
        "channel": SLACK_CHANNEL,
        "text": f"Security Hub Finding Alert:\n```{message}```"
    }
    
    try:
        response = requests.post(
            SLACK_WEBHOOK_URL,
            json=slack_message,
            headers={'Content-Type': 'application/json'}
        )
        response.raise_for_status()
        print(f"Slack notification sent successfully. Status code: {response.status_code}")
    except requests.RequestException as e:
        print(f"Error sending Slack notification: {e}")

この Lambda 関数の主要な特徴は以下の通りです。

  1. イベント処理: lambda_handler 関数は、EventBridge から送られてくる Security Hub の検出結果を処理します。

  2. AI 解釈: interpret_finding 関数は、Bedrock AI(Claude 3 Sonnet モデル)を使用して、検出結果の高度な解釈を生成します。

  3. Slack 通知: send_slack_notification 関数は、解釈された結果を指定された Slack チャンネルに送信します。

  4. エラーハンドリング: Bedrock AI の呼び出しや Slack 通知の送信時に発生する可能性のあるエラーを適切に処理します。

  5. 環境変数の使用: セキュリティを考慮し、Slack Webhook URL や Bedrock モデル ID などの設定値を環境変数として管理しています。

この実装により、Security Hub の検出結果を自動的に解釈し、人間が理解しやすい形式で Slack に通知することが可能になります。次のセクションでは、この Lambda 関数をトリガーするための EventBridge ルールの設定について説明します。

EventBridgeルールの設定:効率的なイベントフィルタリング

EventBridgeは、Security Hubからの検出結果を効率的にフィルタリングし、重要なイベントのみをLambda関数にルーティングする重要な役割を果たします。以下に、modules/eventbridge/main.tfの主要部分を示します。

resource "aws_cloudwatch_event_rule" "security_hub_findings" {
  name        = "security-hub-critical-high-findings"
  description = "Capture Security Hub findings with specific criteria"

  event_pattern = jsonencode({
    source      = ["aws.securityhub"]
    detail-type = ["Security Hub Findings - Imported"]
    detail      = {
      findings = {
        Severity = {
          Label = ["CRITICAL", "HIGH"]
        }
        Workflow = {
          Status = ["NEW"]
        }
        RecordState = ["ACTIVE"]
        Compliance = {
          Status = ["FAILED", "WARNING", "NOT_AVAILABLE"]
        }
      }
    }
  })
}

resource "aws_cloudwatch_event_target" "invoke_lambda" {
  rule      = aws_cloudwatch_event_rule.security_hub_findings.name
  target_id = "InvokeLambdaFunction"
  arn       = var.lambda_function_arn
}

このEventBridgeルールの主な特徴は以下の通りです。

  1. イベントソースの指定: aws.securityhubからのイベントのみを対象とします。

  2. 詳細なフィルタリング:

  • 重要度が「CRITICAL」または「HIGH」のものだけを対象とします。

  • 新しい(「NEW」)検出結果のみを処理します。

  • アクティブ(「ACTIVE」)な状態の検出結果のみを考慮します。

  • コンプライアンスステータスが「FAILED」、「WARNING」、または「NOT_AVAILABLE」のものを対象とします。

  1. Lambda関数のトリガー: フィルタリングされたイベントは、指定されたLambda関数(var.lambda_function_arn)をトリガーします。

このルール設定により、重要かつ緊急性の高いセキュリティ問題のみが処理対象となり、システムリソースの効率的な利用とセキュリティチームの負担軽減が実現します。

Slack通知システムの構築

Slackへの通知は、セキュリティチームが迅速に問題を認識し対応するための重要な要素です。以下に、Slack通知システムの主要コンポーネントを示します。

  1. Slack Webhookの設定: Slack管理画面で新しいWebhookを作成し、URLを取得します。このURLは機密情報として扱い、環境変数やAWS Secrets Managerなどで安全に管理します。

  2. 環境変数の設定: environments/prod/prod.tfvarsファイルに以下の変数を追加します。

  3. Lambda関数でのSlack通知処理: 前述のLambda関数内のsend_slack_notification関数が、実際の通知送信を担当します。

  4. メッセージフォーマット: Slack通知のフォーマットは、セキュリティチームが迅速に情報を把握できるよう設計されています。以下は通知メッセージの例です。

Security Hub Finding Alert:
検出内容の要約: 未認証のSSH接続試行が検出されました
重要度: HIGH
影響: サーバーへの不正アクセスのリスクが高まっています
推奨される対応:

1. SSHの設定を確認し、強力な認証方式を適用する
2. ファイアウォールルールを見直し、不要なSSHアクセスを制限する
3. 侵入の痕跡がないか、関連するログを詳細に調査する

このSlack通知システムにより、セキュリティチームはリアルタイムで重要なセキュリティ問題を把握し、AIによる解釈と推奨アクションを即座に確認することができます。

セキュリティとパフォーマンスの最適化

システムの堅牢性と効率性を確保するために、セキュリティとパフォーマンスの最適化は不可欠です。以下に、主要な最適化ポイントとベストプラクティスを示します。

セキュリティの強化

IAMロールの最小権限原則

Lambda関数やその他のAWSリソースに対して、必要最小限の権限のみを付与します。以下は、Lambda関数用のIAMポリシーの例です。

resource "aws_iam_role_policy" "lambda_policy" {
  name = "lambda_security_hub_policy"
  role = aws_iam_role.lambda_exec.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents"
        ]
        Resource = "arn:aws:logs:*:*:*"
      },
      {
        Effect = "Allow"
        Action = [
          "bedrock:InvokeModel"
        ]
        Resource = "arn:aws:bedrock:${var.bedrock_region}::foundation-model/${var.bedrock_model_id}"
      }
    ]
  })
}

暗号化の適用

転送中および保存時のデータを暗号化します。例えば、Lambda関数の環境変数を暗号化する場合は以下のようになります。

resource "aws_lambda_function" "security_hub_notifier" {
  # その他の設定...

  environment {
    variables = {
      SLACK_WEBHOOK_URL = var.slack_webhook_url
      SLACK_CHANNEL     = var.slack_channel
    }
  }

  kms_key_arn = aws_kms_key.lambda_env_encryption.arn
}

resource "aws_kms_key" "lambda_env_encryption" {
  description = "KMS key for Lambda environment variables encryption"
  enable_key_rotation = true
}

ネットワークセキュリティ

可能な限り、Lambda関数をVPC内に配置し、セキュリティグループを使用してネットワークアクセスを制限します。

パフォーマンスの最適化

Lambda関数のメモリ設定

処理速度と費用のバランスを考慮し、適切なメモリサイズを設定します。以下は設定例です。

resource "aws_lambda_function" "security_hub_notifier" {
  # その他の設定...

  memory_size = 256
  timeout     = 30
}

コールドスタート対策

Lambda関数のコールドスタートを最小限に抑えるために、Provisioned Concurrencyを設定することを検討します。

resource "aws_lambda_provisioned_concurrency_config" "security_hub_notifier" {
  function_name                     = aws_lambda_function.security_hub_notifier.function_name
  provisioned_concurrent_executions = 1
  qualifier                         = aws_lambda_function.security_hub_notifier.version
}

Bedrock APIの効率的な利用

Bedrock APIの呼び出し回数を最適化するために、キャッシングや結果の再利用を検討します。

これらの最適化により、システムのセキュリティが強化され、パフォーマンスが向上します。同時に、運用コストの最適化にも貢献します。

運用とモニタリングのベストプラクティス

システムの効果的な運用と継続的な改善のために、以下のベストプラクティスを推奨します。

  1. ログ管理: CloudWatch Logsを活用し、Lambda関数とEventBridgeルールの動作を詳細に記録します。

  2. メトリクスの監視: CloudWatch Metricsを使用して、Lambda関数の実行時間、エラー率、Bedrockの呼び出し回数などを監視します。

  3. アラートの設定: 重要なメトリクスに対してCloudWatch Alarmsを設定し、異常を検知した場合に通知を受け取ります。

  4. 定期的なレビュー: システムの有効性を定期的に評価し、false positiveの削減やAI解釈の精度向上に努めます。

  5. バージョン管理: Lambda関数やTerraformコードの変更を適切にバージョン管理し、必要に応じてロールバックできるようにします。

これらのプラクティスにより、システムの安定性と効果性を継続的に維持・向上させることができます。

おわりに

本記事では、AWS Security HubとBedrock AIを活用した次世代セキュリティ通知システムの構築について解説しました。このシステムの主な特徴は以下の通りです。

  1. Security Hubからの重要な検出結果をリアルタイムで捕捉

  2. EventBridgeを使用した効率的なイベントフィルタリング

  3. Lambda関数によるイベント処理とBedrock AIを用いた高度な解釈

  4. Slackへのインテリジェントな通知機能

また、Terraformを使用したインフラのコード化により、システムの再現性と管理性を高めています。

このシステムにより、セキュリティチームは重要な脅威をより迅速に把握し、効果的に対応することが可能になります。同時に、AIによる解釈支援によって、複雑なセキュリティイベントの理解が容易になります。

今後の課題としては、機械学習モデルの統合や自動修復機能の実装、他のセキュリティツールとの連携などが考えられます。これらの拡張により、さらに強力なセキュリティ運用体制の構築が期待できます。

セキュリティは常に進化する分野です。本プロジェクトを起点に、継続的な改善と革新を重ねていくことで、組織のサイバーレジリエンスを高めていくことができるでしょう。

Discussion