pgAudit
Open Source PostgreSQL Audit Logging
PostgreSQL Auditing Extension -- PGAudit
注意:对README.md进行翻译,无校对,有错误,请指出,谢谢!
导言
postgresql审计扩展(PgAudit)通过标准postgresql日志工具提供详细的会话和/或对象审计日志记录。
pgAudit的目标是为postgresql用户提供能够生成审计日志的能力,这些日志通常需要遵从政府、财务或iso认证。
审计是对个人或组织账户的正式检查,通常是由一个独立机构进行的。pgAudit收集的信息被正确地称为审计跟踪或审计日志。此文档中使用了审核日志的术语。
为什么是pgAudit?
标准日志设备可以使用logstatement=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语句记录的关系审计的数量,请考虑使用对象审核日志记录(see Object Auditing)。对象审核日志记录允许选择要记录的关系,从而减少了整个日志卷。但是,在添加新关系时,必须显式地将它们添加到对象审核日志记录中。一个方案解决方案,其中指定的表被排除在日志记录之外,而所有其他的表可能在本例中是一个很好的选择。
PostgreSQL版本兼容性
pgAudit开发支持PostgreSQL 9.5或更高版本。
为了支持每个PostgreSQL版本中引入的新功能,pgAudit为每个PostgreSQL主要版本(目前postgresql 9.5通过postgresql 9.6)维护一个独立的分支,它将以与PostgreSQL项目类似的方式进行维护。
除了bug修复之外,postgresql 9.5还没有通过postgresql 9.6分支进行进一步的开发。新的开发(如果有的话)将严格适用于下一个未发行的postgresql版本。
pgAudit版本与postgresql主要版本有关,如下:
- pgAudit v1.1.X是用于支持postgresql 9.6的。
- pgAudit v1.0.X是用于支持postgresql 9.5的。
编译与安装
Clone the PostgreSQL repository:
git clone https://github.com/postgres/postgres.git
Checkout REL9_6_STABLE branch:
git checkout REL9_6_STABLE
Make PostgreSQL:
./configure
make install -s
Change to the contrib directory:
cd contrib
Clone the pgAudit extension:
git clone https://github.com/pgaudit/pgaudit.git
Change to pgAudit directory:
cd pgaudit
Build pgAudit and run regression tests:
make -s check
Install pgAudit:
make install
设置
设置只能由超级用户进行修改。允许正常用户更改它们的设置将使审计日志的点被破坏。
可以在全局范围内指定设置(in postgresql.conf or using ALTER SYSTEM … SET),在数据库级别(using ALTER DATABASE … SET),或者在角色级别(using ALTER ROLE … SET).请注意,设置不是通过正常角色继承的,而SET ROLE将不会更改用户的pgAudit设置。这是对角色系统的限制,而不是pgAudit所固有的。
pgaudit.log
可能的值是:
- READ: SELECT and COPY when the source is a relation or a query.
- WRITE: INSERT, UPDATE, DELETE, TRUNCATE, and COPY when the destination is a relation.
- FUNCTION: Function calls and DO blocks.
- ROLE: Statements related to roles and privileges: GRANT, REVOKE, CREATE/ALTER/DROP ROLE.
- DDL: All DDL that is not included in the ROLE class.
- MISC: Miscellaneous commands, e.g. DISCARD, FETCH, CHECKPOINT, VACUUM.
可以使用逗号分隔的列表来提供多个类,并且类可以通过使用一种来减少类来减少。
默认值为none。
pgaudit.logcatalog
指定在语句中的所有关系都在pgcatalog中的情况下,应该启用会话日志记录。禁用此设置将减少日志中的噪音,例如psql和PgAdmin等工具,这些工具对目录进行了大量查询。
默认值on 。
pgaudit.log_level
指定用于日志条目的日志级别 (see Message Severity Levels for valid levels) ,但注意,不允许ERROR、FATAL和PANIC。此设置用于进行回归测试,也可能对最终用户用于测试或其他目的使用。
默认值为log。
pgaudit.log_parameter
指定审核日志记录应该包含与语句传递的参数。当参数出现时,在语句文本之后,将以CSV格式包含。
缺省值off。
pgaudit.log_relation
指定会话审核日志记录是否应该为SELECT或DML语句中引用的每个关系(表、视图等)创建单独的日志项。这是在不使用对象审核日志记录的情况下进行穷举日志记录的一种有用的捷径。
缺省值已关闭。
pgaudit.log_statement_once
指定日志记录是否包含语句、文本和参数,其中包含statement/substatement组合的第一个日志条目,或与每个条目一起。禁用此设置将导致更少的日志记录,但可能会使确定生成日志项的语句变得更困难,尽管statement/substatement对和进程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;
Log Output:
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、UPDATE和DELETE命令才会被支持。在对象审核日志记录中不包含TRUNCATE。
pgaudit.log = 'read, write'的一个更细粒度的替换。因此,将它们结合在一起可能是不明智的,但一个可能的场景是使用会话日志记录每个语句,然后用对象日志来补充有关特定关系的更多细节。
配置
对象级别的审计日志记录是通过角色系统实现的。pgaudit.role设置定义了用于审核日志记录的角色。当审计角色具有执行命令的权限或继承来自另一个角色的权限时,将对关系(表、视图等)进行审核。这使您能够有效地拥有多个审计角色,尽管在任何上下文中都有一个主角色。
将pgaudit.role设置为auditor,并grant在ACCOUNT表中的SELECT和DELETE权限。现在将记录帐户表中的任何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
Log Output:
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 - SESSION or OBJECT.
- STATEMENT_ID - Unique statement ID for this session. Each statement ID represents a backend call. Statement IDs are sequential even if some statements are not logged. There may be multiple entries for a statement ID when more than one relation is logged.
- SUBSTATEMENT_ID - Sequential ID for each sub-statement within the main statement. For example, calling a function from a query. Sub-statement IDs are continuous even if some sub-statements are not logged. There may be multiple entries for a sub-statement ID when more than one relation is logged.
- CLASS - e.g. READ, ROLE (see pgaudit.log).
- COMMAND - e.g. ALTER TABLE, SELECT.
- OBJECT_TYPE - TABLE, INDEX, VIEW, etc. Available for SELECT, DML and most DDL statements.
- OBJECT_NAME - The fully-qualified object name (e.g. public.account). Available for SELECT, DML and most DDL statements.
- STATEMENT - Statement executed on the backend.
- PARAMETER - If pgaudit.log_parameter is set then this field will contain the statement parameters as quoted 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
有可能有一个命令记录不止一次。例如,当在创建时使用指定的主键创建表时,主键的索引将独立记录,并将在“创建”项下对索引进行另一项审计日志。但是,多个条目将包含在一个语句id中。
Autovacuum和Autoanalyze并没有记录。
在事务进入已中止状态后执行的语句将不会被审计记录。但是,导致错误的语句和在已中止事务中执行的任何后续语句将被标准日志记录设备记录为错误。
作者
The PostgreSQL Audit Extension is based on the 2ndQuadrant pgaudit project authored by Simon Riggs, Abhijit Menon-Sen, and Ian Barwick and submitted as an extension to PostgreSQL core. Additional development has been done by David Steele of Crunchy Data.