PostgreSQL を実行している Amazon RDS DB インスタンスを監査するために pgaudit 拡張機能を使用する方法を教えてください。
最終更新日: 2019 年 10 月 3 日
データベース、ロール、関係、または列をすべて監査し、異なるロールごとに違うレベルの監査結果を取得したいと考えています。PostgreSQL を実行している Amazon Relational Database Service (Amazon RDS) DB インスタンスで、多種類のロールレベルに対して pgaudit 拡張機能を設定する方法を教えてください。
簡単な説明
PostgreSQL DB インスタンスのアクティビティでは、その記録のためにさまざまなパラメータによる設定が行えます。多様なデータベース、ロール、テーブル、または列の監査には、 pgaudit 拡張機能が使用できます。pgaudit 拡張機能を有効にすると、 pgaudit.log パラメータを定義することで、監査するデータベース、ロール、テーブル、および列を指定できます。
解決方法
PostgreSQL を実行する Amazon RDS インスタンスで pgaudit 拡張機能を有効にする
1. 次のコマンドを実行して、rds_pgaudit という専用のデータベースロールを作成します。
CREATE ROLE rds_pgaudit;
CREATE ROLE
2. DB インスタンスに関連付けられている DB パラメータグループを修正し pgaudit を含む共有ライブラリを使用できるようにした上で、pgaudit.role パラメータを設定します。この pgaudit.role を、先に作成したロール rds_pgaudit に設定します。
3. パラメータグループへの変更がインスタンスに反映されるように、インスタンスの再起動を行います。
4. 次のコマンドを実行して、pgaudit が初期化されていることを確認します。
show shared_preload_libraries;
shared_preload_libraries
--------------------------
rdsutils,pgaudit
(1 row)
5. 次のコマンドを実行して pgaudit 拡張機能を作成します。
CREATE EXTENSION pgaudit;
CREATE EXTENSION
6. 次のコマンドを実行して、pgaudit.role が rds_pgaudit に設定されていることを確認します。
show pgaudit.role;
pgaudit.role
------------------
rds_pgaudit
7. 次に示す監査のいずれかを行うため、pgaudit.log パラメータを設定します。
- ALL では、以下のすべてのコマンドを監査します。
- MISC_SET では、SET ROLE などのさまざまな SET コマンドを監査します。
- MISC では、DISCARD、FETCH、CHECKPOINT、VACUUM、SET などの各種コマンドを監査します。
- DDL では、ROLE クラスに含まれていないすべてのデータ記述言語 (DDL) を監査します。
- ROLE では、GRANT、REVOKE、CREATE/ALTER/DROP ROLE など、ロールと権限に関連するステートメントを監査します。
- FUNCTION では、関数呼び出しと DO ブロックを監査します。
- WRITE では、送信先がリレーションである場合に、INSERT、UPDATE、DELETE、TRUNCATE、COPY を監査します。
- READ では、ソースがリレーションまたはクエリである場合、SELECT および COPY を監査します。
pgaudit.log パラメータの値には、監査対象に応じてデータベース、ロール、またはテーブルなどを設定します。
pgaudit 拡張機能を使用したデータベースの監査
1. pgaudit.log パラメータの値にデータベース、ロール、またはテーブルを設定するために、パラメータグループレベルでは pgaudit.log パラメータを none に設定しておきます。
> show pgaudit.log
+---------------+
| pgaudit.log |
|---------------|
| none |
+---------------+
SHOW
2. 次のコマンドを実行して、当該データベースに関してのみ、このパラメーターに関するシステム設定を上書きします。
ALTER DATABASE test_database set pgaudit.log='All';
これにより、パラメータ pgaudit.log の値が All に変更され、 test_database が RDS DB インスタンス内で監査される唯一のデータベースになります。
3. test_database に接続し、次のクエリを実行します。
select * from test_table;
エラーログには、次のような情報が出力されます。
2019-06-25 19:21:35 UTC:192.0.2.7(39330):testpar@test_database:[21638]:LOG: AUDIT: SESSION,2,1,READ,SELECT,,,select * from test_table;,<not logged>
pgaudit 拡張機能を使用してロールを監査する
データベースに対する監査で pgaudit.log パラメータを設定するのと同様に、ここでもロールを修正して pgaudit.log パラメータの値を変更します。次に示すコマンド例では、ロール test1 と test2 では、pgaudit.log の設定がそれぞれ異なっています。
1. 次のコマンドを実行して、pgaudit.log パラメータに対し、それぞれ test1 と test2 で別の値を設定します。
ALTER ROLE test1 set pgaudit.log='All';
ALTER ROLE test2 set pgaudit.log='DDL';
2. 次のクエリを実行して、ロールレベルで変更が行われたことを確認します。
> select rolname,rolconfig from pg_roles where rolname in ('test1','
test2');
+-----------+----------------------+
| rolname | rolconfig |
|-----------+----------------------|
| test1 | [u'pgaudit.log=All'] |
| test2 | [u'pgaudit.log=DDL'] |
+-----------+----------------------+
SELECT 2
Time: 0.010s
3. test1 と test2 の両方に対して次のクエリを実行します。
CREATE TABLE test_table (id int);
CREATE TABLE
select * from test_table;
id
----
(0 rows)
test1 に関するログ出力は次のようになります。
...
2019-06-26 14:51:12 UTC:192.0.2.7(44754):test1@postgres:[3547]:LOG:
AUDIT: SESSION,1,1,DDL,CREATE TABLE,,,CREATE TABLE test_table (id
int);,<not logged>
2019-06-26 14:51:18 UTC:192.0.2.7(44754):test1@postgres:[3547]:LOG:
AUDIT: SESSION,2,1,READ,SELECT,,,select * from test_table;,<not
logged>
...
同じクエリを実行した場合の test2 に関するログ出力は次のようになります。
...
2019-06-26 14:53:54 UTC:192.0.2.7(44772):test2@postgres:[5517]:LOG:
AUDIT: SESSION,1,1,DDL,CREATE TABLE,,,CREATE TABLE test_table (id
int);,<not logged>
...
注: test2 の pgaudit.log パラメータは DDL のみに設定されているため、SELECT クエリに関する監査エントリはありません。
pgaudit 拡張機能を使用したテーブルの監査
pgaudit.log パラメータを設定することで、特定のリレーションに影響するステートメントに関する監査と記録が行えます。pgaudit 拡張機能では、SELECT、INSERT、UPDATE、および DELETE コマンドのみを記録できます。TRUNCATE はオブジェクト監査記録に含まれません。rds_pgaudit ロールに対し、監査対象となるテーブル上のオペレーション (SELECT、DELETE、INSERT、UPDATEなど) へのアクセス権限を付与する場合、関連のあるステートメントが付与監査により記録されます。次の例では、rds_pgaudit ロールに SELECT および DELETE へのアクセス権を付与しているので、すべての SELECT および DELETE ステートメントが test_table において監査されます。
1. 次のコマンドを実行して、rds_pgaudit ロールに対し SELECT および DELETE へのアクセス権を付与します。
grant select, delete on test_table to rds_pgaudit;
2. test_table において DELETE ステートメントを実行し、監査ログが正しく設定されているかどうかをテストします。
Time: 0.008s
DELETE 1
>delete from test_table where pid=5050;
DELETE ステートメントの出力は次のようになります。
2019-06-25 17:13:02
UTC:192.0.2.7(41810):postgresql104saz@postgresql104saz:[24976]:LOG:
AUDIT: OBJECT,3,1,WRITE,DELETE,TABLE,public.t1,delete from test_table where
pid=5050,<not logged>
pgaudit 拡張機能を使用して列を監査する
監査の設定は特定のテーブルの列レベルで行うこともできます。たとえば、機密データが 1 つの列にのみ存在する場合などに使用します。次のコマンド例では、給与データなど機密性が高く監査する必要がある列を含んでいる、給与テーブルが作成されます。
create table payroll
(
name text,
salary text
);
1. rds_pgaudit ロールに、salary 列に対する SELECT ステートメントへのアクセス権を付与し、この列に対する SELECT がすべて監査されるようにします。
grant select (salary) on payroll to rds_pgaudit;
2. salary 列を含む、テーブル内のすべての列に対し SELECT を行います。
select * from payroll;
次の出力例では、salary を含むすべての列に対する SELECT ステートメントが監査されています。ただし、salary 列を含まない SELECT は監査されていません。
2019-06-25
18:25:02
UTC:192.0.2.7(42056):postgresql104saz@postgresql104saz:[4118]:LOG:
AUDIT: OBJECT,2,1,READ,SELECT,TABLE,public.payroll,select * from
payroll,<not logged>