COLUMN
AWS re:Invent 2024 Workshop紹介:Amazon Q Developerを使用して不正なアクティビティ検知時における自動修復の仕組みを構築する
こんにちは、荒井です。 |
毎年ラスベガスで行われている学習型カンファレンスである「AWS re:Invent 2024」が開催され、NTT東日本として参加してきました。今回は、AWS re:Invent 2024における実際のWorkshopの内容について紹介したいと思います。
本コラムで紹介しているWorkshopが行われている際の様子
AWS re:Invent 2024ではBreakout SessionやWorkshop、Gameday、Chalk Talkなどさまざまなセッションが行われました。そのうちWorkshopは、予め用意されたシナリオに沿って実際にAWSコンソールで操作を行いながらソリューション構築を体験できるセッションです。
※Workshopの現地の様子についてはこちらをご参照ください。
今回は、そんなWorkshopで行われた実際の内容について紹介します。AWSアカウントがあれば自身の環境でも実施できるように記載していますので、ぜひこのコラムをお読みの方もお試しいただければと思います。
なお、今回紹介するWorkshopについては料金発生がほとんどありませんので、安心してお試しください。
※このコラムはAWS re:Invent 2024「SUP402-R:Intelligently automating cloud operations」を基に作成しています。
NTT東日本では、AWSなどクラウドに関するお役立ち情報をメールマガジンにて発信していますので、ぜひこちらからご登録ください。
このWorkshop全体のシナリオ
このWorkshopでは以下の4つのシナリオで構成されています。
- AWS Health Abuseイベントに対する自動修復
- ソフトウェアの新バージョンリリース時に異常が検知された際の自動ロールバック
- ハッカー集団からの攻撃が差し迫っている中で全社のSSHポートを変更する大規模な修復自動化
- AWS Trusted AdvisorとAWS Healthのデータから洞察を得ることができるアプリケーションをAmazon Q Businessを使用して構築する
ひとつひとつかなり面白そうな内容ですが、本コラムでは一番上の「AWS Health Abuseイベントに対する自動修復」について紹介したいと思います。他のシナリオについては今後別のコラムにおいて紹介したいと思います。
NTT東日本では、AWSなどクラウドに関するお役立ち情報をメールマガジンにて発信していますので、ぜひこちらからご登録ください。
AWS Health Abuseイベントの自動修復シナリオ
AWSでは、不正なアクティビティ(フィッシング、マルウェア、スパム、Dos/DDoSインシデント)が検知されるとAWS Health経由でアカウント所有者に通知が行われます。今回のシナリオでは、不正なアクティビティが検出された際に自動的に修復するためのソリューションを構築します。
具体的には、Amazon EventBridgeによってAWS Health AbuseイベントをトリガーとしてLambda関数を自動で実行し、そのLambda関数の中で対象となるEC2インスタンスを停止させ、Amazon SNSを使って通知を行うといった構成を構築します。
なお、このLambda関数についてはAmazon Q Developerを用いたコード自動生成で作成します。
AWSにおける不正なアクティビティ検知についてはこちらをご参照ください:What do I do when I receive an abuse report from AWS about my resources?
事前準備
シナリオ向けにEC2インスタンスを作成します。
現地のWorkshopでは既にEC2インスタンスが起動されているアカウントを用いて実施しましたが、今回はそれがありませんので、自身で作成します。
作成するEC2インスタンスとしては本番用のWebサーバーと開発用のWebサーバーとして最低ひとつずつ作成します。(複数作成してもかまいません。)
本番用のWebサーバーにはタグとして「Stage=Prod」と設定し、開発用のWebサーバーにはタグとして「Stage=Dev」を設定してください。後の工程で作成するLambda関数はこのタグによって本番用Webサーバーか開発用Webサーバーかを判断するので、タグは正しく設定する必要があります。
インスタンスの名前は任意の名前でかまいません。
リージョンはus-east-1(バージニア北部)で作成いただけると後の工程がスムーズです。
一応、EC2インスタンスの起動に関して記載します。
正しくタグが設定されたEC2インスタンスが起動していればよいので、この通りでなくても大丈夫です。
「Amzon EC2」のページ左メニューから「インスタンス」を選択し、「インスタンスを起動」を選択します。
作成するEC2インスタンスの名前を入力します。「さらにタグを追加」を選択し、キーに「Stage」、値に「Prod」もしくは「Dev」を設定します。
「Amazonマシンイメージ(AMI)」については無料利用枠の対象であるものを選択します。
「インスタンスタイプ」は無料枠のものを選択します。「キーペア」については、「新しいキーペアを作成」を選択してキーペアを作成します。(今回、EC2インスタンスにログインすることはないのであまり気にしなくても大丈夫です。)セキュリティグループなど他の項目はデフォルトのままで大丈夫です。
「インスタンスを起動」を選択してEC2インスタンスを作成します。
SNSサブスクリプションの設定
不正なアクティビティが検出された際にメールで通知を受け取るために、Amazon SNSの設定を行います。
「Amazon SNS」のページ左メニューから「トピック」を選択し、「トピックの作成」を選択します。
タイプはスタンダードとして、名前(例:aws_health_abuse_report_sns)と表示名(例:abuse_sns)を記載し、他はデフォルトのままトピックを作成します。
トピックの作成が完了したら、「サブスクリプションの作成」を選択します。
プロトコルはEメールを選択し、エンドポイントとしてメールアドレスを入力します。「サブスクリプションの作成」を選択します。
Amazon SNSから確認のメールが届くため、「Confirm subscription」を選択します。
IAMロールとポリシーの作成
Lambda関数を実行するために設定するIAMロールを作成します。作成したIAMロールをLambda関数に設定することで、必要な権限を付与します。
「IAM」ページの左メニューから「ポリシー」を選択し、「ポリシーの作成」を選択します。
「アクセス許可の指定」において右上の「JSON」を選択し、ポリシーエディタに以下のポリシーを記載します。「次へ」を選択します。
ポリシー:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*",
"Effect": "Allow",
"Sid": "AllowLambdaPermissionsToLogInCloudWatchLogs"
},
{
"Action": [
"sns:Publish"
],
"Resource": "<<ARN_of_SNS_TOPIC>>",
"Effect": "Allow",
"Sid": "AllowLambdaPermissionsToPublishSNS"
},
{
"Action": [
"ec2:DescribeInstances",
"ec2:TerminateInstances",
"ec2:StopInstances",
"ec2:DescribeTags"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "AllowLambdaPermissionsToDescribeStopTerminateEC2"
}
]
}
ポリシー名(例:aws_health_dos_lamba_policy)を記載し、IAMポリシーを作成します。
「IAM」ページの左メニューから「ロール」を選択し、「ロールの作成」を選択します。
「信頼されたエンティティタイプ」で「AWSのサービス」を選択し、「サービスまたはユースケース」で「Lambda」を選択します。「次へ」を選択します。
先ほど作成したIAMポリシーを選択し、「次へ」を選択します。
ロール名(例:aws_health_dos_lambda_role)を記載し、IAMロールを作成します。
Amazon Q Developerを使用したAWS Lambda関数の作成
不正なアクティビティ(AWS Health Abuse)を検知した際にEC2インスタンスを自動的に停止し、Amazon SNSで通知を行うためのLambda関数を作成します。この作成にはAmazon Q Developerを使用することで、自身でコード作成を行わずにAmazon Qによって作成してもらいます。AIによって自動的にコードが作成される様子は少し感動を覚えますので、ぜひ自身で行ってみてください。
「Lambda」ページの左メニューから「関数」を選択し、「関数の作成」を選択します。
コードソースに以下のコードを入力します。
見ていただくとわかる通り、このコードは大体の流れだけ記載してあるだけであり、具体的なコードは書かれていません。コード内の「Replace with the prompt from the workshop or try your own」という部分にこれからプロンプト(AIに渡す指示)を記載して、Amazon Q Developerにコードを作成してもらいます。
コード:
import boto3
import os
ec2_client = boto3.client("ec2")
sns_client = boto3.client("sns")
def lambda_handler(event, context):
instances_from_event = parse_event(event)
instances_to_be_stopped = filter_instances_by_tag(instances_from_event)
stop_instances(instances_to_be_stopped)
send_notification(instances_to_be_stopped)
def parse_event(event):
"""
<Replace with the prompt from the workshop or try your own.>
"""
def filter_instances_by_tag(instances):
"""
<Replace with the prompt from the workshop or try your own.>
"""
def stop_instances(instances):
"""
<Replace with the prompt from the workshop or try your own.>
"""
def send_notification(instances):
"""
<Replace with the prompt from the workshop or try your own.>
"""
ではさっそくプロンプトを書いて、Amazon Qにコードを作成してもらいましょう。
「def parse_event(event)」の部分について、既存のコメントを以下のプロンプトに置き換えます。
プロンプトは英語ですが、和訳すると「指定されたイベントから、すべてのインスタンスIDを抽出してください。インスタンスは 'resource' キーに存在し、AWS ARN(Amazon Resource Name)として表されています。」という内容です。
プロンプト:
"""
Given event, extract all instance ids from the event. Instances are present in the "resource" key and are represented as AWS ARN
eg. arn:aws:ec2:us-east-1:123456789012:instance/i-abcdef . Last part of the ARN after '/' is the instance id.
Sample event:
{
"version": "0",
"id": "7bf73129-1428-4cd3-a780-95db273d1602",
"detail-type": "AWS Health Abuse Event",
"source": "aws.health",
"account": "123456789012",
"time": "2022-11-28T06:27:57Z",
"region": "global",
"resources": ["arn:aws:ec2:us-east-1:123456789012:instance/i-abcdef", "arn:aws:ec2:us-east-1:123456789012:instance/i-dcbdfdb"],
"detail": {
"eventArn": "arn:aws:health:global::event/AWS_ABUSE_DOS_REPORT_92387492375_4498_2018_08_01_02_33_00",
"service": "ABUSE",
"eventTypeCode": "AWS_ABUSE_DOS_REPORT",
"eventTypeCategory": "issue",
"startTime": "Wed, 28 Nov 2023 06:27:57 GMT",
"eventDescription": [{
"language": "en_US",
"latestDescription": "A description of the event will be provided here"
}],
"affectedEntities": [{
"entityValue": "arn:aws:ec2:us-east-1:123456789012:instance/i-abcdef"
}, {
"entityValue": "arn:aws:ec2:us-east-1:123456789012:instance/i-dcbdfdb"
}]
}
"""
先ほど記入したプロンプトの次の先頭行(画像の位置)を選択し、Amazon Q Developerによるコード作成を行います。
Amazon Q Developerによるコード作成は、Windows/Linux の場合は Alt+C、Mac の場合は option+Cを使用します。
なお、初めて利用する場合は「Allow cross region calls」(リージョン間の呼び出し許可)を行うことを求められる場合がありますが、その場合は許可を行ってください。
実行するとこのようになります。画像が粗くて少し見づらいですが、46行目にコードが作成されているのがおわかりいただけると思います。Amazon Q Developerで作成されたコードはTabキーを使用することでLambda関数へ反映されます。
続いて、def filter_instances_by_tag(instances)の箇所について、既存のコメントを以下のプロンプトに置き換えます。
プロンプトは和訳すると「インスタンスのリストが与えられた場合、EC2 API を使用して 'Stage' タグキーでフィルタリングを行い、タグ値が 'Prod' ではないものを抽出してください。インスタンスには複数のタグが設定されている可能性があります。インスタンスのリストを返してください。」という内容です。
プロンプト:
"""
Given a list of instances, describe EC2 API and filter using tag key "Stage" and tag value is not equal to "Prod". Instance may have multiple tags.
Return the list of instances
"""
続いて、def stop_instances(instances)の箇所について、既存のコメントを以下のプロンプトに置き換えます。
プロンプトは和訳すると「インスタンスをEC2 APIを使用して停止してください。」という内容です。
プロンプト:
"""
Stop instances using EC2 API
Sample instances:
["i-0a4b7c9e", "i-0a4b7c9e", "i-0a4b7c9e"]
"""
続いて、def send_notification(instances)の箇所について、既存のコメントを以下のプロンプトに置き換えます。
プロンプトは和訳すると「SNS API を使用して SNS トピックに通知を送信してください。メッセージには、インスタンスが不正行為イベントのために停止されたことを反映させてください。」という内容です。
プロンプト:
"""
Send notification to SNS topic using SNS API. Message should reflect that the instances are stopped due to the abuse event.
Sample instances:
["i-0a4b7c9e", "i-0a4b7c9e", "i-0a4b7c9e"]
"""
これより、Health Abuseイベントが発生した際に、その対象となるインスタンスを特定し、StageタグがProdではないものについてインスタンスを停止し、その結果をSNSで通知を行うLambda関数がAmazon Q Developerで作成されました。
指示を与えるだけでコードを作成してくれるため、非エンジニアの方でもこうした仕組みを自身で作成することが可能です。
Lambda関数の細かい設定として、タイムアウト秒数と環境変数の設定を行います。
「設定」から「一般設定」を選択し、「編集」を選択します。
タイムアウトをデフォルトの3秒から25秒に変更し、「保存」を選択します。
「設定」から「環境変数」を選択し、「編集」を選択します。
環境変数として、以下を設定します。
キー:SNS_TOPIC_ARN
値:作成したAmazon SNSトピックのARN
ちなみに、Amazon SNSトピックのARNはここから確認できます。
Amazon EventBridgeルールの作成
今回作成したLambda関数がHealth Abuseイベント契機に実行されるように、Amazon EventBridgeを設定します。
「Amazon EventBridge」ページの左メニューから「ルール」を選択し、「ルールを作成」を選択します。
ルールの名前(例:aws_health_dos_abuse_report_handler_lambda)を入力し、ルールタイプは「イベントパターンを持つルール」を選択します。「次へ」を選択します。
「イベントソース」は「AWSイベントまたはEventBridgeパートナーイベント」を選択し、「サンプルイベント」で「AWS Health Abuse Event」を選択します。
「作成のメソッド」で「カスタムパターン(JSONエディタ)」を選択し、以下のイベントパターンを記載します。「次へ」を選択します。
イベントパターン:
{
"source": ["aws.health"],
"detail-type": ["AWS Health Abuse Event"],
"detail": {
"service": ["ABUSE"],
"eventTypeCategory": ["issue"],
"eventTypeCode": ["AWS_ABUSE_DOS_REPORT"]
}
}
「ターゲットタイプ」は「AWSのサービス」を選択し、「ターゲットを選択」で「Lambda 関数」を選択します。関数は先ほど作成したものを選択します。「次へ」を選択します。
これにより、AWS Health Abuseイベントが起こった場合に自動的にLambda関数が実行されるようになりました。
最後に、実際にLambda関数を実行してテストしてみたいと思います。
ソリューションのテスト
作成したLambda関数を開き、「テスト」タブを選択します。
イベントJSONに以下の内容を記載します。
なお、このうち<<AWS_ACCOUNT_ID>>、<<Instance_ID_1>>、<<Instance_ID_2>>は自身のものに置き換えます。
※EC2インスタンスをus-east-1リージョン(バージニア北部)以外で起動している場合は、JSONに記載しているリージョンも変更してください。
イベントJSON:
{
"version": "0",
"id": "7bf73129-1428-4cd3-a780-95db273d1602",
"detail-type": "AWS Health Abuse Event",
"source": "aws.health",
"account": "<<AWS_ACCOUNT_ID>>",
"time": "2022-11-28T06:27:57Z",
"region": "global",
"resources": ["arn:aws:ec2:us-east-1:<<AWS_ACCOUNT_ID>>:instance/<<Instance_ID_1>>", "arn:aws:ec2:us-east-1:<<AWS_ACCOUNT_ID>>:instance/<<Instance_ID_2>>"],
"detail": {
"eventArn": "arn:aws:health:global::event/AWS_ABUSE_DOS_REPORT_92387492375_4498_2018_08_01_02_33_00",
"service": "ABUSE",
"eventTypeCode": "AWS_ABUSE_DOS_REPORT",
"eventTypeCategory": "issue",
"startTime": "Wed, 28 Nov 2022 06:27:57 GMT",
"eventDescription": [{
"language": "en_US",
"latestDescription": "A description of the event will be provided here"
}],
"affectedEntities": [{
"entityValue": "arn:aws:ec2:us-east-1:<<AWS_ACCOUNT_ID>>:instance/<<Instance_ID_1>>"
}, {
"entityValue": "arn:aws:ec2:us-east-1:<<AWS_ACCOUNT_ID>>:instance/<<Instance_ID_2>>"
}]
}
}
ちなみに、AWSアカウントIDはここから確認できます。
また、EC2インスタンスのインスタンスIDはここから確認できます。インスタンスARNもここから確認できます。
いよいよテストを行いますが、まずEC2インスタンスが全て起動していることを確認します。
本番用サーバー、開発用サーバーともに起動していますね。
Lambda関数に戻り、「テスト」を選択します。
Amazon SNSから、abuse eventを検出したためEC2インスタンスを停止したという内容の通知が届きました。
EC2インスタンスのページを確認すると、想定通りStageタグの値が「Dev」であるインスタンスが停止していました。
まとめ
今回のWorkshopでは、不正なアクティビティに対する自動対応の仕組みを構築しました。
途中でAmazon Q Developerを利用しましたが、Amazon QはこのようなLambdaを使用した仕組みの構築にとってかなり有用であると感じます。特に、非エンジニアにとってハードルが高かったコーディングがほとんど不要になるというのは大きいのではないでしょうか。
クラウド運用の自動化やAmazon Q Developerの活用方法等について、本コラムに記載したWorkshopの中で体験いただけると幸いです。
NTT東日本では、AWSなどクラウドに関するお役立ち情報をメールマガジンにて発信していますので、ぜひこちらからご登録ください。
RECOMMEND
その他のコラム
相談無料!プロが中立的にアドバイスいたします
クラウド・AWS・Azureでお困りの方はお気軽にご相談ください。