使用 pgAudit 记录数据库活动 - Amazon Relational Database Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

使用 pgAudit 记录数据库活动

金融机构、政府机构和许多行业需要保留审计日志以满足监管要求。通过将 PostgreSQL Audit 扩展(pgAudit)与 RDS for PostgreSQL 数据库实例结合使用,您可以捕获审计人员通常需要或满足监管要求的详细记录。例如,您可以设置 pgAudit 扩展来跟踪对特定数据库和表所做的更改,记录进行更改的用户以及许多其他详细信息。

pgAudit 扩展通过更详细地扩展日志消息,进一步构建原生 PostgreSQL 日志记录基础设施的功能。换句话说,您将使用与查看任何日志消息相同的方法来查看审计日志。有关 PostgreSQL 日志记录的更多信息,请参阅 RDS for PostgreSQL 数据库日志文件

pgAudit 扩展会编辑日志中的敏感数据,例如明文密码。如果您的 RDS for PostgreSQL 数据库实例配置为记录数据操作语言(DML)语句(详情请见为您的 RDS for PostgreSQL 数据库实例开启查询日志记录),则可以使用 PostgreSQL Audit 扩展来避免明文密码问题。

您可以在数据库实例上配置具有高度明确性的审计。您可以审计所有数据库和所有用户。或者,您可以选择仅审计某些数据库、用户和其他对象。您也可以明确排除对某些用户和数据库进行审计。有关更多信息,请参阅从审计日志记录中排除用户或数据库

考虑到可以捕获的详细信息量,我们建议您在使用 pgAudit 时监控存储消耗。

所有可用的 RDS for PostgreSQL 版本。有关可用 RDS for PostgreSQL 版本支持的 pgAudit 版本的列表,请参阅《Amazon RDS for PostgreSQL 版本注释》中的 Amazon RDS for PostgreSQL 的扩展版本

设置 pgAudit 扩展

要在 RDS for PostgreSQL 数据库实例 上设置 pgAudit 扩展,首先要将 pgAudit 添加到 RDS for PostgreSQL 数据库实例的自定义数据库参数组 上的共享库中。有关创建自定义数据库参数组的信息,请参阅 使用参数组接下来,安装 pgAudit 扩展。最后,指定要审计的数据库和对象。本部分中的过程向您展示如何操作。您可以使用 Amazon Web Services Management Console或 Amazon CLI。

您必须拥有 rds_superuser 角色的权限才能执行所有这些任务。

以下步骤假设您的 RDS for PostgreSQL 数据库实例与自定义 数据库参数组相关联。

设置 pgAudit 扩展
  1. 登录 Amazon Web Services Management Console 并通过以下网址打开 Amazon RDS 控制台:https://console.aws.amazon.com/rds/

  2. 在导航窗格中,选择 RDS for PostgreSQL 数据库实例

  3. 打开 RDS for PostgreSQL 数据库实例的 Configuration(配置)选项卡。在实例详细信息中,找到 Parameter group(参数组)链接。

  4. 选择此链接以打开与您的 RDS for PostgreSQL 数据库实例关联的自定义参数。

  5. Parameters(参数)搜索字段中,键入 shared_pre 以查找 shared_preload_libraries 参数。

  6. 选择 Edit parameters(编辑参数)以访问属性值。

  7. pgaudit 添加到 Values(值)字段的列表中。使用逗号分隔值列表中的项目。

    
                添加了 pgAudit 的 shared_preload_libaries 参数的图像。
  8. 重启 RDS for PostgreSQL 数据库实例,以使对 shared_preload_libraries 参数的更改生效。

  9. 当实例可用时,请验证 pgAudit 是否已初始化。使用 psql 连接到 RDS for PostgreSQL 数据库实例,然后运行以下命令。

    SHOW shared_preload_libraries; shared_preload_libraries -------------------------- rdsutils,pgaudit (1 row)
  10. 初始化 pgAudit 后,您现在可以创建扩展了。您需要在初始化库后创建扩展,因为 pgaudit 扩展会为审计数据定义语言(DDL)语句安装事件触发器。

    CREATE EXTENSION pgaudit;
  11. 关闭 psql 会话。

    labdb=> \q
  12. 登录 Amazon Web Services Management Console 并通过以下网址打开 Amazon RDS 控制台:https://console.aws.amazon.com/rds/

  13. 在列表中找到 pgaudit.log 参数并设置为适合您的使用案例的值。例如,将 pgaudit.log 参数设置为 write(如下图所示),可以捕获对日志的插入、更新、删除和其他一些类型的更改。

    
            带有设置的 pgaudit.log 参数的图像。

    还可以为 pgaudit.log 参数选择以下值之一。

    • none – 这是默认值。不记录任何数据库更改。

    • all – 记录所有内容(read、write、function、role、ddl、misc)。

    • ddl – 记录所有数据定义语言(DDL)语句(不包括在 ROLE 类中)。

    • function – 记录函数调用和 DO 块。

    • misc – 记录其他命令,例如 DISCARDFETCHCHECKPOINTVACUUMSET

    • read –当源为关系(例如表)或查询时记录 SELECTCOPY

    • role – 记录与角色和权限相关的语句,例如 GRANTREVOKECREATE ROLEALTER ROLEDROP ROLE

    • write – 当目标为关系(表)时,记录 INSERTUPDATEDELETETRUNCATECOPY

  14. 选择 Save changes(保存更改)。

  15. 通过以下网址打开 Amazon RDS 控制台:https://console.aws.amazon.com/rds/

  16. 从数据库列表中选择 RDS for PostgreSQL 数据库实例以将其选中,然后从 Actions(操作)菜单中选择 Reboot(重启)。

设置 pgAudit

要使用 Amazon CLI 设置 pgAudit,您可以调用 modify-db-parameter-group 操作来修改自定义参数组中的审计日志参数,如以下过程所示。

  1. 使用以下 Amazon CLI 命令向 shared_preload_libraries 参数中添加 pgaudit

    aws rds modify-db-parameter-group \ --db-parameter-group-name custom-param-group-name \ --parameters "ParameterName=shared_preload_libraries,ParameterValue=pgaudit,ApplyMethod=pending-reboot" \ --region aws-region
  2. 使用以下 Amazon CLI 命令重启 RDS for PostgreSQL 数据库实例,以便初始化 pgaudit 库。

    aws rds reboot-db-instance \ --db-instance-identifier your-instance \ --region aws-region
  3. 当实例可用时,您可以验证 pgaudit 是否已初始化。使用 psql 连接到 RDS for PostgreSQL 数据库实例,然后运行以下命令。

    SHOW shared_preload_libraries; shared_preload_libraries -------------------------- rdsutils,pgaudit (1 row)

    初始化 pgAudit 后,您现在可以创建扩展了。

    CREATE EXTENSION pgaudit;
  4. 关闭 psql 会话以便您可以使用 Amazon CLI。

    labdb=> \q
  5. 使用以下 Amazon CLI 命令指定要由会话审计日志记录所记录的语句类别。该示例将 pgaudit.log 参数设置为 write,用于捕获对日志的插入、更新和删除。

    aws rds modify-db-parameter-group \ --db-parameter-group-name custom-param-group-name \ --parameters "ParameterName=pgaudit.log,ParameterValue=write,ApplyMethod=pending-reboot" \ --region aws-region

    还可以为 pgaudit.log 参数选择以下值之一。

    • none – 这是默认值。不记录任何数据库更改。

    • all – 记录所有内容(read、write、function、role、ddl、misc)。

    • ddl – 记录所有数据定义语言(DDL)语句(不包括在 ROLE 类中)。

    • function – 记录函数调用和 DO 块。

    • misc – 记录其他命令,例如 DISCARDFETCHCHECKPOINTVACUUMSET

    • read –当源为关系(例如表)或查询时记录 SELECTCOPY

    • role – 记录与角色和权限相关的语句,例如 GRANTREVOKECREATE ROLEALTER ROLEDROP ROLE

    • write – 当目标为关系(表)时,记录 INSERTUPDATEDELETETRUNCATECOPY

    使用以下 Amazon CLI 命令重启 RDS for PostgreSQL 数据库实例

    aws rds reboot-db-instance \ --db-instance-identifier your-instance \ --region aws-region

审计数据库对象

RDS for PostgreSQL 数据库实例上设置 pgAudit 并根据您的要求进行配置后,将在 PostgreSQL 日志中捕获更多详细信息。例如,虽然默认 PostgreSQL 日志记录配置标识数据库表中发生更改的日期和时间,但使用 pgAudit 扩展后,日志条目可以包括模式、进行更改的用户和其他详细信息,具体取决于扩展参数的配置方式。您可以设置审计以通过以下方法跟踪更改。

  • 对于每个会话,按用户进行跟踪。对于会话级别,您可以捕获完全限定的命令文本。

  • 对于每个对象,按用户和数据库进行跟踪。

当您在系统上创建 rds_pgaudit 角色,然后将此角色添加到自定义参数组中的 pgaudit.role 参数时,将激活对象审计功能。默认情况下,pgaudit.role 参数处于未设置状态,唯一允许的值是 rds_pgaudit。以下步骤假设 pgaudit 已初始化,并且您已按照设置 pgAudit 扩展中的步骤创建了 pgaudit 扩展。


      设置 pgAudit 后 PostgreSQL 日志文件的图像。

如本示例所示,“LOG: AUDIT: SESSION”行提供了有关表及其架构的信息以及其他详细信息。

设置对象审计
  1. 使用 psql 连接到 RDS for PostgreSQL 数据库实例

    psql --host=your-instance-name.aws-region.rds.amazonaws.com --port=5432 --username=postgrespostgres --password --dbname=labdb
  2. 使用以下命令创建名为 rds_pgaudit 的数据库角色。

    labdb=> CREATE ROLE rds_pgaudit; CREATE ROLE labdb=>
  3. 关闭 psql 会话。

    labdb=> \q

    在接下来的几步中,使用 Amazon CLI 修改自定义参数组中的审计日志参数。

  4. 使用以下 Amazon CLI 命令将 pgaudit.role 参数设置为 rds_pgaudit。默认情况下,此参数为空,rds_pgaudit 是唯一允许的值。

    aws rds modify-db-parameter-group \ --db-parameter-group-name custom-param-group-name \ --parameters "ParameterName=pgaudit.role,ParameterValue=rds_pgaudit,ApplyMethod=pending-reboot" \ --region aws-region
  5. 使用以下 Amazon CLI 命令重启 RDS for PostgreSQL 数据库实例,以使对参数的更改生效。

    aws rds reboot-db-instance \ --db-instance-identifier your-instance \ --region aws-region
  6. 运行以下命令确认 pgaudit.role 设置为 rds_pgaudit

    SHOW pgaudit.role; pgaudit.role ------------------ rds_pgaudit

要测试 pgAudit 日志记录,您可以运行几条要审计的示例命令。例如,您可以运行以下命令。

CREATE TABLE t1 (id int); GRANT SELECT ON t1 TO rds_pgaudit; SELECT * FROM t1; id ---- (0 rows)

数据库日志应包含类似于以下内容的条目。

... 2017-06-12 19:09:49 UTC:...:rds_test@postgres:[11701]:LOG: AUDIT: OBJECT,1,1,READ,SELECT,TABLE,public.t1,select * from t1; ...

有关查看日志的信息,请参阅监控 Amazon RDS 日志文件

要了解关于 pgAudit 扩展的更多信息,请参阅 GitHub 上的 pgAudit

从审计日志记录中排除用户或数据库

RDS for PostgreSQL 数据库日志文件中所述,PostgreSQL 日志会消耗存储空间。使用 pgAudit 扩展会在不同程度上增加日志中收集的数据量,具体取决于您跟踪的更改。您可能不需要审计 RDS for PostgreSQL 数据库实例中的每个用户或数据库。

为了最大限度地减少对存储的影响,避免不必要地捕获审计记录,您可以将用户和数据库排除在审计范围之外。您还可以在给定会话中更改日志记录。下面的示例向您演示如何操作。

注意

会话级别的参数设置优先于 RDS for PostgreSQL 数据库实例的自定义数据库参数组中的设置。如果您不希望数据库用户绕过您的审计日志记录配置设置,请务必更改其权限。

假设您的 RDS for PostgreSQL 数据库实例配置为审计所有用户和数据库的相同级别的活动。然后,您决定不想对用户 myuser 进行审计。您可以使用以下 SQL 命令对 myuser 关闭审计功能。

ALTER USER myuser SET pgaudit.log TO 'NONE';

然后,您可以使用以下查询来检查 pgaudit.loguser_specific_settings 列,以确认该参数已设置为 NONE

SELECT usename AS user_name, useconfig AS user_specific_settings FROM pg_user WHERE usename = 'myuser';

您将看到如下输出。

user_name | user_specific_settings -----------+------------------------ myuser | {pgaudit.log=NONE} (1 row)

在给定用户与数据库的会话期间,您可以使用以下命令对此用户关闭日志记录功能。

ALTER USER myuser IN DATABASE mydatabase SET pgaudit.log TO 'none';

使用以下查询,对于特定用户和数据库组合检查 pgaudit.log 的设置列。

SELECT usename AS "user_name", datname AS "database_name", pg_catalog.array_to_string(setconfig, E'\n') AS "settings" FROM pg_catalog.pg_db_role_setting s LEFT JOIN pg_catalog.pg_database d ON d.oid = setdatabase LEFT JOIN pg_catalog.pg_user r ON r.usesysid = setrole WHERE usename = 'myuser' AND datname = 'mydatabase' ORDER BY 1, 2;

您将看到类似以下内容的输出。

user_name | database_name | settings -----------+---------------+------------------ myuser | mydatabase | pgaudit.log=none (1 row)

myuser 关闭审计后,您决定不想跟踪对 mydatabase 的更改。您可以使用以下命令对该特定数据库关闭审计。

ALTER DATABASE mydatabase SET pgaudit.log to 'NONE';

然后,使用以下查询检查 database_specific_settings 列,以确认 pgaudit.log 已设置为 NONE。

SELECT a.datname AS database_name, b.setconfig AS database_specific_settings FROM pg_database a FULL JOIN pg_db_role_setting b ON a.oid = b.setdatabase WHERE a.datname = 'mydatabase';

您将看到如下输出。

database_name | database_specific_settings ---------------+---------------------------- mydatabase | {pgaudit.log=NONE} (1 row)

要将 myuser 的设置恢复为默认设置,请使用以下命令:

ALTER USER myuser RESET pgaudit.log;

要将数据库的设置恢复为默认设置,请使用以下命令。

ALTER DATABASE mydatabase RESET pgaudit.log;

要将用户和数据库重置为默认设置,请使用以下命令。

ALTER USER myuser IN DATABASE mydatabase RESET pgaudit.log;

还可以通过将 pgaudit.log 设置为 pgaudit.log 参数的其他允许值之一,将特定事件捕获到日志中。有关更多信息,请参阅pgaudit.log 参数允许的设置列表

ALTER USER myuser SET pgaudit.log TO 'read'; ALTER DATABASE mydatabase SET pgaudit.log TO 'function'; ALTER USER myuser IN DATABASE mydatabase SET pgaudit.log TO 'read,function'

pgAudit 扩展的参考

您可以通过更改本节中列出的一个或多个参数来为审计日志指定所需的详细级别。

控制 pgAudit 行为

您可以通过更改下表中列出的一个或多个参数来控制审计日志记录。

参数 描述

pgaudit.log

指定会话审计日志记录将记录哪些语句类。允许的值包括 ddl、function、misc、read、role、write、none、all。有关更多信息,请参阅pgaudit.log 参数允许的设置列表

pgaudit.log_catalog

启用(设置为 1)时,如果语句中的所有关系都在 pg_catalog 中,则将语句添加到审计跟踪中。

pgaudit.log_level

指定要用于日志条目的日志级别。允许的值:debug5、debug4、debug3、debug2、debug1、info、notice、warning、log

pgaudit.log_parameter

启用(设置为 1)时,将在审计日志中捕获随语句传递的参数。

pgaudit.log_relation

启用(设置为 1)时,会话的审计日志为 SELECCT 或 DML 语句中引用的每个关系(TABLE、VIEW 等)创建单独的日志条目。

pgaudit.log_statement_once

指定日志记录在语句/子语句组合中的第一个日志条目中包含语句文本和参数,还是在每个条目中都包含。

pgaudit.role

指定用于对象审计日志记录的主角色。唯一允许的条目是 rds_pgaudit

pgaudit.log 参数允许的设置列表

描述

none

这是默认模式。不记录任何数据库更改。

全部

记录所有内容(read、write、function、role、ddl、misc)。

ddl

记录所有数据定义语言(DDL)语句(不包括在 ROLE 类中)。

函数

记录函数调用和 DO 块。

misc

记录其他命令,例如 DISCARDFETCHCHECKPOINTVACUUMSET

read

当源为关系(例如表)或查询时记录 SELECTCOPY

role

记录与角色和权限相关的语句,例如 GRANTREVOKECREATE ROLEALTER ROLEDROP ROLE

write

当目标为关系(表)时,记录 INSERTUPDATEDELETETRUNCATECOPY

要使用会话审计记录多种事件类型,请使用逗号分隔的列表。要记录所有事件类型,请将 pgaudit.log 设置为 ALL。重启数据库实例以应用更改。

通过对象审计,您可以细化审计日志记录以使用特定的关系。例如,您可以指定要对一个或多个表上的 READ 操作进行审计日志记录。