生成AIを用いてセキュリティアラートをカスタマイズする
はじめに
こんにちは。hisadonです。
今回は Amazon GuardDuty のセキュリティアラートを生成AIを用いて、良い感じにメールを送信するナレッジをご紹介したいと思います。
実装の推しポイント
- 検知したセキュリティアラートの原因と対策を生成AIに出してもらいました。
実装後に届くメールイメージ
AWS構成イメージ
Amazon GuardDutyとは?
Amazon GuardDutyは、AWSのセキュリティサービスでリアルタイムで脅威検出を行うツールです。
- 脅威検出:GuardDutyは、VPCフローログ、AWS CloudTrail管理イベントログ、DNSログなどのデータソースを利用して、異常な活動や不正アクセスを検出します。これにより、サイバー攻撃や内部不正の兆候を見逃さずに把握することができます。
- 自動解析:機械学習や統計分析を用いて、膨大なデータから潜在的な脅威を自動的に抽出します。これにより、セキュリティ担当者が効率的に対策を講じることが可能です。
- 警告と通知:GuardDutyは、脅威を検出するとアラートを生成し、AWSマネジメントコンソールやメール、SNS、サードパーティ製品などを通じて通知します。これにより、迅速に対応を行うことができます。
- 継続的な監視:常にAWS環境を監視し続けるため、新しい脅威が発生した場合にもすぐに対応できます。クラウド環境のセキュリティを強化し、リスクを最小限に抑えることができます。
実装に向けての前提
- 東京リージョンにて実装する
- AWS CloudShellのコマンドを用いて実装する
実装の流れ
- Amazon GuardDutyを有効化する。
- Amazon SES で連絡先メールアドレスを登録する。
- Amazon Bedrockを利用できる様にする
- AWS Lambda の関数を作成する。
- Amazon EventBridge で Amazon GuardDuty の通知を拾う設定を投入する。
- AWS CloudShell にてテストアラートを作成する。
設定手順1(Amazon GuardDutyを有効化する)
1.AWS CloudShell を起動して、以下のコマンドを実施します。
$ aws guardduty create-detector --enable --region ap-northeast-1
設定手順2(Amazon SESで連絡先メールアドレスを登録する)
1.AWS CloudShell を起動して、以下のコマンドを実施します。
※ "your-email@example.com" は受信したいメールアドレスに直してください
$ aws ses verify-email-identity --email-address "your-email@example.com" --region ap-northeast-1
2.AWSから検証メールが届きますので、URLをクリックします。(Amazon SESの設定は完了)
設定手順3(Amazon Bedrockを利用できる様にする)
1.東京リージョンが選択されている状態で、Amazon Bedrockを選択し下記のような画面に遷移することを確認します。
2.画面内にある「モデルアクセスをリクエスト」を選択します。
3.ステータスが「リクエスト可能」との表示の場合、Bedrockが使えていない状態です。「リクエスト可能」を選択し、モデルアクセスをリクエストしましょう。
※ 参考ですが各リージョンで使えるベースモデルは異なり、北米のリージョンだと表示よりも多くのベースモデルが利用可能です。
4.今回はAnthropicのClaudeが利用可能であれば問題ありません。一旦は全て選択して利用可能な様にしていきます。トしましょう。
※ Anthropicだけは「ユースケースの詳細」を入力する必要があります。画面フォームに従い会社名などを入力して送信します。
5.以下のような画面になっていたら利用可能な状態です。
設定手順4(AWS Lambda の関数を作成する)
1.AWS GUI 上で東京リージョンを選択する。
2.AWS Lambdba を選択する。
3.関数の作成を実施し、以下を指定します。
- オプション:一から作成
- 関数名:自由につけちゃってOK
- ランタイム:Python 3.12
- 他はそのままで「関数の作成」でOK
4.以下のPythonコードを記述します。
※ コード内で変更が必要な箇所はありません。
import json
import boto3
import os
# SESとBedrockのクライアントを作成
ses_client = boto3.client('ses')
bedrock_client = boto3.client('bedrock-runtime') # 正しいクライアント名を使用してください
# 環境変数からSES送信元と送信先のメールアドレスを取得
SES_SENDER_EMAIL = os.environ['SES_SENDER_EMAIL']
SES_RECIPIENT_EMAIL = os.environ['SES_RECIPIENT_EMAIL']
def lambda_handler(event, context):
# イベントがリストとして渡される場合の処理
if isinstance(event, list):
event = event[0]
# イベントが辞書であることを確認
if not isinstance(event, dict):
return {'statusCode': 400, 'body': json.dumps('Invalid event format')}
# イベントから詳細を取得
detail = event.get('detail', {})
# 解析する情報を抽出
account_id = event.get('account', '不明')
region = event.get('region', '不明')
severity = detail.get('severity', '不明')
finding_id = detail.get('id', '不明')
finding_type = detail.get('type', '不明')
resource_type = detail.get('resource', {}).get('resourceType', '不明')
# 解析リクエストメッセージを生成
prompt = (
f'AWS GuardDuty 検知結果\n'
f'アカウントID: {account_id}\n'
f'リージョン: {region}\n'
f'重要度: {severity}\n'
f'検出結果ID: {finding_id}\n'
f'検出結果タイプ: {finding_type}\n'
f'影響を受けるリソース: {resource_type}\n'
f'原因と対策を教えてください。\n'
)
try:
# Bedrock APIを呼び出し
response = bedrock_client.invoke_model(
modelId='anthropic.claude-v2:1',
contentType='application/json',
accept='application/json',
body=json.dumps({
"prompt": f"Human: {prompt}\nAssistant:",
"max_tokens_to_sample": 500,
"temperature": 0.7
})
)
# 非同期でレスポンスを待つ
response_body = response['body'].read().decode('utf-8')
analysis_result = json.loads(response_body).get('completion', '分析結果が返されませんでした。')
except Exception as e:
analysis_result = f"GuardDutyイベントの処理中にエラーが発生しました: {str(e)}"
# SESを使用してメールを送信
try:
ses_client.send_email(
Source=SES_SENDER_EMAIL,
Destination={'ToAddresses': [SES_RECIPIENT_EMAIL]},
Message={
'Subject': {'Data': "GuardDuty Event Analysis Result", 'Charset': 'UTF-8'},
'Body': {'Text': {'Data': f"Analysis Result:\n\n{prompt}\n\n{analysis_result}", 'Charset': 'UTF-8'}}
}
)
except Exception as e:
return {'statusCode': 500, 'body': json.dumps(f"メール送信中にエラーが発生しました: {str(e)}")}
return {'statusCode': 200, 'body': json.dumps('Email sent successfully!')}
5.AWS CloudShell にて以下のコマンドを実施し、環境変数に値を設定します。
※ "function-name"は、作成したAWS Lambdaの関数名に直してください。
※ "your-email@example.com"は、手順内で作成したAmazon SESに設定したメールアドレスに直してください。
$ aws lambda update-function-configuration \
--function-name "function-name" \
--environment "Variables={ \
SES_RECIPIENT_EMAIL="your-email@example.com", \
SES_SENDER_EMAIL="your-email@example.com" \
}"
6.AWS CloudShell にて以下のコマンドを実施し、AWS Lambd のIAMロールを修正します。
※ "Lambdaに適用されているロール名" の箇所は適宜修正してください。
$ aws iam put-role-policy \
--role-name "Lambdaに適用されているロール名" \
--policy-name BedrockAccessPolicy \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"ses:SendRawEmail"
],
"Resource": "*"
}
]
}'
7.AWS CloudShell にて以下のコマンドを実施し、AWS Lambda のタイムアウトを15秒に変更しておきます。
※ "function-name" はLambdaの関数名に直してください。
$ aws lambda update-function-configuration --function-name <function-name> --timeout 15
設定手順5(Amazon EventBridge で Amazon GuardDuty の通知を拾う設定を投入する)
1.AWS CloudShell にて以下のコマンドを実施し、Amazon EventBridgeルールを作成します。
※ コマンド内で変更が必要な箇所はありません。
aws events put-rule \
--name GuardDutyAllFindingsRule \
--event-pattern '{
"source": ["aws.guardduty"],
"detail-type": ["GuardDuty Finding"]
}' \
--description "Rule to catch all GuardDuty findings" \
--region ap-northeast-1
2.AWS CloudShell にて以下のコマンドを実施し、作成したLambdaのARNを取得します。
※ "function-name"は、作成したLambdaの関数名に直してください。
$ export LAMBDA_ARN=$(aws lambda get-function --function-name "function-name" --query 'Configuration.FunctionArn' --output text)
$ echo $LAMBDA_ARN
3.AWS CloudShell にて以下のコマンドを実施し、Amazon EventBridgeにてターゲットを指定します。
※ コマンド内で変更が必要な箇所はありません。
aws events put-targets \
--rule GuardDutyAllFindingsRule \
--targets "[
{
\"Id\": \"1\",
\"Arn\": \"${LAMBDA_ARN}\"
}
]" \
--region ap-northeast-1
設定手順6(AWS CloudShell にてテストアラートを作成する)
1.AWS CloudShell にて以下のコマンドを実施し、Amazon Guardduty のデテクターIDを取得する。
$ DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)
$ echo $DETECTOR_ID
2.テストデータを生成する。
$ aws guardduty create-sample-findings --detector-id $DETECTOR_ID --finding-types "Backdoor:EC2/DenialOfService.Dns"
3.意図したセキュリティメールが届いているか確認する。
まとめ
Amazon GuardDutyと生成AIの組み合わせにより、原因と対策を出力させてみました。
これにより検知時の初動も早くなり、セキュリティリスクをより軽減できるかと思います。
この記事が皆様のセキュリティ対応に役立つことを願っています。