
pgaudit v19beta2
PostgreSQL監査拡張機能
pgAudit
オープンソース PostgreSQL 監査ログ記録
はじめに
PostgreSQL Audit Extension (pgAudit) は、標準の PostgreSQL ログ機能を介して、詳細なセッションおよびオブジェクトの監査ログを提供します。
pgAudit の目標は、政府、金融、ISO 認証などの要件を満たすために必要な監査ログを生成する機能を PostgreSQL ユーザーに提供することです。
監査とは、通常、独立した機関による個人または組織のアカウントの公式な検査です。pgAudit によって収集された情報は、監査証跡または監査ログと呼ばれます。このドキュメントでは「監査ログ」という用語を使用します。
なぜ pgAudit なのか?
基本的なステートメントログは、log_statement = all を設定することで標準のログ機能によって提供できます。これは監視やその他の用途には許容されますが、通常監査に必要なレベルの詳細を提供しません。データベースに対して実行されたすべての操作のリストがあるだけでは不十分です。監査人が関心を持つ特定のステートメントを見つけることも可能でなければなりません。標準のログ機能はユーザーが要求した内容を示しますが、pgAudit はデータベースが要求を満たしている間に実際に何が起こったかの詳細に焦点を当てます。
たとえば、監査人は特定のテーブルが文書化されたメンテナンスウィンドウ内に作成されたことを確認したい場合があります。これは grep で簡単にできるように思えますが、次のような (意図的に難読化された) 例に直面したらどうでしょうか:
DO $$
BEGIN
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;
標準ログでは次のように出力されます:
LOG: statement: DO $$
BEGIN
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;
テーブルが動的に作成される場合、目的のテーブルを見つけるにはコードに関する知識が必要になる可能性があることがわかります。テーブル名だけで検索できれば理想的ですが、そうではありません。ここで pgAudit が活躍します。同じ入力に対して、ログに次の出力を生成します:
AUDIT: SESSION,33,1,FUNCTION,DO,,,"DO $$
BEGIN
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;"
AUDIT: SESSION,33,2,DDL,CREATE TABLE,TABLE,public.important_table,CREATE TABLE important_table (id INT)
DO ブロックがログに記録されるだけでなく、サブステートメント 2 には CREATE TABLE の全文がステートメントタイプ、オブジェクトタイプ、完全修飾名とともに含まれているため、検索が容易です。
SELECT および DML ステートメントをログに記録する場合、pgAudit はステートメント内で参照される各リレーションに対して個別のエントリをログに記録するように設定できます。特定のテーブルに触れるすべてのステートメントを見つけるために解析は必要ありません。実際、目標はステートメントテキストが主に詳細なフォレンジックのために提供され、監査には必須ではないことです。
使用上の考慮事項
設定によっては、pgAudit が膨大な量のログを生成する可能性があります。環境で何を監査ログに記録する必要があるかを正確に判断し、過剰なログを避けるように注意してください。
たとえば、OLAP 環境で作業する場合、大規模なファクトテーブルへの挿入を監査ログに記録することは賢明ではないでしょう。ログファイルのサイズは、挿入の実際のデータサイズの何倍にもなる可能性があります。ログファイルはテキストとして表現されるためです。ログは通常 OS とともに保存されるため、ディスク容量がすぐに枯渇する可能性があります。特定のテーブルに監査ログを制限できない場合は、テスト中にパフォーマンスへの影響を評価し、ログボリュームに十分なスペースを割り当ててください。これは OLTP 環境にも当てはまる可能性があります。挿入ボリュームがそれほど高くなくても、監査ログのパフォーマンスへの影響がレイテンシに顕著に影響を与える可能性があります。
SELECT および DML ステートメントで監査ログに記録されるリレーションの数を制限するには、オブジェクト監査ログ (「オブジェクト監査」を参照) の使用を検討してください。オブジェクト監査ログを使用すると、ログに記録するリレーションを選択できるため、全体的なログ量を削減できます。ただし、新しいリレーションが追加された場合は、オブジェクト監査ログに明示的に追加する必要があります。指定されたテーブルをログから除外し、それ以外をすべて含めるプログラムによる解決策が、この場合には適切な選択肢かもしれません。
PostgreSQL バージョン互換性
pgAudit は PostgreSQL 14 以降をサポートしています。
各 PostgreSQL リリースで導入される新機能をサポートするために、pgAudit は PostgreSQL のメジャーバージョンごとに個別のブランチ (現在は PostgreSQL 14 - 19) を維持しており、PostgreSQL プロジェクトと同様の方法で保守されます。
バグ修正以外には、安定版ブランチに対する新たな開発は許可されません。新たな開発 (もしあれば) は、リリースされていない次の PostgreSQL メジャーバージョンに限定されます。
pgAudit のバージョンは、PostgreSQL のメジャーバージョンと次のように対応します:
-
pgAudit v19.X は PostgreSQL 19 をサポートすることを目的としています。
-
pgAudit v18.X は PostgreSQL 18 をサポートすることを目的としています。
-
pgAudit v17.X は PostgreSQL 17 をサポートすることを目的としています。
-
pgAudit v16.X は PostgreSQL 16 をサポートすることを目的としています。
-
pgAudit v1.7.X は PostgreSQL 15 をサポートすることを目的としています。
-
pgAudit v1.6.X は PostgreSQL 14 をサポートすることを目的としています。
コンパイルとインストール
pgAudit は、開発パッケージがインストールされた PostgreSQL に対して PGXS を使用してコンパイルできます。以下の手順は、ほとんどの Unix 系オペレーティングシステムで動作するはずです。
pgAudit 拡張機能をクローンします:
git clone https://github.com/pgaudit/pgaudit.git
pgAudit ディレクトリに移動します:
cd pgaudit
REL_19_STABLE ブランチをチェックアウトします (リリースされていない PostgreSQL バージョンでは安定版ブランチが存在しない場合があることに注意):
git checkout REL_19_STABLE
pgAudit をビルドしてインストールします:
make install USE_PGXS=1 PG_CONFIG=/usr/pgsql-19/bin/pg_config
テストと開発に関する手順は test にあります。
設定
設定はスーパーユーザーのみが変更できます。通常のユーザーが自分の設定を変更できるようにすると、監査ログの目的が損なわれます。
設定は、グローバル (postgresql.conf または ALTER SYSTEM ... SET を使用)、データベースレベル (ALTER DATABASE ... SET を使用)、またはロールレベル (ALTER ROLE ... SET を使用) で指定できます。設定は通常のロール継承によって継承されず、SET ROLE はユーザーの pgAudit 設定を変更しないことに注意してください。これはロールシステムの制限であり、pgAudit に固有のものではありません。
pgAudit 拡張機能は shared_preload_libraries にロードする必要があります。そうしないと、ロード時にエラーが発生し、監査ログは記録されません。
さらに、pgaudit.log を設定する前に CREATE EXTENSION pgaudit を呼び出して、適切な pgaudit 機能を確保する必要があります。この拡張機能はイベントトリガーをインストールし、DDL に追加の監査機能を提供します。pgAudit は拡張機能がインストールされていなくても動作しますが、DDL ステートメントにはオブジェクトタイプと名前に関する情報が含まれません。
pgaudit 拡張機能を削除して再作成する必要がある場合は、最初に pgaudit.log を設定解除する必要があります。そうしないとエラーが発生します。
pgaudit.log
セッション監査ログによってどのクラスのステートメントがログに記録されるかを指定します。指定可能な値は次のとおりです:
-
READ: ソースがリレーションまたはクエリである場合の
SELECTおよびCOPY。 -
WRITE: 宛先がリレーションである場合の
INSERT、UPDATE、DELETE、TRUNCATE、およびCOPY。 -
FUNCTION: 関数呼び出しおよび
DOブロック。 -
ROLE: ロールと権限に関するステートメント:
GRANT、REVOKE、CREATE/ALTER/DROP ROLE。 -
DDL:
ROLEクラスに含まれないすべてのDDL。 -
MISC: その他のコマンド。例:
DISCARD、FETCH、CHECKPOINT、VACUUM、SET。 -
MISC_SET: その他の
SETコマンド。例:SET ROLE。 -
ALL: 上記のすべてを含みます。
複数のクラスはカンマ区切りリストで指定でき、クラス名の前に - 記号を付けて除外できます (「セッション監査ログ」を参照)。
デフォルトは none です。
pgaudit.log_catalog
ステートメント内のすべてのリレーションが pg_catalog にある場合にセッションログを有効にするかどうかを指定します。この設定を無効にすると、psql や PgAdmin などのツールがカタログを頻繁にクエリすることによるログのノイズが減少します。
デフォルトは on です。
pgaudit.log_client
ログメッセージが psql などのクライアントプロセスから表示可能かどうかを指定します。この設定は通常は無効のままにすべきですが、デバッグやその他の目的には役立つ場合があります。
pgaudit.log_level は pgaudit.log_client が on の場合にのみ有効になることに注意してください。
デフォルトは off です。
pgaudit.log_level
ログエントリに使用されるログレベルを指定します (有効なレベルについては「メッセージ重大度レベル」を参照)。ただし、ERROR、FATAL、PANIC は許可されません。この設定はリグレッションテストに使用され、エンドユーザーがテストやその他の目的にも役立つ場合があります。
pgaudit.log_level は pgaudit.log_client が on の場合にのみ有効になることに注意してください。それ以外の場合はデフォルトが使用されます。
デフォルトは log です。
pgaudit.log_parameter
監査ログにステートメントとともに渡されたパラメータを含めるかどうかを指定します。パラメータが存在する場合、ステートメントテキストの後に CSV 形式で含まれます。
デフォルトは off です。
pgaudit.log_parameter_max_size
この設定値 (バイト単位) より長いパラメータ値はログに記録せず、代わりに <long param suppressed> に置き換えることを指定します。これはバイト単位で設定され、文字単位ではないため、テキストパラメータのエンコーディングにおけるマルチバイト文字は考慮されません。この設定は log_parameter が off の場合は効果がありません。この設定が 0 (デフォルト) の場合、長さに関係なくすべてのパラメータがログに記録されます。
デフォルトは 0 です。
pgaudit.log_relation
セッション監査ログが SELECT または DML ステートメントで参照される各リレーション (TABLE、VIEW など) に対して個別のログエントリを作成するかどうかを指定します。これはオブジェクト監査ログを使用せずに詳細なログを取るための便利なショートカットです。
デフォルトは off です。
pgaudit.log_rows
監査ログにステートメントによって取得または影響を受けた行数を含めるかどうかを指定します。有効にすると、行数フィールドがパラメータフィールドの後に含まれます。
デフォルトは off です。
pgaudit.log_statement
ログにステートメントテキストとパラメータ (有効な場合) を含めるかどうかを指定します。要件によっては、監査ログにこれが不要な場合もあり、ログの冗長性を低下させます。
デフォルトは on です。
pgaudit.log_statement_once
ログにステートメントテキストとパラメータを、ステートメント/サブステートメントの組み合わせの最初のログエントリのみに含めるか、すべてのエントリに含めるかを指定します。この設定を有効にすると、ログの冗長性は低下しますが、ログエントリを生成したステートメントを特定するのが難しくなる可能性があります。ただし、ステートメント/サブステートメントのペアとプロセス ID があれば、以前のエントリでログに記録されたステートメントテキストを特定するには十分なはずです。
デフォルトは off です。
pgaudit.role
オブジェクト監査ログに使用するマスターロールを指定します。マスターロールに権限を付与することで、複数の監査ロールを定義できます。これにより、複数のグループが監査ログのさまざまな側面を担当することが可能になります。
デフォルトはありません。
セッション監査ログ
セッション監査ログは、バックエンドでユーザーが実行したすべてのステートメントの詳細なログを提供します。
設定
セッションログは pgaudit.log 設定で有効になります。
すべての DML および DDL に対してセッションログを有効にし、DML ステートメント内のすべてのリレーションをログに記録します:
set pgaudit.log = 'write, ddl';
set pgaudit.log_relation = on;
MISC を除くすべてのコマンドに対してセッションログを有効にし、監査ログメッセージを NOTICE として出力します:
set pgaudit.log = 'all, -misc';
set pgaudit.log_level = notice;
例
この例では、セッション監査ログを使用して DDL および SELECT ステートメントをログに記録します。WRITE クラスが有効になっていないため、insert ステートメントはログに記録されないことに注意してください。
SQL:
set pgaudit.log = 'read, ddl';
create table account
(
id int,
name text,
password text,
description text
);
insert into account (id, name, password, description)
values (1, 'user1', 'HASH1', 'blah, blah');