Amazon Aurora の 監査ログ ( pgAudit ) を、ログアーカイブ用の AWS アカウントにある S3 バケットに出力してみる

記事タイトルとURLをコピーする

はじめに

本記事では、Amazon Aurora の 監査ログ ( pgAudit ) を、ログアーカイブ用の AWS アカウントにある S3 バケットに出力して保管してみます。

  1. Aurora の 監査ログ ( pgAudit ) を自 AWS アカウントの CloudWatch Logs に出力します。
  2. CloudWatch Logs を 異なる AWS アカウントの Kinesis Data Firehose を使用して、異なる AWS アカウントの S3 に出力します。

構成図

厳密には以下のような構成図になります。

前提

  • リージョンは東京リージョンを使用すること。
  • Aurora の 監査ログ ( pgAudit ) を保管する AWS アカウント、ログアーカイブ用の AWS アカウントに管理者権限でログイン可能であること。

検証のため、参考ドキュメントになるべく忠実にしつつ、AWS マネジメントコンソールで作成していきます。

参考ドキュメント

試してみる

上記の参考ドキュメントを見つつ、実際にやってみましょう。

Aurora の 監査ログ ( pgAudit ) を自 AWS アカウントの CloudWatch Logs に出力

pgAudit の有効化

ライターインスタンスのパラメータグループを参照し、shared_preload_libraries を検索します。
タイプが Static なので、インスタンスの再起動が必要なパラメータです。

pgaudit, を先頭に追加します。

インスタンスの設定画面を見ると、再起動の保留中となっています。

インスタンスを再起動します。

psql ツールを使用して、ライターインスタンスに接続し、以下のコマンドを実行します。

  • shared_preload_libraries に pgaudit が追加できたことの確認
    • pgaudit の出力があれば OK
SHOW shared_preload_libraries;
  • pgaudit 拡張の作成
    • CREATE EXTENSION の出力があれば OK
CREATE EXTENSION pgaudit;
  • pgaudit 拡張の作成後確認
    • pgaudit の出力があれば OK
SELECT * FROM pg_extension;

実行例:

接続を切断します。

\q

ライターインスタンスのパラメータグループを参照し、pgaudit.log を検索します。 今回は all を選択し、「変更を保存」を押しました。

none – これはデフォルトです。データベースの変更は記録されません。

all — すべてをログに記録します (読み取り、書き込み、関数、ロール、DDL、その他)。

ddl – ROLE クラスに含まれていない、すべてのデータ定義言語 (DDL) ステートメントのログ記録。

function – 関数呼び出し、および DO ブロックのログ記録。

misc – DISCARD、FETCH、CHECKPOINT、VACUUM、SET など、さまざまなコマンドのログ記録。

read – SELECT および COPY のログ記録 (ソースがリレーション (テーブルなどの) またはクエリの場合)。

role – GRANT、REVOKE、CREATE ROLE、ALTER ROLE、DROP ROLE など、ロールと権限に関連するステートメントのログ記録。

write – INSERT、UPDATE、DELETE、TRUNCATE、および COPY のログ記録 (送信先がリレーション (テーブル) の場合)。

パラメータグループのタイプは Dynamic なものの、実際にログを出すためには再起動が必要なようです。

インスタンスの「ログとイベント」画面からログを参照することができます。

監査ログは、:LOG: AUDIT: というラベルが付いて出力されています。

2024-05-20 09:00:02 UTC:118.238.245.175(57617):postgres@hajimete_no_database:[1703]:LOG: AUDIT: SESSION,2,1,MISC,SHOW,,,SHOW shared_preload_libraries;,

オブジェクト監査については割愛します。ドキュメントを参照ください。
pgAudit を使用してデータベースのアクティビティを記録する - Amazon Aurora

CloudWatch Logs への出力

クラスターを変更し、以下のチェックボックスにチェックを入れます。
特に再起動はいりません。

DB クラスター・インスタンスと同じリージョンの CloudWatch にロググループ・ログストリームが出来ています。

CloudWatch Logs を 異なる AWS アカウントの Kinesis Data Firehose を使用して、異なる AWS アカウントの S3 に出力

送信先となる異なる AWS アカウント (222222222222) での作業

参考:ステップ 1: Kinesis Data Firehose 送信ストリームを作成する - Amazon CloudWatch Logs

送信先となる異なる AWS アカウントで S3 バケットを作成します。

送信先となる異なる AWS アカウントで Kinesis Data Firehose 用の IAM Role を作成します。

カスタム信頼ポリシー
  • 222222222222 は自身の AWS アカウント ID です。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "firehose.amazonaws.com"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                    "sts:ExternalId": "222222222222"
                }
            }
        }
    ]
}

許可ポリシー
  • test-yamamoto-123456789012-lucky は上で作成したバケットです
{
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::test-yamamoto-123456789012-lucky",
                "arn:aws:s3:::test-yamamoto-123456789012-lucky/*"
            ]
        }
    ]
}

送信先となる異なる AWS アカウントで Kinesis Data Firehose を作成します。

作成した S3 バケット、 IAM Role を選択し作成します。

送信先となる異なる AWS アカウントで CloudWatch Logs の送信先(Destination)用の IAM Role を設定します。

CloudWatch Logs の送信先(Destination)は、クロスアカウントで CloudWatch Logs のデータを受け取る際に利用する CloudWatch Logs の機能です。
本記事では送信先となる AWS アカウントで設定し、送信元の CloudWatch Logs のデータを受け取ります。

Creates or updates a destination. This operation is used only to create destinations for cross-account subscriptions.

A destination encapsulates a physical resource (such as an Amazon Kinesis stream). With a destination, you can subscribe to a real-time stream of log events for a different account, ingested using PutLogEvents

参考:put-destination — AWS CLI 2.16.1 Command Reference

それでは、CloudWatch Logs の送信先(Destination) 用に IAM Role を作成します。 222222222222 は自身の AWS アカウント ID です。
111111111111 は送信元の AWS アカウント ID です。

  • 信頼ポリシー
{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Principal": {
            "Service": "logs.ap-northeast-1.amazonaws.com"
        },
        "Action": "sts:AssumeRole",
        "Condition": {
            "StringLike": {
                "aws:SourceArn": [
                    "arn:aws:logs:ap-northeast-1:111111111111:*",
                    "arn:aws:logs:ap-northeast-1:222222222222:*"
                ]
            }
        }
     }
}
  • アクセス許可ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": [
                "firehose:*"
            ],
            "Resource": [
                "arn:aws:firehose:ap-northeast-1:222222222222:*"
            ]
        }
    ]
}

送信先となる異なる AWS アカウントで CloudWatch Logs の送信先(Destination)を設定します。

CloudWatch Logs の送信先(Destination)を作成します。
この機能は CloudShell 等で AWS CLI を使用して設定します。

--target-arn は Kinesis Data Firehose のデリバリストリームの ARN
--role-arn は先程作成した IAM Role の ARN
です。

例:

aws logs put-destination --destination-name "testFirehoseDestination" --target-arn "arn:aws:firehose:ap-northeast-1:123456789012:deliverystream/PUT-S3-ihcN0" --role-arn "arn:aws:iam::123456789012:role/CWLtoKinesisFirehoseRole-yamamoto"

作成後は以下のコマンドを実行し、確認することが出来ます。
aws logs describe-destinations

CloudWatch Logs の送信先(Destination)に、送信元の AWS アカウントからの送信を許可するアクセスポリシーを付与します。
以下の json を記述した、AccessPolicy.json を作成してください。

  • AccessPolicy.json
{
  "Version" : "2012-10-17",
  "Statement" : [
    {
      "Sid" : "",
      "Effect" : "Allow",
      "Principal" : {
        "AWS" : "111111111111"
      },
      "Action" : "logs:PutSubscriptionFilter",
      "Resource" : "arn:aws:logs:us-east-1:222222222222:destination:testFirehoseDestination"
    }
  ]
}

そして、以下のコマンドを実行し、CloudWatch Logs の送信先(Destination)に関連付けしてください。

aws logs put-destination-policy \
    --destination-name "testFirehoseDestination" \
    --access-policy file://~/AccessPolicy.json

送信先(Destination)を作成時と同様に、aws logs describe-destinations で結果を確認できます。

あとで使用するため、arn (下から2行目)をメモしておきましょう。

送信元となる自アカウント (111111111111) での作業

pgAudit を出力している CloudWatch Logs のロググループにサブスクリプションフィルターを設定します。
「クロスアカウント」を選択し、送信先の ARN に メモしておいた CloudWatch Logs の送信先(Destination)の ARN を入れます。

作成します。

確認

Aurora にログインして任意の SQL を実行します。 これにより監査ログを出力します。

Aurora の画面からログを参照します。

自 AWS アカウントの CloudWatch Logs を参照します。

送信先の AWS アカウントの S3 バケットを確認し、対象ファイルをダウンロードします。

gz 形式で圧縮しているので、gunzip -c コマンド等を使用して中身確認します。

無事、異なる AWS アカウントの S3 に Aurora の監査ログを送信することが出来ました。

まとめ

CloudWatch Logs の Destination 機能は、クロスアカウントで Logs を連携できる良い機能です。
AWS マネジメントコンソールにも対応してもらえると、全手順をポチポチでできるな、と思いました。

余談

GW は穂高連峰に登ってきました。高温のお陰で雪の状態が悪く、全層雪崩も起きていたりして、少し怖かったです。
万全の装備で臨んだ結果、楽しく登れて景色も最高でした。

山本 哲也 (記事一覧)

カスタマーサクセス部のエンジニア。2024 Japan AWS Top Engineers に選んでもらいました。

今年の目標は Advanced Networking – Specialty と Machine Learning - Specialty を取得することです。

山を走るのが趣味です。今年の目標は 100 km と 100 mile を完走することです。 100 km は Gran Trail みなかみで完走しました。OSJ koumi 100 で 100 mile 砕け散りました。どこかで 100 mile やりたいです。

基本的にのんびりした性格です。座右の銘は「いつか着く」