GaussDB(DWS)数据库安全守护者之审计日志

举报
半岛里有个小铁盒 发表于 2024/02/25 17:06:12 2024/02/25
【摘要】 数据库安全对数据库系统来说至关重要,而数据库审计日志是数据库安全的重要一环。GaussDB(DWS)将用户的所有操作写入审计日志。数据库安全管理员可以利用这些日志信息,重现导致数据库现状的一系列事件,找出非法操作的用户、时间和内容等。

GaussDB(DWS)数据库安全守护者之审计日志

1.前言

适用版本:【8.1.0(及以上)】

数据库安全对数据库系统来说至关重要,而数据库审计日志是数据库安全的重要一环。GaussDB(DWS)将用户的所有操作写入审计日志。数据库安全管理员可以利用这些日志信息,重现导致数据库现状的一系列事件,找出非法操作的用户、时间和内容等。

2.背景简介

GaussDB(DWS)的审计日志通过日志文件来承载,默认目录为$GAUSSLOG/pg_audit。其中,存在多个审计文件和一个index_table,index_table中标识了现有的文件数量、文件大小、文件时间等详细信息,根据该内容可对审计日志进行老化、新增、分裂、查询索引等操作。经过了多次演进,审计日志中记录的内容已经日益全面,且具有很强的配置性。不同版本之间审计日志新增内容简介如下:

版本 实现或优化内容 字段数 备注
8.0.0 最初版审计日志,支持审计DML、存储过程、copy操作 12 审计雏形,保证语句级记录
8.1.1 全面覆盖对各操作类型的审计,同时将命令执行失败场景也纳入系统审计 17 优化审计选项,场景覆盖全面
8.2.1 DML操作和部分DDL操作中对于列的操作纳入审计,并记录返回行数 20 增加审计细粒度

3. 审计日志配置介绍

关于审计功能的配置,需要清楚审计开关的设计。审计的开关可配置性较多,灵活性较强,以下将介绍其中重要的开关选项。

3.1 审计日志记录配置

  • audit_enabled:审计总开关,为布尔型开关,默认值为on,表示开启审计功能。审计总开关的开启和关闭也会被记录到审计日志中。
  • audit_inner_tool:内部维护工具对应的审计开关,控制是否对来自内部维护工具的操作进行审计;为布尔型开关,默认值为off,表示关闭对来自内部维护工具的操作进行审计。内部维护工具包括:cm_agent、gs_clean、OM、gs_roach、gs_redis、wlm、gs_ctl、gs_rewind等。
  • audit_operation_exec:执行成功操作对应的审计开关,支持对各操作类型进行配置,只有审计类型被配置,对应的操作执行成功时才会被记录到审计日志中。
  • audit_operation_error:执行失败操作对应的审计开关,支持对各操作类型进行配置,只有审计类型被配置,对应的操作执行失败时才会被记录到审计日志中。
  • audit_system_object:控制DDL操作对象的审计开关,数据库的DDL(CREATE,ALTER,DROP,表对象还包含TRUNCATE)操作的对象较多,通过该配置参数在操作对象维度上对审计进行更细粒度的控制。
  • audit_object_details:控制object_details字段是否对语句中的表名、列名以及列使用的类型以json格式进行审计;其中字段记录的场景有:SELECT、DELETE、UPDATE、INSERT、MERGE、CREATE TABLE AS SELECT,GRANT、DECLARE CURSOR,其中对于执行失败的GRANT语句不予记录(8.2.1版本及以上)
  • audit_object_name_format:控制审计日志object_name字段所显示的对象名的格式。其中选项为single时,表示object_name字段显示单个对象名,且为目标对象的名称。选项为all,表示object_name字段显示多个对象名称,并以json格式展示。(8.2.0版本及以上)

通常情况下,为保证审计日志中内容不会重复记录,默认仅会开启CN上的audit_enabled开关,从而使日志均记录在CN上,并且如果为非客户端下发语句而是从其他CN上下发的语句,也不做记录。

3.2 审计日志维护配置

  • audit_directory:审计文件的存储目录。一个相对于数据目录data的路径,可自行指定,默认值为pg_audit。如果指定,也只能指定在$GAUSSLOG下
  • audit_space_limit:审计文件占用的磁盘空间总量。取值范围为1024KB~1024GB
  • audit_file_remain_threshold:审计目录下审计文件个数的最大值。默认值为1048576
  • audit_data_format:审计日志文件的格式。当前仅支持二进制格式。
  • audit_rotation_interval:指定创建一个新审计日志文件的时间间隔。当现在的时间减去上次创建一个审计日志的时间超过了此参数值时,服务器将生成一个新的审计日志文件。
  • audit_rotation_size:指定审计日志文件的最大容量。当审计日志消息的总量超过此参数值时,服务器将生成一个新的审计日志文件。
  • audit_resource_policy:控制审计日志的保存策略,以空间还是时间限制为优先策略。如果开启了以时间限制为优先,存储的审计日志所占磁盘空间达到audit_space_limit,此时也会对审计日志做老化操作。
  • audit_file_remain_time:表示需记录审计日志的最短时间要求,该参数audit_resource_policy在为off时生效。

以上参数中,如果需要控制审计日志的存储空间和时间,最好使用audit_resource_policyaudit_space_limitaudit_file_remain_time参数进行控制。

**注:**9.1.0以前版本,audit_space_limit参数有大变小调整范围过大时,审计线程会一直执行老化操作,可能会导致业务语句无法处理和记录。因此建议该参数由大变小时每次调整10G。9.1.0版本对此做了优化,每次对于审计日志的老化最多老化10个,当在业务空闲期再对审计日志进行老化操作。

4 审计日志参数具体配置及记录范围

4.1审计开关audit_operation_exec的配置

audit_operation_exec的默认配置项为:login, logout, database_process, user_lock, grant_revoke, select, set, transaction, cursor

表示对用户登录、注销、数据库启动\停止\切换\恢复、用户锁定\解锁、权限授予\收回、SET操作、事务操作、游标操作的成功场景进行审计。

如需要增加审计操作,支持的配置项如下:

配置项 描述
none 表示未配置审计项,如果同时配置了其他任何审计项,则none失效
all 表示对所有操作成功的场景进行审计。如果同时配置了其他任何审计项,则覆盖所有其他审计项的配置。需要注意,即使配置为all,也不表示对所有的DDL操作进行审计,仍然需要结合audit_system_object,对DDL操作的对象级别进行控制
login 表示对用户登录成功的场景进行审计,默认配置
logout 表示对用户退出进行审计,默认配置
database_process 表示对数据库启动、停止、切换、恢复操作进行审计,默认配置
user_lock 表示对用户锁定和解锁成功的场景进行审计,默认配置
grant_revoke 表示对用户权限授予和回收成功的场景进行审计,默认配置
ddl 表示对DDL操作成功的场景进行审计,因为DDL操作由会根据操作对象进行更细粒度控制,仍然沿用审计开关audit_system_object,即由audit_system_object控制对哪些对象的DDL操作进行审计(此处不配置ddl,只要配置了audit_system_object,审计也会生效)
select 表示对select操作成功的场景进行审计
copy 表示对copy操作成功的场景进行审计
userfunc 表示对用户自定义函数、存储过程、匿名块操作成功的场景进行审计
set 表示对set操作成功的场景进行审计,默认配置
transaction 表示对事务操作成功的场景进行审计
vacuum 表示对vacuum操作成功的场景进行审计
analyze 表示对analyze操作成功的场景进行审计
explain 表示对explain操作成功的场景进行审计
specialfunc 表示对特殊函数调用操作成功的场景进行审计,包括:pg_terminate_backendpg_cancel_backend等强制终止业务函数
insert 表示对insert操作成功的场景进行审计
update 表示对update操作成功的场景进行审计
delete 表示对delete操作成功的场景进行审计
merge 表示对merge操作成功的场景进行审计
show 表示对show操作成功的场景进行审计
checkpoint 表示对checkpoint操作成功的场景进行审计
barrier 表示对barrier操作成功的场景进行审计
cluster 表示对cluster操作成功的场景进行审计
comment 表示对comment操作成功的场景进行审计
cleanconn 表示对clean connection操作成功的场景进行审计
prepare 表示对PREPARE、EXECUTE、DEALLOCATE操作成功的场景进行审计
constraints 表示对constraints操作成功的场景进行审计
cursor 表示对游标操作成功的场景进行审计

4.2审计开关audit_operation_error的配置

audit_operation_error的默认配置项为:login表示对登录失败的场景进行审计;

支持的配置项如下:

配置项 描述
none 表示未配置审计项,如果同时配置了其他任何审计项,则none失效
syn_success 表示同步audit_operation_exec的配置,即配置了某操作执行成功场景的审计,则对应的执行失败场景也记入审计。需注意,配置了syn_success后,仍可以继续配置其他操作执行失败场景的审计;如果audit_operation_exec配置为all,则所有的失败场景均记入审计;如果audit_operation_exec配置为none,则syn_success等同于none,即未配置审计项
parse 表示对用户输入命令解析失败场景进行审计,包含等待命令超时的失败场景
login 表示对用户登录失败的场景进行审计,默认配置
user_lock 表示对用户锁定和解锁失败的场景进行审计
violation 表示对用户访问存在越权的场景进行审计
grant_revoke 表示对用户权限授予和回收失败的场景进行审计
ddl 表示对DDL操作失败的场景进行审计,因为DDL操作由会根据操作对象进行更细粒度控制,仍然需要结合audit_system_object的配置情况,所以此处配置ddl后,将对audit_system_object指定类型的DDL失败场景进行审计
select 表示对SELECT操作失败的场景进行审计
copy 表示对COPY操作失败的场景进行审计
userfunc 表示对用户自定义函数、存储过程、匿名块操作失败的场景进行审计
set 表示对SET操作失败的场景进行审计
transaction 表示对事务操作失败的场景进行审计
vacuum 表示对VACUUM操作失败的场景进行审计
analyze 表示对ANALYZE操作失败的场景进行审计
explain 表示对EXPLAIN操作失败的场景进行审计
specialfunc 表示对特殊函数调用操作失败的场景进行审计,包括:pg_terminate_backendpg_cancel_backend等强制终止业务函数
insert 表示对INSERT操作失败的场景进行审计
update 表示对UPDATE操作失败的场景进行审计
delete 表示对DELETE操作失败的场景进行审计
merge 表示对MERGE操作失败的场景进行审计
show 表示对SHOW操作失败的场景进行审计
checkpoint 表示对CHECKPOINT操作失败的场景进行审计
barrier 表示对BARRIER操作失败的场景进行审计
cluster 表示对CLUSTER操作失败的场景进行审计
comment 表示对COMMENT操作失败的场景进行审计
cleanconn 表示对CLEAN CONNECTION操作失败的场景进行审计
prepare 表示对PREPARE、EXECUTE、DEALLOCATE操作失败的场景进行审计
constraints 表示对CONSTRAINTS操作失败的场景进行审计
cursor 表示对游标操作失败的场景进行审计
blacklist 表示对黑名单操作的执行失败进行审计

4.3审计开关audit_system_object的配置

audit_system_object的值由22个二进制位的组合求出,这22个二进制位分别代表GaussDB(DWS)的22类数据库对象。

每一位可以取值0或1,取值的含义为:

  • 取值为0:表示不审计对应的数据库对象的DDL操作;
  • 取值为1:表示审计对应的数据库对象的DDL操作;

例如:默认值为12295,对应的二进制为0011 0000 0000 0111(高位在前,低位在后),表示打开第0位、第1位、第2位、第12位、第13位对应对象的DDL操作的审计,具体对应DATABASE、SCHEMA、USER、DATA SOURCE、NODE GROUP这五个对象。

如需要增加审计table类型的DDL操作,可以通过以下方式进行设置:

  • table在第3位,对应的十进制为8

  • 在原有12295的基础上加上8,得12303

  • 将audit_system_object的值设置为12303即可,如下:

    gs_guc reload -Z coordinator -Z datanode -N all -I all -c "audit_system_object = 12303"
    

这22个二进制位代表的具体含义如下:

二进制位 含义说明
第0位 是否审计DATABASE对象的CREATE、DROP、ALTER操作
第1位 是否审计SCHEMA对象的CREATE、DROP、ALTER操作
第2位 是否审计USER对象的CREATE、DROP、ALTER操作
第3位 是否审计TABLE对象的CREATE、DROP、ALTER、TRUNCATE操作
第4位 是否审计INDEX对象的CREATE、DROP、ALTER操作
第5位 是否审计VIEW对象的CREATE、DROP、ALTER操作
第6位 是否审计TRIGGER对象的CREATE、DROP、ALTER操作
第7位 是否审计PROCEDURE/FUNCTION对象的CREATE、DROP、ALTER操作
第8位 是否审计TABLESPACE对象的CREATE、DROP、ALTER操作
第9位 是否审计RESOURCE POOL对象的CREATE、DROP、ALTER操作
第10位 是否审计WORKLOAD对象的CREATE、DROP、ALTER操作
第11位 是否审计SERVER FOR HADOOP对象的CREATE、DROP、ALTER操作
第12位 是否审计DATA SOURCE对象的CRAETE、DROP、ALTER操作
第13位 是否审计NODE GROUP对象的CREATE、DROP、ALTER操作
第14位 是否审计ROW LEVEL SECURITY对象的CREATE、DROP、ALTER操作
第15位 是否审计TYPE对象的CREATE、DROP、ALTER操作
第16位 是否审计TEXT SEARCH对象(CONFIGURATION和DICTIONARY)的CREATE、DROP、ALTER操作
第17位 是否审计DIRECTORY对象的CREATE、DROP、ALTER操作
第18位 是否审计SYNONYM对象的CREATE、DROP、ALTER操作
第19位 是否审计REDACTION POLICY对象的CREATE、DROP、ALTER操作
第20位 是否审计SEQUENCE对象的CREATE、DROP、ALTER操作
第21位 是否审计NODE对象的CREATE、DROP、ALTER操作

**注:**事务操作具有一定的特殊性,一个事务块涉及到多个语句的执行。如果在事务块进行中,对事务审计配置项(transaction)进行动态修改,将导致该事务块的审计记录不完整的问题。事务审计部分对这种情况按如下约定方式处理:

  • 事务进行中事务配置项开启(无头有尾),不审计后续操作(无头有尾不记尾)
  • 事务进行中事务配置项关闭(有头无尾),审计后续操作直到事务end(有头无尾不掉尾)
  • 事务进行中,事务开关保持开启,但审计总开关开启(开总闸),因事务块的部分语句已经执行完毕,无法记录,所以不审计改事务块的后续操作(无头有尾不记尾)
  • 事务进行中,事务开关保持开启,但审计总开关关闭(断总闸),因事务块部分操作已经被记录,为保证事务记录的完整性,审计线程将继续运行,直到该事务块的end被审计后审计线程才退出(有头无尾不掉尾)
  • 事务进行中,事务开关保持开启,会话结束,记录事务回滚(未提交事务必回滚)

5. 审计日志查看

只有拥有AUDITADMIN属性的用户才可以查看审计记录。

审计日志需通过以下数据库接口

  • pg_query_audit(timestamptz startime,timestamptz endtime, audit_log):查看当前CN的审计日志,可以指定需要读取审计日志的目录,默认从$GAUSSHOME/audit_directory中读取。
  • pgxc_query_audit(timestamptz startime,timestamptz endtime):查看所有CN的审计日志
  • pg_query_audit_details(timestamptz startime,timestamptz endtime, text node_mode):查看审计日志并将审计日志中的object_name和object_details字段由json格式解析出来;其中node_mode字段选项为current表示查询当前CN节点的审计日志,all表示查询所有CN节点的审计日志。

以上三个函数中,最开始的startimeendtime分别表示审计记录的开始时间和结束时间,满足审计条件的记录为startime ≤ 单条审计信息记录的结束时间 < endtime

审计日志查看结果解析(821版本),各字段含义如下:

字段 含义
begintime 执行操作的开始时间(811版本新增)
endtime 执行操作的结束时间,查看审计日志是根据此时间判断的
operation_type 操作类型(811版本新增)
audit_type 审计类型
result 执行操作的结果
username 执行操作的用户名
database 数据库名称
client_conninfo 客户端信息
object_name 操作对象的名称
object_details 对语句中的表名、列名以及列使用的类型以json格式进行审计(821版本新增)
command_text 执行操作的命令(811版本新增)
detail_info 执行操作详细信息
transaction_xid 事务id(811版本新增)
query_id query id(811版本新增)
node_name 节点名称
thread_id 线程id
local_port 本地节点
remote_port 远端节点
result_rows 执行成功时的返回行(821版本新增)
error_code 执行失败时的错误码(821版本新增)

设置GUC参数,执行SELECT语句,查看审计日志记录,查询结果如下:

1.设置GUC参数
gs_guc reload -Z coordinator -Z datanode -N all -I all -c "audit_operation_exec='login, logout, database_process, user_lock, grant_revoke, set, transaction, cursor,select'"
gs_guc reload -Z coordinator -Z datanode -N all -I all -c "audit_object_details=on'"
gs_guc reload -Z coordinator -Z datanode -N all -I all -c "audit_object_name_format='all'"

2.执行select
postgres=# select * from t1 left join t2 on t1.a = t2.a;
 a | b | c | a | b | c
---+---+---+---+---+---
 1 | 1 | 1 |   |   |
(1 row)

3.查看审计日志记录
postgres=# select * from pg_query_audit(sysdate-0.1,sysdate) order by begintime desc, endtime desc limit 1;
-[ RECORD 3 ]---+-------------------------------------------------------------------------------------------------
begintime       | 2024-01-23 10:34:56.972+08
endtime         | 2024-01-23 10:34:56.985+08
operation_type  | dml
audit_type      | dml_action_select
result          | ok
username        | w00804127
database        | postgres
client_conninfo | gsql@[local]
object_name     | ["public.t1","public.t2"]
object_details  | {"public.t1":[{"a":"22"},{"b":"2"},{"c":"2"}],"public.t2":[{"a":"22"},{"b":"2"},{"c":"2"}]}
command_text    | select * from t1 left join t2 on t1.a = t2.a;
detail_info     |
transaction_xid | 0
query_id        | 72339069014638717
node_name       | coordinator1
session_id      | 1705976808.140052286080432.coordinator1
local_port      | 37100
remote_port     |
result_rows     | 1
error_code      |

postgres=# select * from pg_query_audit_details(sysdate-0.1,sysdate,'current') where command_text like 'select * from t1 left join%' and query_id = 72339069014638717 order by begintime desc, endtime desc limit 4;
-[ RECORD 1 ]---+----------------------------------------------
begintime       | 2024-01-23 10:34:56.972+08
endtime         | 2024-01-23 10:34:56.985+08
operation_type  | dml
audit_type      | dml_action_select
result          | ok
username        | w00804127
database        | postgres
client_conninfo | gsql@[local]
transaction_xid | 0
query_id        | 72339069014638717
node_name       | coordinator1
session_id      | 1705976808.140052286080432.coordinator1
local_port      | 37100
remote_port     |
object_name     | public.t1
column_name     | a
type_of_use     | 22
use_type        | Access,Conditional,Outer join
command_text    | select * from t1 left join t2 on t1.a = t2.a;
-[ RECORD 2 ]---+----------------------------------------------
begintime       | 2024-01-23 10:34:56.972+08
endtime         | 2024-01-23 10:34:56.985+08
operation_type  | dml
audit_type      | dml_action_select
result          | ok
username        | w00804127
database        | postgres
client_conninfo | gsql@[local]
transaction_xid | 0
query_id        | 72339069014638717
node_name       | coordinator1
session_id      | 1705976808.140052286080432.coordinator1
local_port      | 37100
remote_port     |
object_name     | public.t1
column_name     | b
type_of_use     | 2
use_type        | Access
command_text    | select * from t1 left join t2 on t1.a = t2.a;
-[ RECORD 3 ]---+----------------------------------------------
begintime       | 2024-01-23 10:34:56.972+08
endtime         | 2024-01-23 10:34:56.985+08
operation_type  | dml
audit_type      | dml_action_select
result          | ok
username        | w00804127
database        | postgres
client_conninfo | gsql@[local]
transaction_xid | 0
query_id        | 72339069014638717
node_name       | coordinator1
session_id      | 1705976808.140052286080432.coordinator1
local_port      | 37100
remote_port     |
object_name     | public.t1
column_name     | c
type_of_use     | 2
use_type        | Access
command_text    | select * from t1 left join t2 on t1.a = t2.a;
-[ RECORD 4 ]---+----------------------------------------------
begintime       | 2024-01-23 10:34:56.972+08
endtime         | 2024-01-23 10:34:56.985+08
operation_type  | dml
audit_type      | dml_action_select
result          | ok
username        | w00804127
database        | postgres
client_conninfo | gsql@[local]
transaction_xid | 0
query_id        | 72339069014638717
node_name       | coordinator1
session_id      | 1705976808.140052286080432.coordinator1
local_port      | 37100
remote_port     |
object_name     | public.t2
column_name     | a
type_of_use     | 22
use_type        | Access,Conditional,Outer join
command_text    | select * from t1 left join t2 on t1.a = t2.a;

6.总结

GaussDB(DWS)审计日志作为GaussDB(DWS)集群数据安全运维的重要支撑手段,记录着数据库的启动和停止、用户的登录和退出、各种各样的语句的执行情况、访问越权操作、事务操作等等,可以提供合规审计依据,支持审计数据转储以满足对审计数据保存期限的要求,可以记录、分析、追踪数据库安全事件,可以进行问题定位等。本文详细介绍了审计日志的版本发展历程,并总结了现有规格,标明了审计中常常遇到的问题及具体解决方案。

7.参考文献

  1. GaussDB(DWS)数据库安全守护者之审计日志 https://bbs.huaweicloud.com/blogs/253698
  2. 【如何保证你的DWS数据更安全】GaussDB(DWS) 8.2.1版本审计日志新增功能介绍 https://bbs.huaweicloud.com/blogs/407529
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。