PowerGres

技術記事 | PowerGres付属のpgAuditを使って監査ログを取得してみよう

PowerGres体験記

使用バージョン: PowerGres Plus Linux V16

はじめに

本稿では監査ログを取得する拡張pgAuditを紹介します。

PowerGres(およびPowerGres Plus)には、pgAuditパッケージが標準で付属しているため、ダウンロードの手間が必要ありません。手軽なステップでpgAudit機能をインストールし利用することが可能です。

pgAuditは、標準のPostgreSQLログ機能を通じて、セッション単位およびオブジェクト単位の詳細な監査ログを提供します。この機能をPowerGres で活用することで、データベースの操作ログを詳細に記録し、セキュリティ監査やコンプライアンス要件への対応に利用できます。

本稿では、PostgreSQLの監査ロギングを実現する拡張機能であるpgAuditについて、基本的な仕組みからインストール方法、実際のログ取得方法までを体系的に解説します。実運用における監査要件に対応するための第一歩として、セッション監査ロギングとオブジェクト監査ロギングの両方を実際に確認していきます。

目次

1. pgAuditとは

pgAuditは、PostgreSQLで監査ログを取得するためのオープンソースの拡張機能です。標準のログ機能では取得しづらい詳細な操作履歴を記録することができ、セキュリティ監査や内部統制の要件を満たすために利用されます。

pgAuditの目的は、政府規制、金融要件、またはISO認証への準拠のためにしばしば求められる監査ログを生成する機能を提供することです。

監査(audit)とは、通常、独立した機関によって行われる、個人または組織の会計や活動に対する公式な検査を指します。pgAuditによって収集される情報は、正確には「監査証跡(audit trail)」または「監査ログ(audit log)」と呼ばれます。

pgAuditはPostgreSQLの拡張機能として動作し、設定した監査対象の操作内容は通常のPostgreSQLログに混在して出力されます。そのため、既存のログ運用に統合しやすい点も特徴です。

1.1 通常のPostgreSQLログと監査ログの違い

PostgreSQLの標準ログでもSQL文の記録は可能ですが、監査用途としては不十分なケースがあります。例えば以下のような点が挙げられます。

  • 誰がどのオブジェクトに対して操作したかの詳細な追跡が難しい
  • テーブル単位やカラム単位での操作記録ができない
  • 監査対象の操作のみを選択的に記録することが難しい

pgAuditを利用することで、これらの情報を明確にログとして取得できるようになります。

1.2 セッション監査ロギングとオブジェクト監査ロギング

pgAuditには大きく分けて2種類の監査方式があります。

  • セッション監査ロギング
    セッション単位でSQL操作を監査します。pgaudit.logパラメータに設定したクラス(READ、WRITEなど)に該当する操作がすべて記録されます。
  • オブジェクト監査ロギング
    特定のテーブルやカラムに対する操作のみを監査します。pgaudit.roleに指定したロールに権限を付与することで、その操作がログとして記録されます。

セッション監査は広範囲の監査に向いており、オブジェクト監査は特定対象に絞った詳細な監査に向いています。

1.3 pgAuditのログ出力形式について

pgAuditのログは「AUDIT:」で始まるカンマ区切り形式で出力されます。主な項目は以下の通りです。

  • AUDIT_TYPE(SESSION または OBJECT)
    監査ログの種別を示します。SESSIONはセッション監査ロギング、OBJECTはオブジェクト監査ロギングによる出力です。
  • STATEMENT_ID
    セッション内で実行されたSQL文に割り当てられる一意の識別子です。同一セッション内で連番として管理されます。
  • SUBSTATEMENT_ID
    1つのSQL文の中に含まれるサブ処理(関数呼び出しなど)に付与される識別子です。複数のサブ処理がある場合に区別するために使用されます。
  • CLASS(READ、WRITEなど)
    操作の種類を分類したものです。READはSELECT、WRITEはINSERTやUPDATEなど、実行された処理のカテゴリを示します。
  • COMMAND(SELECT、INSERTなど)
    実際に実行されたSQLコマンドの種類を示します。具体的な操作内容を把握するために使用されます。
  • OBJECT_TYPE(TABLEなど)
    操作対象となるオブジェクトの種類を示します。TABLEやINDEX、VIEWなどが記録されます。
  • OBJECT_NAME(public.table1など)
    操作対象のオブジェクト名をスキーマ付きで示します。どのテーブルやビューに対する操作かを特定できます。
  • STATEMENT(実行されたSQL)
    実際にデータベースで実行されたSQL文そのものが記録されます。
  • PARAMETER(パラメータ情報)
    SQLにバインドされたパラメータの値が記録されます。設定によっては記録されず、<not logged>や<none>と表示される場合があります。

これらpgAuditのログ出力は前述の通り、PostgreSQLの通常ログと一体となって出力されますので、必要に応じてlog_line_prefixを設定することで、これに日時やユーザ名などの情報も付加することもできます。

2. pgAuditのインストール方法

PowerGres では、pgAuditパッケージは標準で付属しているので、ダウンロードの手間は必要ありません。以下の手順でインストールと有効化を行うことで、速やかに利用を始めることができます。

なお、pgAuditパッケージはPowerGres ディレクトリの以下に配置されています。

Red Hat Enterprise Linux 9系
《展開したPowerGresディレクトリ》/packages/el9-x86_64/
Red Hat Enterprise Linux 8系
《展開したPowerGresディレクトリ》/packages/el8-x86_64/

それではインストールおよび有効化方法を紹介します。

2.1 pgAudit の RPM パッケージをインストール

コマンドラインより、以下を実行します。

# cd (パッケージの格納先のディレクトリ)
# rpm -ivh powergresplus16-pgaudit-*

ここでは具体例として、/root配下に置いたPowerGres のインストールパッケージ(/root/powergresplus-16update10-3-linuxディレクトリ)から、RPM パッケージをインストールします。

(例)
# cd /root/powergresplus-16update10-3-linux/packages/el9-x86_64
# rpm -ivh powergresplus16-pgaudit-16.1-1PGDG.el9.x86_64.rpm
Verifying...                          ################################# [100%]
準備しています...              ################################# [100%]
更新中 / インストール中...
   1:powergresplus16-pgaudit-16.1-1PGD################################# [100%]

2.2 postgresql.confの設定

インストール後、監査ログを有効にするために、以下の手順で設定ファイル(postgresql.conf)の編集、SQLでのpgAudit拡張の有効化を行います。

まず、データディレクトリ内の postgresql.conf ファイルをテキストエディタで開き、shared_preload_libraries パラメータに文字列で「pgaudit」と設定します。

shared_preload_libraries = 'pgaudit'  # 既存の設定がある場合はカンマ区切りで追加

ここでは併せて、セッション単位の監査ログを出力するため、暫定的に以下の設定を追加します。

pgaudit.log = 'ALL'  # すべての操作を監査ログに記録

設定ファイルを保存して閉じ、変更した設定を反映するため、PowerGres サービス(サーバ)を再起動します。この再起動は、PowerGres Administration Toolでの操作でも、コマンドラインでの実行でも構いません。

(例)
$ vi /var/lib/pgsql/16/data/postgresql.conf
(以下を追記)
shared_preload_libraries = 'pgaudit'
pgaudit.log = 'ALL'
(サーバ再起動)
$ /opt/powergresplus16/bin/pg_ctl restart -D /var/lib/pgsql/16/data
サーバ停止処理の完了を待っています....完了
サーバは停止しました
サーバの起動完了を待っています
(中略)
完了
サーバ起動完了

次にpgAudit拡張を有効化するため、データベースにスーパーユーザとして接続し、psql コマンドラインより以下のSQLを実行します。

=# CREATE EXTENSION pgaudit;
CREATE EXTENSION

以上でインストールと有効化は完了です。

2.3 動作確認

次に、有効化したpgAudit機能が動作していることを確認します。

psql コマンドラインより以下のSQLを実行します。

=# SELECT 'pgAudit Test';
   ?column?
--------------
 pgAudit Test
(1 row)

この操作により、PostgreSQLのログファイルに以下のような監査ログが出力されます。

LOG:  AUDIT: SESSION,1,1,READ,SELECT,,,SELECT 'pgAudit Test';,

以上のように動作を確認することができましたら、PowerGres でのpgAuditのインストールおよび有効化は無事完了です。

3. pgAuditを使ってみよう(セッション監査ロギング編)

本章では、pgAuditの基本的な利用方法としてセッション監査ロギングを確認します。

セッション監査ロギングは、データベースに接続したセッション単位で操作を監査する仕組みです。あらかじめpgaudit.logパラメータに監査対象のクラス(READ、WRITE、DDLなど)を設定しておくことで、そのセッション内で実行された該当操作がすべて監査ログとして出力されます。

この方式の特徴は、設定がシンプルで広範囲の操作を一括して記録できる点にあります。一方で、すべての対象操作が記録されるため、環境によってはログ量が非常に多くなる可能性があります。そのため、検証環境ではALLを指定して動作を確認し、本番環境では必要なクラスのみに絞るといった運用が一般的です。

なお、パラメータの変更はpostgresql.confに記述(テキストエディタで追記)するか、SQL(SET文)で動的に行います。ただし、SET文の場合、これはセッション単位の変更となりますのでご留意ください。変更されたpgAuditパラメータはpostgresql.confのリロードで反映されます。pg_ctl reloadやsystemctl reloadの他、SQLでpg_reload_conf関数を実行することで反映してください。

それでは、実際に各種パラメータを設定しながら、どのようにログが出力されるのかを確認していきます。

3.1 基本のログ確認

まずは基本的な運用として、すべての操作を監査ログに記載する設定として、postgresql.confに以下を設定します。この基本確認は前章の最後で行っておりますので、既に実施済の場合は適宜読み飛ばしてください。

pgaudit.log = 'ALL'

設定反映後、SELECT文を実行すると以下のようなログが出力されます。

LOG:  AUDIT: SESSION,1,1,READ,SELECT,,,SELECT 'pgAudit Test';,

3.2 pgaudit.log_catalogについて

デフォルトではonになっており、pg_catalogへのアクセスもログに出力されます。psqlの内部クエリも記録されるため、必要に応じてoffに設定することでログのノイズを減らせます。

psql で \d を実行すると、psql が実行した pg_catalog.pg_class と pg_catalog.pg_namespace への SELECT 文が監査ログとして記録されます。これは、pgaudit.log_catalog のデフォルト値が ‘on’ になっており、pg_catalogへのアクセス監査対象としてログに出力されるためです。

デフォルト値のままだと必要な監査ログが埋もれてしまう可能性があるので、こういった pg_catalog への参照をするようなツール使用時に監査ログを取得する場合、pgaudit.log_catalog を ‘off’ に設定することでログのノイズを減らせます。

(例)\d を実行した際のログ出力
LOG:  AUDIT: SESSION,2,1,READ,SELECT,,,"SELECT n.nspname as ""Schema"",
          c.relname as ""Name"",
          CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 't' THEN 'TOAST table' WHEN 'f' THEN 'foreign table' WHEN 'p' THEN 'partitioned table' WHEN 'I' THEN 'partitioned index' END as ""Type"",
          pg_catalog.pg_get_userbyid(c.relowner) as ""Owner""
        FROM pg_catalog.pg_class c
             LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
             LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam
        WHERE c.relkind IN ('r','p','v','m','S','f','')
              AND n.nspname <> 'pg_catalog'
              AND n.nspname !~ '^pg_toast'
              AND n.nspname <> 'information_schema'
          AND pg_catalog.pg_table_is_visible(c.oid)
        ORDER BY 1,2;",<not logged>

3.3 pgaudit.log_relationについて

pgaudit.log_relationは、SQL文で参照されたリレーション(TABLEやVIEWなど)の情報を監査ログに出力するかどうかを制御するパラメータです。

デフォルト値はoffで、この場合はリレーションに関する情報(どのテーブルを操作したか)はログに含まれません。

onに設定すると、SELECT文やDML文で参照されたリレーションごとにログエントリが出力され、以下の情報が追加されます。

  • 6番目の項目にオブジェクトの種類(TABLE、VIEWなど)
  • 7番目の項目にオブジェクトの完全修飾名(例:public.table1)

この設定を有効にすることで、どのオブジェクトに対する操作なのかを明確に把握できるようになります。特に同名テーブルが複数スキーマに存在する環境では、有用な情報となります。

(例)offの場合
LOG:  AUDIT: SESSION,5,1,READ,SELECT,,,SELECT * FROM test;,<not logged>
(例)onの場合
LOG:  AUDIT: SESSION,7,1,READ,SELECT,TABLE,public.test,SELECT * FROM test;,<not logged>

3.4 pgaudit.log_parameterについて

pgaudit.log_parameter はSQLのパラメータを出力するかどうかを制御します。この出力は、監査ログの最後のエントリに追記されます。

デフォルト値は ’off’ でパラメータは記録されずに <not logged> と表示されます。

’on’ に設定するとパラメータがあるときは実際のパラメータは記録され、パラメータが無い時は <none> と表示されます。

以下は、「SHOW pgaudit.log_client;」実行時のログ例です。

(例)offの場合
LOG:  AUDIT: SESSION,3,1,MISC,SHOW,,,SHOW pgaudit.log_client;,<not logged>
(例)onでパラメータがない場合
LOG:  AUDIT: SESSION,7,1,MISC,SHOW,,,SHOW pgaudit.log_client;,<none>

3.5 pgaudit.log_statement_onceについて

pgaudit.log_statement_onceは、監査ログにおいてSQL文(ステートメント)とパラメータ情報を各ログ行にすべて出力するか、それとも最初の1回だけ出力するかを制御するパラメータです。

デフォルト値はoffで、この場合は同一SQLに対する各ログエントリにおいて、SQL文およびパラメータ情報がすべての行に繰り返して出力されます。

一方、onに設定すると、SQL文とパラメータは最初のログエントリにのみ出力され、2行目以降は<previously logged>と表示され、省略されます。

この設定は、特にJOINなどで複数のリレーションが関与し、1つのSQLに対して複数行の監査ログが生成される場合に有用です。

例えば、pgaudit.log_relationをonにした状態でテーブルtable1とtable2をJOINした場合、以下のような違いが発生します。

offの場合、リレーションごとにSQL文とパラメータがすべての行に出力されます。

(例)pgaudit.log_statement_onceがoffの場合
LOG:  AUDIT: SESSION,12,1,READ,SELECT,TABLE,public.table1,"SELECT table1.i, table2.i
        FROM table1
        JOIN table2 ON true;",<not logged>
LOG:  AUDIT: SESSION,12,1,READ,SELECT,TABLE,public.table2,"SELECT table1.i, table2.i
        FROM table1
        JOIN table2 ON true;",<not logged>

onの場合、最初の行のみSQL文とパラメータが出力され、2行目以降は <previously logged>と表示され、重複が省略されます。

(例)onの場合
LOG:  AUDIT: SESSION,15,1,READ,SELECT,TABLE,public.table1,"SELECT table1.i, table2.i
        FROM table1
        JOIN table2 ON true;",<not logged>
LOG:  AUDIT: SESSION,15,1,READ,SELECT,TABLE,public.table2,<previously logged>,<previously logged>

このように、log_statement_onceはログの冗長性を抑え、可読性を向上させるための設定です。

3.6 pgaudit.log_clientとpgaudit.log_levelについて

pgaudit.log_clientは、監査ログをサーバ側のログファイルだけでなく、クライアント側にも表示するかどうかを制御するパラメータです。通常、pgAuditの監査ログはPostgreSQLサーバのログにのみ出力されますが、pgaudit.log_clientをonに設定すると、psqlなどのクライアント画面にも同じ監査ログが表示されるようになります。デバッグや動作確認の際に、ログファイルを確認せずにその場で監査結果を確認できるため便利です。

デフォルト値はoffであり、通常はクライアントには表示されず、サーバのPostgreSQLログにのみログが出力されます。

また、pgaudit.log_clientをonにした場合にのみ有効になるパラメータとしてpgaudit.log_levelがあります。このパラメータは、クライアント側に出力されるログのレベルを指定するものです。 指定可能なログレベルは以下の通りです。

  • debug1からdebug5
  • info
  • notice
  • warning
  • log

なお、error、fatal、panicといった重大なレベルは指定できません。

デフォルト値はlogで、通常のログ出力レベルとして扱われます。

このように、pgaudit.log_clientとpgaudit.log_levelを組み合わせることで、監査ログをクライアント側でリアルタイムに確認しながら開発や検証を行うことが可能になります。

4. pgAuditを使ってみよう(オブジェクト監査ロギング編)

本章では、特定のテーブルやカラム単位で監査を行うオブジェクト監査ロギングについて解説します。

オブジェクト監査ロギングは、監査対象となるロール(マスターロール)を定義し、そのロールに対して特定のオブジェクトへの権限を付与することで、その操作のみを監査ログとして記録する仕組みです。セッション監査ロギングとは異なり、対象を限定して詳細な監査が可能である点が大きな特徴です。

この方式は、機密性の高いテーブルや特定のカラムに対するアクセス履歴のみを取得したい場合に特に有効です。不要なログ出力を抑えつつ、必要な情報だけを正確に取得できるため、実運用においては重要な監査手法の一つとなります。

それでは、マスターロールの作成から権限設定、実際の操作と監査ログの出力内容までを順に確認していきます。

4.1 マスターロールの作成とpgaudit.roleの設定

まず監査対象となるロールを作成します。

=# CREATE ROLE auditmrole;
CREATE ROLE

次にpostgresql.confに以下を設定します。

pgaudit.role = ‘auditmrole’

(例)
$ cd $PGDATA
$ vi postgresql.conf
pgaudit.role = 'auditmrole'
$ pg_ctl reload

postgresql.confの変更後は、pg_ctl reloadコマンドやSQLでのpg_reload_conf関数での、設定再読み込みを忘れずに行ってください。

4.2 マスターロールの権限について

次に、監査対象とするテーブルのテストデータを作成し、テーブルに対して権限を付与します。

ここでは例として、t_mroleテーブルに対して、カラムt1のみを対象にSELECT権限をロールauditmroleに付与します。

(例)
=# CREATE TABLE t_mrole (id int, t1 text);
CREATE TABLE
=# INSERT INTO t_mrole VALUES (1, 'aaa'),(2, 'bbb');
INSERT 0 2
=# SELECT * FROM t_mrole;
 id | t1
----+-----
  1 | aaa
  2 | bbb
(2 行)
=# GRANT SELECT (t1) ON t_mrole TO auditmrole;
GRANT

4.3 マスターロールでの操作と監査ログ

続いてオブジェクト監査ロギングの動作を確認するため、以下のように操作を実行します。

(例)
=# SELECT id FROM t_mrole;
 id
----
  1
  2
(2 行)

postgres=# SELECT id,t1 FROM t_mrole;
 id | t1
----+-----
  1 | aaa
  2 | bbb
(2 行)

結果として、以下のようにt1カラムを含む操作のみが監査ログに記録されます。

(例)
LOG:  AUDIT: OBJECT,4,1,READ,SELECT,TABLE,public.t_mrole,SELECT * FROM t_mrole;,<not logged>
LOG:  AUDIT: OBJECT,5,1,READ,SELECT,TABLE,public.t_mrole,"SELECT id,t1 FROM t_mrole;",<not logged>

auditmroleロールに与えられた権限の通り、t1カラムを含むSELECTは記録されましたが、t1カラムを含まないidカラムのみのSELECT文は記録されませんでした。このようにオブジェクト監査ロギングではauditmroleロールに与えられた権限のみがPostgreSQLログに記録されますので、対象を絞った詳細な監査ログの記録が可能です。

5. おわりに

本稿では、pgAuditの基本からインストール方法、さらにセッション監査ロギングおよびオブジェクト監査ロギングの実践方法までを解説しました。

セッション監査ロギングはデータベース全体の幅広い操作を網羅的に記録する用途に適しており、一方でオブジェクト監査ロギングは特定のテーブルやカラムに対するアクセスを詳細に追跡する用途に適しています。これらを適切に使い分けることで、必要な情報を過不足なく取得し、効率的で実用的な監査ログ運用を実現できます。

このように、データベース運用において監査ログの取得が求められる環境では、pgAuditが標準で利用可能なPowerGres や PowerGres Plus は有力な選択肢となります。追加の拡張導入を最小限に抑えつつ、監査機能をすぐに利用できる点は運用上の大きなメリットです。

さらに、PowerGres Plus の透過的データ暗号化機能と組み合わせることで、データの保護とアクセス監査の両面をカバーすることができます。これらの魅力的な機能によりPowerGres Plus は、単なるデータベース基盤にとどまらず、現場運用に耐えうる柔軟かつ強固なデータベース運用環境を提供します。

ぜひ、PowerGres および PowerGres Plus の利用をご検討ください。

製品・サービスに関するお問い合わせ
03-5979-2701

お問い合せ受付時間 月 - 金 10:00 - 17:00

メールフォームでのお問い合わせ

ページトップへ