こんにちは、近藤(りょう)です!
AWS Security Hub で 「AWS 基礎セキュリティのベストプラクティス v1.0.0(AWS Foundational Security Best Practices v1.0.0、以降 FSBP」 を有効化し、運用している AWS アカウントにおいて、Security Hub の 「EC2.2」 を検知していて
その是正対象となるデフォルトのセキュリティグループが Lambda 関数で利用されているケースがありました。
本記事では、Lambda のセキュリティグループを効率的に確認する方法 を紹介し、適切な設定に変更する手順 を説明します。
SecurityHub の「EC2.2」とは?
「EC2.2」は、AWS Security Hub の FSBP に基づくセキュリティのベストプラクティスから逸脱しているルールの一つです。このルールは、デフォルトのセキュリティグループが適切に設定されているかどうかを評価します。
リソースに誤ってデフォルトのセキュリティグループが設定されている場合、意図しないトラフィックを防ぐための対策が必要です。デフォルトのセキュリティグループは 削除できないため、インバウンドルールとアウトバウンドルールをすべて削除します。
詳細は、以下のドキュメントをご参照ください。
docs.aws.amazon.com
作業手順
「EC2.2」対象のセキュリィティグループを確認
SecurityHub コンソール画面から対象のルールをチェックします。
コンプライアンスのステータスが「FAILED」の項目が是正対象のデフォルトのセキュリィティグループとなります。

対象のセキュリィティグループを利用しているリソースの確認
まずは、EC2 コンソールの「ネットワークインターフェース」画面から、デフォルトのセキュリティグループを使用しているネットワークインターフェースを検索します。
インターフェースのタイプが「lambda」となっているものが VPC にアタッチされた Lambda 関数が利用しているネットワークインターフェースです。

こちらは、対象のネットワークインターフェースの詳細画面となります。

VPC にアタッチされた Lambda 関数とは?
Lambda 関数を VPC 内で実行できるようにする設定です。
これにより、Lambda 関数がVPC内のリソース(例: RDS、ElastiCache、内部アプリケーションサーバーなど)に安全にアクセスができるようになります。
詳細な仕様については、以下の公式ドキュメントを参照してください。
docs.aws.amazon.com
Lambda のセキュリィティグループを確認
次に デフォルトのセキュリィティグループを利用している Lambda 関数を確認します。
Lambda コンソール画面から関数名を押下します。

「設定」-「VPC」から利用しているセキュリィティグループを確認できます。
これがデフォルトのセキュリィティグループと一致していたらセキュリィティグループの変更対象となります。

ここで問題がありました。
数が少ない場合は、Lambda 関数がデフォルトのセキュリィティグループを利用しているかひとつずつ画面上で確認すればよさそうですが、数が数千個あった場合は 途方に暮れてしまいます。
そこで、AWS CLI を利用して確認する方法を紹介します。
AWS CLI を利用した確認方法
※CloudShell 等で以下のスクリプトを利用してください。
#!/bin/bash # Lambda関数の一覧を取得 function_names=$(aws lambda list-functions --query "Functions[].FunctionName" --output text) echo "Lambda関数のデフォルトセキュリティグループ利用チェック:" # 各関数をループで確認 for function_name in $function_names; do echo "Checking function: $function_name" # Lambda関数のVPC設定を取得 vpc_config=$(aws lambda get-function-configuration --function-name "$function_name" --query "VpcConfig" --output json 2>/dev/null) # VPC設定が取得できない場合はスキップ if [[ $? -ne 0 || -z "$vpc_config" ]]; then echo " -> function: $function_name No VPC configuration found or unable to retrieve. Skipping." continue fi # VPC IDとセキュリティグループIDを取得 vpc_id=$(echo "$vpc_config" | jq -r '.VpcId' 2>/dev/null || echo "") sg_ids=$(echo "$vpc_config" | jq -r '.SecurityGroupIds[]' 2>/dev/null || echo "") # VPC IDが取得できない場合はスキップ if [[ -z "$vpc_id" || "$vpc_id" == "null" ]]; then echo " -> function: $function_name No VPC ID. Skipping." continue fi # デフォルトのセキュリティグループを取得 default_sg=$(aws ec2 describe-security-groups --filters Name=vpc-id,Values="$vpc_id" Name=group-name,Values=default --query "SecurityGroups[0].GroupId" --output text 2>/dev/null) # チェック結果を表示 if echo "$sg_ids" | grep -q "$default_sg"; then echo " -> function: $function_name Default SG ($default_sg) is in use." else echo " -> function: $function_name Default SG is NOT in use." fi done
- 実行結果内容
- そもそもLambdaにVPCがアタッチしていない場合
- -> function: Lambda関数名 No VPC ID. Skipping.
- Lambda関数にデフォルトのセキュリィティグループがアタッチしている場合
- -> function: Lambda関数名 Default SG (デフォルトのセキュリィティグループID) is in use.
- Lambda関数にデフォルトのセキュリィティグループ以外がアタッチしている場合
- -> function: Lambda関数名 Default SG is NOT in use.
- そもそもLambdaにVPCがアタッチしていない場合
(出力例) Lambda関数のデフォルトセキュリティグループ利用チェック: Checking function: SampleLambdaFunction10 -> function: SampleLambdaFunction10 No VPC ID. Skipping. Checking function: SampleLambdaFunction3 -> function: SampleLambdaFunction3 No VPC ID. Skipping. Checking function: SampleLambdaFunction7 -> function: SampleLambdaFunction7 No VPC ID. Skipping. Checking function: SampleLambdaFunction6 -> function: SampleLambdaFunction6 Default SG (sg-xxxxxxxxxxxxxxxxx) is in use. Checking function: SampleLambdaFunction1 -> function: SampleLambdaFunction1 No VPC ID. Skipping. Checking function: SampleLambdaFunction5 -> function: SampleLambdaFunction5 Default SG (sg-xxxxxxxxxxxxxxxxx) is in use. Checking function: SampleLambdaFunction8 -> function: SampleLambdaFunction8 Default SG (sg-xxxxxxxxxxxxxxxxx) is in use. Checking function: SampleLambdaFunction9 -> function: SampleLambdaFunction9 Default SG is NOT in use. Checking function: SampleLambdaFunction2 -> function: SampleLambdaFunction2 No VPC ID. Skipping. Checking function: SampleLambdaFunction4
出力された結果を CSV 形式などに変更すると、管理しやすくなりますので。
必要に応じてスクリプトの出力結果は、カスタマイズしてください。
Lambda のセキュリティグループを変更
対象となる Lambda 関数が整理できたら、適切なセキュリティグループに変更します。
Lambda コンソール画面から変更対象の Lambda 関数から「設定」-「VPC」の「編集」を押下します。
なお、セキュリティグループは、事前に作成しておく必要があります。

変更するセキュリティグループを選択して「保存」を押下します。

変更対象が多い場合は、AWS CLI もご検討ください。
(AWS CLI コマンド例) aws lambda update-function-configuration \ --function-name <Lambda 関数名> \ --vpc-config SecurityGroupIds=sg-xxxxxxxxxxxxxxxxx SecurityGroupIds=sg-xxxxxxxxxxxxxxxxx:新しく適用するセキュリティグループID(カンマ区切りで複数可) なお、同じVPC内で作成したセキュリティグループIDを指定してください。
変更時の注意点
Lambda の実行ロールに、EC2 のネットワークインターフェースを変更できる権限がない場合、以下のようなエラーが発生します。
例:The provided execution role does not have permissions to call CreateNetworkInterface on EC2
このエラーを回避するために、一時的に適切な IAM ポリシーを付与する必要があります。
- 必要なポリシー
- ec2:CreateNetworkInterface
- ec2:DescribeNetworkInterfaces
- ec2:DeleteNetworkInterface
- ec2:ModifyNetworkInterfaceAttribute
- ec2:AttachNetworkInterface
- ec2:DetachNetworkInterface

(参考)デフォルトのセキュリィティグループのルール削除
今回は、Lambda のセキュリティグループ設定確認・変更方法をメインに説明をしましたが、参考としてデフォルトのセキュリティグループを利用しているリソースのセキュリィティグループの付け替えがすべて完了した後の「EC2.2」の是正作業を記載しておきます。
VPCコンソール画面の左ペインのセキュリィティグループを選択します。
その後、ルールを編集します。
図ではアウトバウンドルールを編集するものとなります。
「アウトバウンドのルールを編集」を押下します。

すべてのルールを削除します。

すべてのルールがなくなっていることを確認して「ルールを保存」を押下します。

これで「EC2.2」の是正作業のデフォルトのセキュリティグループのルール削除が完了となります。
まとめ
AWS Security Hub の「EC2.2」の是正対応として Lambda 関数がデフォルトのセキュリティグループを利用しているといった稀なケースに着目し、 Lambda 関数が多数存在し手動での確認が困難な場合に備え、AWS CLI を活用した効率的な確認方法も併せてご紹介しました。
この記事がどなたかの支えになれば幸いです。