使用pgaudit插件
一.介绍
postgresql可以通过log_statement=all 提供日志审计,但是无法详细的提供日志信息,使用ogaudit能够提供详细的会话和对象审计日志,是PG的一个扩展插件
注意:pgAudit可能会生成大量日志。请谨慎确定要在您的环境中记录哪些审核内容,以避免过多记录,可以根据需要开启审计,关闭审计设置pgaudit.log=’none’,并重新加载即可。
二.安装pgaudit
1.查看版本记录信息
yum list pgaudit*
注意:版本和数据库的匹配
使用rockylinux源
查看是否添加postgresql源
dnf repolist
添加 PostgreSQL 官方仓库
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
安装 PostgreSQL 13 及其相关工具
sudo dnf install -y postgresql13 postgresql13-server postgresql13-contrib
查看是否存在
sudo dnf search pgaudit
2.安装对应版本
yum install pgaudit14_12.x86_64
我这里安装pgsql是12,根据你的版本进行安装
使用rockylinux源
用pg-13演示,自行选择版本 查看是否添加postgresql源
dnf repolist
添加 PostgreSQL 官方仓库
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
安装 PostgreSQL 13 及其相关工具
sudo dnf install -y postgresql13 postgresql13-server postgresql13-contrib
查看是否存在
sudo dnf search pgaudit
3.配置postgresql.conf文件
在使用之前我们可以开启数据库链接日志
注:配置文件要修改pg运行的对应文件夹,可以查看服务状态查看
sudo systemctl status postgresql-12
修改配置文件参数
/var/lib/pgsql/12/data/postgresql.conf
修改日志地址和文件名称
log_directory = '/var/log/postgresql' # 使用绝对路径 log_directory = 'log' # 使用相对路径 log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # 以日期和时间命名 log_filename = 'postgresql-%a.log' # 以星期几命名,如 postgresql-Mon.log log_rotation_age = 1d # 每天轮转一次日志 log_rotation_age = 1h # 每小时轮转一次日志 log_rotation_age = 0 # 禁用时间驱动的轮转 log_rotation_size = 10MB # 日志文件达到10MB时轮转 log_rotation_size = 0 # 禁用大小驱动的轮转 log_truncate_on_rotation = on # 截断旧日志文件 log_truncate_on_rotation = off # 追加到旧日志文件 log_file_mode = 0644 # 文件所有者有读写权限,组和其他用户有只读权限
增加日志链接信息
#Log connections and disconnections log_connections = on log_disconnections = on #Optional: Adjust logging format and log file parameters log_line_prefix = '%m [%p] user=%u,db=%d,txid=%x,app=%a,client=%h ' #log_line_prefix 选项允许你自定义 PostgreSQL 日志条目的前#缀格式。你可以使用多种格式符来插入不同的信息。以下是 #log_line_prefix 可用的格式符选项: %a:应用程序名称(application_name) %u:数据库用户名 %d:数据库名 %r:远程主机名和端口 %h:远程主机名 %p:进程 ID %t:时间戳(以 YYYY-MM-DD HH:MI:SS 格式显示) %m:时间戳(以毫秒为单位的精确时间,YYYY-MM-DD HH:MI:SS.MS 格式) %i:命令标识符(command_tag,如 INSERT、UPDATE) %e:SQL 错误码 %c:会话 ID(由 PostgreSQL 生成的唯一会话标识符) %l:日志行号(由日志文件中的行号,计数器) %s:会话开始时间戳 %v:虚拟事务 ID %x:事务 ID %q:无操作(与空字符串相同,可以用来插入常量文本) %%:字面百分号符号 (%)
这些设置将启用连接和断开的日志记录,并将日志行前缀配置为包含时间戳、进程ID、用户名、数据库名、应用程序名和客户端IP地址等信息。
开启前后差别
开启前:
开启后:
4.创建扩展
查看版本
select * from pg_available_extensions where name like '%audit%';
启用
ALTER SYSTEM SET shared_preload_libraries = 'pgaudit';
查看是否启用
SHOW shared_preload_libraries;
配置生效
select pg_reload_conf();
需要重启postgresql
sudo systemctl restart postgresql-12
再次查看是否启用
SHOW shared_preload_libraries;
创建pgaudit
CREATE EXTENSION pgaudit;
删除 wpgaudit
DROP EXTENSION pgaudit;
三.pguadit配置
简介
使用持续时间分为两种方式,一种的只应用于当前会话,一种是持久化应用到角色上,使用方式又分为会话审计日志记录和对象审核日志两种
区别就是
SET pgaudit.log = 'DDL'; 应用于当前会话 ALTER ROLE test_super_user1 SET pgaudit.log = 'DDL'; 持久化应用 alter system set pgaudit.log = 'READ'; 应用到系统,谨慎操作
你可以随时查看你的设置
相关设置
查看相关设置 select name,setting from pg_settings where name ~ 'pgaudit'; 查看role和log SHOW pgaudit.log; SHOW pgaudit.role; 查询用户 select * from pg_user; 查询角色 select * from pg_roles;
接下来我们示例用持久化演示,角色提前创建好
参数介绍
参数 | 说明 |
---|---|
pgaudit.role | 该参数用于指定负责进行审计日志记录的角色。没有默认值,需要手动配置。例如配置为创建的审计用户 auditor 。 |
pgaudit.log | 该参数用于指定哪些操作需要被审计记录。默认值为 none 。取值包括: none:不记录任何操作。 READ:记录 SELECT 和 COPY 操作。 WRITE:记录 INSERT、UPDATE、DELETE、TRUNCATE 和 COPY 操作。FUNCTION:记录函数调用和 DO 块。 ROLE:记录与角色和权限相关的操作,例如 GRANT、REVOKE、CREATE/ALTER/DROP ROLE。 DDL:记录除 ROLE 类外的所有 DDL 操作。 MISC:记录其它操作,例如 DISCARD、FETCH、CHECKPOINT、VACUUM、SET 等。 MISC_SET:记录其他 SET 操作,例如 SET ROLE。 ALL:记录所有操作。多个取值使用逗号分隔。还可以通过 - 符号排除特定值,例如,pgaudit.log = 'all, -misc' 表示记录除 MISC 外的所有操作。 |
pgaudit.log_catalog
指定在语句中的所有关系都在pg_catalog中的情况下,应该启用会话日志记录。禁用此设置将减少日志中的噪音,例如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.logstatementonce
指定日志记录是否包含语句、文本和参数,其中包含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提交:
这种方式可以指定用户或者应用到全部,对操作级别的审计
示例
我们登录test_super_user2
create table account ( id int, name text, password text, description text );
创建表
select * from account; insert into account (id, name, password, description) values (7, 'user1', 'HASH1', 'blah, blah');
查看服务器日志
打开查看,此时并没有日志产生,只有刚刚链接的信息和登录信息
分配test_super_user2 read权限,多个用,分割即可
ALTER ROLE test_super_user2 SET pgaudit.log = 'READ';
执行完毕需要重启服务器或者重新登录
执行完毕查看
SHOW pgaudit.role; SHOW pgaudit.log;
执行测试
select * from account ; insert into account (id, name, password, description) values (5, 'user1', 'HASH1', 'blah, blah');
再次打开日志,出现了我们预料的
多个权限分配
ALTER ROLE test_super_user2 SET pgaudit.log = 'READ,WRITE';
重启pg服务或者重新登录
查询用户,也能看到pgaudit.log
select * from pg_user;
insert into account (id, name, password, description) values (22, 'user1', 'HASH1', 'blah, blah');
打开日志出现了刚刚记录
设置不记录日志
ALTER ROLE you_role SET pgaudit.log = 'NONE';
设置为除以下命令以外的所有命令启用会话日志记录
set pgaudit.log = 'all, -misc';
创建库的审计
ALTER DATABASE pgaudit_testdb SET pgaudit.log = 'READ';
关闭库的审计
ALTER DATABASE pgaudit_testdb SET pgaudit.log = 'NONE';
对象审核日志
简介
只有SELECT、INSERT、UPDATE和DELETE命令才会被支持。在对象审核日志记录中不包含TRUNCATE。
pgaudit.log = 'read, write'的一个更细粒度的替换。因此,将它们结合在一起可能是不明智的,但一个可能的场景是使用会话日志记录每个语句,然后用对象日志来补充有关特定关系的更多细节。
对象级别的审计日志记录是通过角色系统实现的。pgaudit.role设置定义了用于审核日志记录的角色。当审计角色具有执行命令的权限或继承来自另一个角色的权限时,将对关系(表、视图等)进行审核。这使您能够有效地拥有多个审计角色,尽管在任何上下文中都有一个主角色。
将pgaudit.role设置为auditor,并grant在ACCOUNT表中的SELECT和DELETE权限。现在将记录帐户表中的任何SELECT或DELETE语句:
这种方式的概念就是设置角色用另一个角色的权限进行进行审计记录日志,这种提供了更为细致的记录,对表级别的审计
查看对应用户表权限
SELECT grantee, privilege_type FROM information_schema.role_table_grants WHERE table_name='account' AND table_schema='public' AND grantee='user2';
清除权限
REVOKE SELECT,Update ON public.account FROM user2;
查询用户 查看配置
select * from pg_user
示例
用户user1是一个普通用户,记得每次更新完role,重启服务或者重新登录
查看user1用户权限
SELECT grantee, privilege_type FROM information_schema.role_table_grants WHERE table_name='account' AND table_schema='public' AND grantee='user1';
清除权限
REVOKE SELECT ON public.account FROM user1;
查询用户 查看配置
select * from pg_user
清除配置
ALTER ROLE super_user2 RESET pgaudit.role;
重启pgsql-12服务或者重新登录
执行测试
select * from account
此时日志并没有super_user2的日志
设置super_user2按照user2的规则进行审计
ALTER ROLE super_user2 set pgaudit.role = 'user1';
重启pgsql-12服务或者重新登录
执行sql
select * from account
此时日志也不存在记录
分配对应权限
grant select on public.account to user1;
执行sql
select * from account
打开出现日志信息
执行sql
清除权限 REVOKE select,DELETE ON public.account FROM user1;
多权限分配
grant UPDATE,delete on public.account to user1;
查看
SELECT grantee, privilege_type FROM information_schema.role_table_grants WHERE table_name='account' AND table_schema='public' AND grantee='user1';
sql
select * from account ; update account set name = 'qwe' where id = 22;
结果查看