AWS Lambda 関数のログを収集する
このドキュメントでは、Amazon S3 を使用して AWS Lambda 関数のログを Google Security Operations に取り込む方法について説明します。
AWS Lambda は、イベントに応じてコードを実行し、基盤となるコンピューティング リソースを自動的に管理するサーバーレス コンピューティング サービスです。Lambda は、すべての関数ログ(プラットフォーム ログ、拡張機能ログ、アプリケーション出力)を Amazon CloudWatch Logs に自動的に送信し、関数ごとにロググループを作成します。この統合では、Amazon Data Firehose を使用して、CloudWatch Logs から S3 バケットに Lambda ログイベントをストリーミングします。Google SecOps は、Amazon S3 V2 フィードを使用してこのデータを取得します。
始める前に
次の前提条件を満たしていることを確認してください。
- Google SecOps インスタンス
- 次の管理権限を持つ AWS Management Console への特権アクセス権:
- AWS Lambda(関数、ロギング構成)
- Amazon CloudWatch Logs(ロググループ、サブスクリプション フィルタ)
- Amazon Data Firehose(配信ストリーム)
- Amazon S3(バケット)
- AWS IAM(ロール、ポリシー、ユーザー)
Lambda 関数の CloudWatch Logs ロググループを確認する
AWS Lambda は、関数が最初に呼び出されたときに、関数ごとに CloudWatch Logs ロググループを自動的に作成します。デフォルトのロググループの命名規則は次のとおりです。
/aws/lambda/<function-name>
確認する方法を次に示します。
- AWS コンソールで、[CloudWatch] > [ログ] > [ロググループ] に移動します。
/aws/lambda/を検索します。ログを取り込む Lambda 関数ごとにロググループが存在することを確認します。
AWS S3 バケットを構成する
- バケットの作成のユーザーガイドに沿って、Amazon S3 バケットを作成します。
- バケットの名前とリージョンを後で参照できるように保存します(例:
lambda-logs-to-secops)。
Amazon Data Firehose の IAM ロールを構成する
Amazon Data Firehose では、S3 バケットにログを書き込むために IAM ロールが必要です。
IAM ポリシーを作成する
- AWS コンソールで、[IAM] > [ポリシー] > [ポリシーを作成] に移動します。
- [JSON] タブを選択します。
次のポリシーを貼り付けます(
lambda-logs-to-secopsは実際のバケット名に置き換えます)。{ "Version": "2012-10-17", "Statement": [ { "Sid": "S3Delivery", "Effect": "Allow", "Action": [ "s3:AbortMultipartUpload", "s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket", "s3:ListBucketMultipartUploads", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::lambda-logs-to-secops", "arn:aws:s3:::lambda-logs-to-secops/*" ] }, { "Sid": "CloudWatchLogging", "Effect": "Allow", "Action": [ "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:log-group:/aws/kinesisfirehose/lambda-logs-to-secops:log-stream:*" } ] }[次へ] をクリックします。
[Policy name] フィールドに「
LambdaLogsFirehoseS3Policy」と入力します。[ポリシーを作成] をクリックします。
IAM ロールを作成する
- [IAM]> [ロール]> [ロールを作成] に移動します。
- [カスタム信頼ポリシー] を選択します。
次の信頼ポリシーを貼り付けます。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "firehose.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }[次へ] をクリックします。
LambdaLogsFirehoseS3Policy を検索して選択します。
[次へ] をクリックします。
[ロール名] フィールドに「
LambdaLogsFirehoseToS3Role」と入力します。[ロールを作成] をクリックします。
Amazon Data Firehose ストリームを作成する
- https://console.aws.amazon.com/kinesis で Kinesis コンソールを開きます。
- ナビゲーション パネルで [Amazon Data Firehose] を選択します。
- [Firehose ストリームを作成] をクリックします。
- [移行元と移行先を選択] で、次の構成を指定します。
- ソース: [Direct PUT] を選択します。
- 宛先: [Amazon S3] を選択します。
- [Firehose ストリーム名] フィールドに「
lambda-logs-to-secops」と入力します。 [レコードを変換] の [Amazon CloudWatch Logs からソースレコードを解凍] セクションで、次の操作を行います。
- [解凍を有効にする] を選択します。
- [メッセージ抽出を有効にする] は選択しないでください。
[宛先の設定] で次の操作を行います。
- S3 バケット: S3 バケット
lambda-logs-to-secopsを選択します。 - S3 バケットの接頭辞(省略可):
lambda-logs/と入力します。 - S3 バケット エラー出力プレフィックス(省略可):
firehose-errors/と入力します。
- S3 バケット: S3 バケット
[バッファのヒント] で、次の操作を行います。
- バッファサイズ:
5MiB(デフォルト)。 - バッファ間隔:
300秒(デフォルト)。
- バッファサイズ:
[詳細設定] で、以下の操作を行います。
- サーバーサイド暗号化: 省略可。暗号化が必要な場合は有効にします。
- エラー ロギング: [有効] を選択します(推奨)。
- 権限: [既存の IAM ロールを選択] を選択し、
LambdaLogsFirehoseToS3Roleを選択します。
[Firehose ストリームを作成] をクリックします。
ストリームの [ステータス] が [アクティブ] になるまで待ちます。
CloudWatch Logs の IAM ロールを構成する
CloudWatch Logs では、ログデータを Firehose ストリームに送信するために IAM ロールが必要です。
IAM ポリシーを作成する
- [IAM] > [ポリシー] > [ポリシーを作成] に移動します。
- [JSON] タブを選択します。
次のポリシーを貼り付けます(
<region>と<account-id>は、AWS リージョンとアカウント ID に置き換えます)。{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "firehose:PutRecord", "firehose:PutRecordBatch" ], "Resource": "arn:aws:firehose:<region>:<account-id>:deliverystream/lambda-logs-to-secops" } ] }[次へ] をクリックします。
[Policy name] フィールドに「
LambdaLogsCWLtoFirehosePolicy」と入力します。[ポリシーを作成] をクリックします。
IAM ロールを作成する
- [IAM]> [ロール]> [ロールを作成] に移動します。
- [カスタム信頼ポリシー] を選択します。
次の信頼ポリシーを貼り付けます(
<region>は AWS リージョンに置き換えます)。{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "logs.<region>.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }[次へ] をクリックします。
LambdaLogsCWLtoFirehosePolicy を検索して選択します。
[次へ] をクリックします。
[ロール名] フィールドに「
LambdaLogsCWLtoFirehoseRole」と入力します。[ロールを作成] をクリックします。
CloudWatch Logs サブスクリプション フィルタを作成する
- AWS コンソールで、[CloudWatch] > [ログ] > [ロググループ] に移動します。
- ロググループ
/aws/lambda/<function-name>を選択します。 - [サブスクリプション フィルタ] タブを選択します。
- [作成> Amazon Data Firehose サブスクリプション フィルタを作成] をクリックします。
- 次の構成の詳細を入力します。
- 宛先: Firehose ストリーム
lambda-logs-to-secopsを選択します。 - 権限を付与: ロール
LambdaLogsCWLtoFirehoseRoleを選択します。 - サブスクリプション フィルタ名: わかりやすい名前を入力します(例:
lambda-logs-to-secops-filter)。 - ログ形式: [その他] を選択します。
- サブスクリプション フィルタ パターン: すべての Lambda 関数ログイベントを送信する場合は、空白のままにします。
- 宛先: Firehose ストリーム
[ストリーミングを開始] をクリックします。
Google SecOps 用に IAM ユーザーを構成する
Google SecOps は、配信されたログを取り込むために、S3 バケットにアクセスできる IAM ユーザーを必要とします。
- IAM ユーザーの作成のユーザーガイドに沿って、ユーザーを作成します。
- 作成したユーザーを選択します。
- [セキュリティ認証情報] タブを選択します。
- [アクセスキー] セクションで [アクセスキーを作成] をクリックします。
- [ユースケース] で [サードパーティ サービス] を選択します。
- [Next] をクリックします。
- 省略可: 説明タグを追加します。
- [アクセスキーを作成] をクリックします。
- [.csv ファイルをダウンロード] をクリックして、[アクセスキー] と [シークレット アクセスキー] を保存し、今後の参照に備えます。
- [完了] をクリックします。
- [権限] タブを選択します。
- [権限ポリシー] セクションの [権限を追加] をクリックします。
- [権限を追加] を選択します。
- [ポリシーを直接アタッチする] を選択します。
- AmazonS3FullAccess ポリシーを検索します。
- ポリシーを選択します。
- [次へ] をクリックします。
- [権限を追加] をクリックします。
AWS Lambda 関数のログを取り込むように Google SecOps でフィードを構成する
- [SIEM 設定] > [フィード] に移動します。
- [Add New Feed] をクリックします。
- 次のページで [単一フィードを設定] をクリックします。
- [Feed name] に一意の名前を入力します。
- [ソースタイプ] として [Amazon S3 V2] を選択します。
- [ログタイプ] で [AWS Lambda 関数] を選択します。
- [次へ] をクリックしてから、[送信] をクリックします。
- 次のフィールドに値を指定します。
- S3 URI:
s3://lambda-logs-to-secops/lambda-logs/ - Source deletion option: 必要に応じて削除オプションを選択します。
- ファイルの最大経過日数: 指定した日数以内に変更されたファイルを含めます(デフォルトは 180 日)。
- アクセスキー ID: S3 バケットにアクセスできるユーザー アクセスキー
- シークレット アクセスキー: S3 バケットにアクセスできるユーザーのシークレット キー
- アセットの名前空間: アセットの名前空間
- Ingestion labels: このフィードのイベントに適用されるラベル
- S3 URI:
- [次へ] をクリックしてから、[送信] をクリックします。
UDM マッピング テーブル
| ログフィールド | UDM マッピング | ロジック |
|---|---|---|
Activity_id_label |
additional.fields |
統合済み |
Arrays_label |
additional.fields |
統合済み |
Name_label |
additional.fields |
統合済み |
Type_1_label |
additional.fields |
統合済み |
Type_id_label |
additional.fields |
統合済み |
Type_label |
additional.fields |
統合済み |
Uid_label |
additional.fields |
統合済み |
Uid_label_1 |
additional.fields |
統合済み |
Value_label |
additional.fields |
統合済み |
__type_label |
additional.fields |
統合済み |
attempts_label |
additional.fields |
統合済み |
class_name_label |
additional.fields |
統合済み |
contentType_label |
additional.fields |
統合済み |
env_label |
additional.fields |
統合済み |
extendedRequestId_label |
additional.fields |
統合済み |
feature_name_label |
additional.fields |
統合済み |
line_number_label |
additional.fields |
統合済み |
logType_label |
additional.fields |
統合済み |
product_name_label |
additional.fields |
統合済み |
requestid_label |
additional.fields |
統合済み |
sourceAccount_label |
additional.fields |
統合済み |
stack_label |
additional.fields |
統合済み |
totalRetryDelay_label |
additional.fields |
統合済み |
vendor_name_label |
additional.fields |
統合済み |
version_label |
additional.fields |
統合済み |
has_principal |
extensions.auth.type |
マッピング: true → AUTHTYPE_UNSPECIFIED |
description |
metadata.description |
直接マッピングされます。 |
file_desc |
metadata.description |
直接マッピングされます。 |
Time |
metadata.event_timestamp |
UNIX として解析 |
time |
metadata.event_timestamp |
yyyy-MM-ddTHH:mm:ss.SSSZ として解析 |
has_principal |
metadata.event_type |
マッピング: true → USER_LOGIN、true → NETWORK_HTTP、true → NETWORK_CONNECTION、`true... |
has_principal_user |
metadata.event_type |
マッピング: true → USER_RESOURCE_ACCESS |
Api.Operation |
metadata.product_event_type |
直接マッピングされます。 |
name |
metadata.product_event_type |
直接マッピングされます。 |
Api.Request.Uid |
metadata.product_log_id |
直接マッピングされます。 |
id |
metadata.product_log_id |
直接マッピングされます。 |
meta_data.requestId |
metadata.product_log_id |
直接マッピングされます。 |
Metadata.Version |
metadata.product_version |
直接マッピングされます。 |
version |
metadata.product_version |
直接マッピングされます。 |
meta_data.httpStatusCode |
network.http.response_code |
直接マッピングされます。 |
Http_request.User_agent |
network.http.user_agent |
直接マッピングされます。 |
Actor.Invoked_by |
principal.administrative_domain |
直接マッピングされます。 |
Src_endpoint.Domain |
principal.asset.hostname |
直接マッピングされます。 |
Src_endpoint.Domain |
principal.hostname |
直接マッピングされます。 |
Cloud.Region |
principal.resource.attribute.cloud.availability_zone |
直接マッピングされます。 |
Actor.User.Name |
principal.user.userid |
直接マッピングされます。 |
Status |
security_result.action_details |
直接マッピングされます。 |
Category_name |
security_result.category_details |
統合済み |
error |
security_result.description |
直接マッピングされます。 |
errorMessage |
security_result.description |
直接マッピングされます。 |
Metadata_uid_label |
security_result.detection_fields |
統合済み |
category_uid_label |
security_result.detection_fields |
統合済み |
class_uid_label |
security_result.detection_fields |
統合済み |
errorType_label |
security_result.detection_fields |
統合済み |
event_code_label |
security_result.detection_fields |
統合済み |
fault_label |
security_result.detection_fields |
統合済み |
functionName_label |
security_result.detection_fields |
統合済み |
severity_id_label |
security_result.detection_fields |
統合済み |
sourceArn_label |
security_result.detection_fields |
統合済み |
type_name_label |
security_result.detection_fields |
統合済み |
type_uid_label |
security_result.detection_fields |
統合済み |
user_type_label |
security_result.detection_fields |
統合済み |
Severity |
security_result.severity |
マッピング: Informational → INFORMATIONAL |
severity |
security_result.severity |
マッピング: INFO → INFORMATIONAL |
msg |
security_result.summary |
直接マッピングされます。 |
Api.Service.Name |
target.application |
直接マッピングされます。 |
service |
target.application |
直接マッピングされます。 |
size |
target.file.size |
直接マッピングされます。 |
filename |
target.process.file.full_path |
直接マッピングされます。 |
Activity_name |
target.resource.name |
直接マッピングされます。 |
targetVar |
target.resource.name |
直接マッピングされます。 |
| なし | extensions.auth.type |
定数: AUTHTYPE_UNSPECIFIED |
| なし | metadata.event_type |
定数: USER_UNCATEGORIZED |
| なし | metadata.product_name |
定数: AWS_Lambda_Function |
| なし | metadata.vendor_name |
定数: AWS_Lambda_Function |
| なし | principal.resource.attribute.cloud.environment |
定数: AMAZON_WEB_SERVICES |
| なし | security_result.severity |
定数: INFORMATIONAL |
さらにサポートが必要な場合 コミュニティ メンバーや Google SecOps のプロフェッショナルから回答を得ることができます。