pgAudit - 开源PostgreSQL审计日志

翻译自官方文档:传送门html

能力有限,若有错误请指正git

介绍

PostgreSQL审计扩展(pgAudit)经过标准的PostgreSQL日志记录工具提供详细的会话和(或)对象审计日志记录。github

pgAudit的目标是为PostgreSQL用户提供生成审计日志的能力,这些日志一般须要符合政府、金融或ISO认证。sql

审计是对我的或组织帐户的正式检查,一般由独立机构进行。pgAudit收集的信息被正确地称为审计跟踪或审计日志。本文档中使用了审计日志这一术语。数据库

为何使用 pgAudit?

基本语句日志记录能够由 log_statement = all 的标准日志记录工具提供。这对于监视和其余使用是能够接受的,可是没有提供审计所需的详细程度。仅仅拥有对数据库执行的全部操做的列表是不够的。还必须可以找到审计人员感兴趣的特定报表。标准的日志记录功能显示了用户的请求,而pgAudit关注的是数据库知足请求时发生的事情的细节。编程

例如,审计人员可能想要验证某个特定的表是在文档化的维护窗口中建立的。对于grep来讲,这彷佛是一项简单的工做,可是若是您看到这样一个(故意混淆的)例子:后端

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环境中工做时,审计大型事实表中的日志插入可能不太明智。日志文件的大小多是插入的实际数据大小的许多倍,由于日志文件表示为文本。因为日志一般与操做系统一块儿存储,这可能致使磁盘空间很快耗尽。在不可能将审计日志记录限制到某些表的状况下,请确保在测试时评估性能影响,并在日志卷上分配大量空间。对于OLTP环境也是如此。即便插入卷没有那么高,审计日志记录的性能影响仍然会显著影响延迟。

为了限制SELECT和DML语句记录的关系审计的数量,考虑使用对象审计日志记录(请参阅对象审计)。对象审计日志容许选择要记录的关系,从而减小整体日志量。然而,当添加新关系时,它们必须显式地添加到对象审计日志记录中。在这种状况下,将指定的表排除在日志以外并包含全部其余表的编程解决方案多是一个不错的选择。

PostgreSQL版本兼容性

pgAudit支持PostgreSQL 9.5或更高版本。

为了支持在每一个PostgreSQL发行版中引入的新功能,pgAudit为每一个PostgreSQL主版本(当前的PostgreSQL 9.5 - 11)维护一个独立的分支,该分支将以相似于PostgreSQL项目的方式进行维护。

除了bug修复以外,尚未为稳定的分支计划进一步的开发。新的开发(若是有的话)将严格用于下一个未发布的主要版本PostgreSQL。

与PostgreSQL主要版本相关的pgAudit版本以下:

  • pgAudit v1.3.X 用于支持 PostgreSQL 11.

  • pgAudit v1.2.X 用于支持 PostgreSQL 10.

  • pgAudit v1.1.X 用于支持 PostgreSQL 9.6.

  • pgAudit v1.0.X 用于支持 PostgreSQL 9.5.

编译和安装

获取源代码:

git clone https://github.com/postgres/postgres.git

切换分支:

git checkout REL_11_STABLE

编译 PostgreSQL:

./configure
make
make install

切换到 contrib 目录:

cd contrib

获取 pgAudit 扩展源码:

git clone https://github.com/pgaudit/pgaudit.git

切换到 pgAudit 目录:

cd pgaudit

切换分支:

git checkout REL_11_STABLE

编译、安装、回归测试:

make
make install
make check

设置

设置只能由超级用户修改。容许普通用户更改他们的设置将会破坏审计日志。

设置能够全局指定(在 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扩展并须要从新建立pgaudit扩展,那么 pgaudit.log 必须先取消设置,不然会引起错误。

pgaudit.log

指定会话审计日志记录将记录哪类语句。可能的值是:

  • READ: SELECTCOPY 当源是关系或查询时。
  • WRITE: INSERT, UPDATE, DELETE, TRUNCATE, 和COPY 当目标是一个关系时。
  • FUNCTION: 函数调用和 DO 块.
  • ROLE: 与角色和特权相关的语句: GRANT, REVOKE, CREATE/ALTER/DROP ROLE.
  • DDL: 不包含在 ROLE 类中的全部DDL.
  • MISC: 其余的一些命令, 好比 DISCARD, FETCH, CHECKPOINT, VACUUM.

可使用逗号分隔的列表提供多个类,经过在类前面加 - 号能够减去类(参阅 会话审计日志记录).

默认值为 none.

pgaudit.log_catalog

指定若是语句中的全部关系都在pg_catalog中,则应该启用会话日志记录。禁用此设置将减小psql和PgAdmin等工具在日志中大量查询catalog的噪音。

默认值为 on.

pgaudit.log_level

指定将用于日志条目的日志级别 (详见有效级别的消息严重级别),但注意不容许出现 ERROR, FATAL, 和PANIC 。此设置用于回归测试,对于测试或其余目的的最终用户也可能有用。

默认值为 log.

pgaudit.log_parameter

指定审计日志记录应该包括与语句一块儿传递的参数。当参数出现时,它们将包含在语句文本以后的CSV格式中。

默认值为 off.

pgaudit.log_relation

指定会话审计日志记录是否应该为SELECT或DML语句中引用的每一个关系(表、视图等)建立单独的日志条目。对于不使用对象审计日志记录的详尽日志记录,这是一个有用的快捷方式。

默认值为 off.

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');

select *
    from account;

日志输出:

AUDIT: SESSION,1,1,DDL,CREATE TABLE,TABLE,public.account,create table account
(
    id int,
    name text,
    password text,
    description text
);
AUDIT: SESSION,2,1,READ,SELECT,,,select *
    from account

对象审计日志记录

影响特定关系的对象审计日志记录语句。只支持 SELECT, INSERT, UPDATEDELETE 命令。对象审计日志中不包括 TRUNCATE

对象审计日志记录旨在成为pgaudit.log = 'read, write'的细粒度替代。所以,将它们结合使用可能没有任何意义,可是一种可能的场景是使用会话日志记录来捕获每一个语句,而后用对象日志记录来补充这些语句,以得到关于特定关系的更多细节。

配置

对象级审计日志是经过角色系统实现的。pgaudit.role 设置定义用于审计日志记录的角色。当审计角色对执行的命令具备权限或从另外一个角色继承权限时,将记录一个关系(表、视图等)。这容许您有效地拥有多个审计角色,即便在任何上下文中只有一个主角色。

设置pgaudit.role为auditor,并授予account表的SELECT和DELETE权限。account表上的任何SELECT或DELETE语句都将被记录:

set pgaudit.role = 'auditor';

grant select, delete
   on public.account
   to auditor;

实例说明

在这个示例中,使用对象审计日志记录来讲明如何使用粒度方法来记录SELECT和DML语句。注意,account表上的日志记录由列级权限控制,而account_role_map表上的日志记录是表级的。

SQL语句:

set pgaudit.role = 'auditor';

create table account
(
    id int,
    name text,
    password text,
    description text
);

grant select (password)
   on public.account
   to auditor;

select id, name
  from account;

select password
  from account;

grant update (name, password)
   on public.account
   to auditor;

update account
   set description = 'yada, yada';

update account
   set password = 'HASH2';

create table account_role_map
(
    account_id int,
    role_id int
);

grant select
   on public.account_role_map
   to auditor;

select account.password,
       account_role_map.role_id
  from account
       inner join account_role_map
            on account.id = account_role_map.account_id

日志输出:

AUDIT: OBJECT,1,1,READ,SELECT,TABLE,public.account,select password
  from account
AUDIT: OBJECT,2,1,WRITE,UPDATE,TABLE,public.account,update account
   set password = 'HASH2'
AUDIT: OBJECT,3,1,READ,SELECT,TABLE,public.account,select account.password,
       account_role_map.role_id
  from account
       inner join account_role_map
            on account.id = account_role_map.account_id
AUDIT: OBJECT,3,1,READ,SELECT,TABLE,public.account_role_map,select account.password,
       account_role_map.role_id
  from account
       inner join account_role_map
            on account.id = account_role_map.account_id

格式

审计条目被写入标准日志记录工具,并以逗号分隔的格式包含如下列。只有在删除每一个日志条目的日志行前缀部分时,输出才符合CSV格式。

  • AUDIT_TYPE - 会话或对象.

  • STATEMENT_ID - 此会话的惟一语句ID。每一个语句ID表示后端调用。即便没有记录某些语句,语句id也是连续的。当记录多个关系时,语句ID可能有多个条目。

  • SUBSTATEMENT_ID - 主语句中每一个子语句的顺序ID。例如,从一个查询中调用函数。即便没有记录一些子语句,子语句id也是连续的。当记录多个关系时,子语句ID可能有多个条目。

  • CLASS - 例如 READ, ROLE (详见 pgaudit.log).

  • COMMAND - 例如 ALTER TABLE, SELECT

  • OBJECT_TYPE - TABLE, INDEX, VIEW等. 可用于SELECT、DML和大多数DDL语句。

  • OBJECT_NAME - 彻底限定对象名(例如public.account)。可用于SELECT、DML和大多数DDL语句。

  • STATEMENT - 在后端执行的语句。

  • PARAMETER - 若是设置了pgaudit.log_parameter 后,该字段将包含引用CSV的语句参数。

使用log_line_prefix添加知足审计日志需求所需的任何其余字段。典型的日志行前缀多是 '\%m \%u \%d: ' ,它将为每一个审计日志提供日期/时间、用户名和数据库名。

警告

对象重命名被记录在它们重命名的名称下。例如,从新命名表将产生如下结果:

ALTER TABLE test RENAME TO test2;

AUDIT: SESSION,36,1,DDL,ALTER TABLE,TABLE,public.test2,ALTER TABLE test RENAME TO test2

能够将命令记录屡次。例如,当在建立时使用指定的主键建立表时,主键的索引将被独立记录,而对于create条目下的索引将建立另外一个审计日志。可是,多个条目将包含在一个语句ID中。

Autovacuum 和 Autoanalyze 不会被记录。

事务进入停止状态后执行的语句将不会被审计记录。可是,致使错误的语句和在停止的事务中执行的任何后续语句将被标准日志记录工具做为错误记录。

相关文章
相关标签/搜索