Aurora PostgreSQL で監査ログを取ってみた

  • Audit
  • PostgreSQL
  • RDS
  • SQL
  • 目的、やりたいこと

    以下のような形で、ログが取れることを確認したいと思います。

    postgresql-03

    特定のユーザーによる操作のみを取得する。特定のテーブルに対する SELECT は全て取得する。

    監査ログを全て取得するという設定は簡単ですので、上記のことを実現したいと思います。

    監査ログの種類

    Aurora PostgreSQL の監査ログは大きく分けて以下の3つです。

    1. ログイン監査(標準機能)
    2. セッション監査(pgaudit)
    3. オブジェクト監査(pgaudit)

    Aurora PostgreSQL が標準で備えているのが、ログイン監査機能です。セッション監査とオブジェクト監査は、追加のライブラリを読み込むことで使用可能になります。

    セッション監査では、ログ種別のクラス(ddl, function, misc, read, role, write, none 等)毎にログの取得を行います。ALL で全て指定することも可能です。

    オブジェクト監査では、rds_pgaudit に付与した権限(特定のテーブル、特定のカラムへの select, update, insert, delete)に基づき、監査ログを取得します。

    今回は、3つとも試してみたいと思います。

    Aurora PostgresSQL 監査ログ関係のパラメータ解説

    主に以下のパラメータが監査ログの取得に関係しています。こんなにパラメータがあるのか~、といった感じですね。

    no パラメータ 説明
    1 shared_preload_libraries 読み込む共有ライブラリのリスト
    2 pgaudit.log ログ種別のクラスを指定
    ddl, function, misc, read, role, write, none 等
    3 pgaudit.log_catalog pg_catalog へのロギング
    4 pgaudit.log_level ログエントリのレベルを指定
    log, info, notice, warning, debug1 等
    5 pgaudit.log_parameter 変数に代入された値をロギングする
    6 pgaudit.log_relation 操作した対象のオブジェクト名を分かりやすく出力
    7 pgaudit.log_statement_once Session Audit LoggingとObject Auditingを併用時
    同じSQLログを複数回出力させない設定
    8 pgaudit.role object監査を実行するロール名を指定
    AWSの場合、この値は rds_pgaudit 限定
    9 log_connections 標準機能
    ログイン成功の接続情報を記録
    10 log_disconnections 標準機能
    ログイン失敗の接続情報を記録
    11 log_destination ログの出力形式(stderr, csvlog)

    監査ログの設定

    それでは実際に Aurora PostgreSQL にて監査ログの取得をやってみます。

    pgaudit.log に misc を指定しています。これは監査設定の変更操作についてログを取得するためです。

    # クラスターパラメータ変更 aws rds modify-db-cluster-parameter-group \ --cli-input-json file://change.json # change.json の中身 { "DBClusterParameterGroupName": "koizumi-postgresql-cluster", "Parameters": [ { "ParameterName": "pgaudit.log", "ParameterValue": "misc", "ApplyMethod": "immediate" }, { "ParameterName": "pgaudit.log_catalog", "ParameterValue": "1", "ApplyMethod": "immediate" }, { "ParameterName": "pgaudit.log_level", "ParameterValue": "log", "ApplyMethod": "immediate" }, { "ParameterName": "pgaudit.log_parameter", "ParameterValue": "1", "ApplyMethod": "immediate" }, { "ParameterName": "pgaudit.log_relation", "ParameterValue": "1", "ApplyMethod": "immediate" }, { "ParameterName": "pgaudit.log_statement_once", "ParameterValue": "1", "ApplyMethod": "immediate" }, { "ParameterName": "pgaudit.role", "ParameterValue": "rds_pgaudit", "ApplyMethod": "immediate" }, { "ParameterName": "log_connections", "ParameterValue": "1", "ApplyMethod": "immediate" }, { "ParameterName": "log_disconnections", "ParameterValue": "1", "ApplyMethod": "immediate" }, { "ParameterName": "shared_preload_libraries", "ParameterValue": "pgaudit", "ApplyMethod": "pending-reboot" } ] }

    設定の反映にはDBの再起動が必要です。DBの再起動後、以下の手順で pgaudit 拡張機能を有効化します。

    # pgaudit 拡張機能を有効化 CREATE EXTENSION pgaudit; -> shared_preload_libraries:pgaudit # 監査用ロールも作成しておきます。 CREATE ROLE rds_pgaudit; # ロール毎の権限の確認は以下のコマンドです。 select rolname,rolconfig from pg_roles;

    目的の監査ログが取得できたか、動作確認

    試しにテーブルをいくつか作成して、アクセス権を付与しておきましょう。

    予め、user01 と user02 という一般ユーザーを作成しておき、以下の操作を実行します。

    # user01 でテーブル作成 create table emilyschema.mybook (id integer, name varchar(10)); create table emilyschema.myfamily (id integer, name varchar(10)); create table emilyschema.myhobby (id integer, name varchar(10)); # 作成したテーブルへのアクセス権をuser02に付与 GRANT ALL ON emilyschema.mybook ,emilyschema.myfamily,emilyschema.myhobby TO user02;

    監査対象を設定

    たとえば、以下のような設定をします。

    # ロールレベル:user01 は read を監査する。 ALTER ROLE user01 set pgaudit.log='read'; # オブジェクトレベル:テーブル myfamily への SELECT および DELETE を監査する。 grant select, delete on emilyschema.myfamily to rds_pgaudit;

    そして、各テーブルに対して、select, insert, update, delete を実行してみてください。

    以下のような結果になれば成功です。

    postgresql-04

    以上です。

  • Audit
  • PostgreSQL
  • RDS
  • SQL