如何使用 pgaudit 扩展来审计运行 PostgreSQL 的 Amazon RDS 数据库实例?

3 分钟阅读
0

我想要审计所有的数据库、角色、关系或列,并且希望为不同的角色提供不同级别的审计。如何在运行 Amazon RDS for PostgreSQL 的 Amazon Relational Database Service (Amazon RDS) 数据库实例上为不同的角色级别配置 pgaudit 扩展?

解决方法

您可以设置不同的参数来记录 PostgreSQL 数据库实例上的活动。要审计不同的数据库、角色、表或列,可以使用 pgaudit 扩展。激活 pgaudit 扩展后,您可以配置 pgaudit.log 参数来审计特定的数据库、角色、表和列。

在运行 PostgreSQL 的 Amazon RDS 实例上激活 pgaudit 扩展

1.    通过运行以下命令创建名为 rds_pgaudit 的特定数据库角色:

CREATE ROLE rds_pgaudit;
CREATE ROLE

2.    在与数据库实例关联的自定义数据库参数组中修改以下参数
shared_preload_libraries 添加或附加 pgaudit
pgaudit.role 配置为在步骤 1 中创建的角色 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 用于审计其他命令,例如 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,因此在 RDS 数据库实例中 test_database 是唯一进行审计的数据库。

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 参数值。在以下示例命令中,角色 test1test2 被更改为具有不同的 pgaudit.log 配置。

1.    运行以下命令,为 test1test2 设置不同的 pgaudit.log 参数值:

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.    同时为 test1test2 运行以下查询:

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>
...

**注意:**SELECT 查询没有审计条目,这是因为 test2pgaudit.log 参数仅配置为 DDL

使用 pgaudit 扩展审计表

配置 pgaudit.log 参数审计并记录影响特定关系的语句。pgaudit 扩展只能记录 SELECTINSERTUPDATEDELETE 命令。TRUNCATE 不包含在对象审计日志记录中。如果您授予 rds_pgaudit 角色访问要审计的表中某个操作(例如 SELECTDELETEINSERTUPDATE)的权限,则任何授权审计都会记录相应的语句。以下示例授予 rds_pgaudit 角色访问 SELECTDELETE 的权限,这样 test_table 上的所有 SELECTDELETE 语句都会被审计。

1.    运行以下命令,授予 rds_pgaudit 角色对 SELECTDELETE 的访问权限:

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 扩展审计列

您还可以为特定表设置列级别的审计。例如,当敏感数据仅存在于一列中时。在以下示例命令中,创建了一个工资表,该表有一个必须审计的包含工资数据的敏感列:

create table payroll
(    
    name text,
    salary text
);

1.    授予 rds_pgaudit 角色对 salary 列上的 SELECT 语句的访问权限,以便对该列上的任何 SELECT 语句进行审计:

grant select (salary)  on payroll to rds_pgaudit;

2.    对表中的所有列执行 SELECT 语句,包括 salary 列:

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>

相关信息

PostgreSQL 的数据库管理员常见任务