为什么要写这个?
话说笔者的一个朋友的朋友在管理一套由第三方搭建的oracle19c RAC集群。为了保证数据安全,于是他写了一个脚本,脚本的作用就是每天定时使用expdp备份数据库中所有业务表。当然,脚本写得没问题,备份也正常。但奇怪的是sysaux表空间总是快速地增长。经过分析,他发现是因为有一个视图,保存了业务上平时所有的操作行为,特别是expdp这种行为,每次备份后都会在这个视图中找到非常非常多的记录。他不明白具体原因,于是咨询我,看能否不让expdp的行为记录到该视图之中。
我听完他的描述后,初步怀疑是审计日志导致的。但在我的印象中,我管理的数据库也没出现这种expdp被大量记录在审计日志中的情况呀!远程连接查看一波,奇怪,sys.aud$表中竟然没有任何内容。而AUDSYS.AUD$UNIFIED表中却看到了大量的审计内容。诶,这还是我所了解的审计吗?这什么情况,感觉要翻车了。
下面,我就临时抱佛脚,通过官方文档和博客,对oracle统一审计进行了整理,希望对大家能有所启发。
一、统一审计
从Oracle12c开始,Oracle引入了统一审计(unified auditing),提供了一整套增强的审计功能。为了向后兼容,仍然支持传统的审计(Traditional auditing)。
统一审计默认是关闭的。如果统一审计关闭,则传统的审计方式生效,可以将audit_trail参数设为:none\os\db\xml\extended,与11g无异。
如果开启统一审计,则audit_trail参数无效,审计记录会自动存储在AUDSYS用户下(AUDSYS.AUD$UNIFIED表),该表默认在SYSAUX表空间中。
Oracle建议将现有审计设置迁移到新的统一审计策略语法。对于新的审计要求,Oracle建议您使用新的统一审计。在未来的主要版本中,可能不再支持传统审计。
二、查看是否开启统一审计
col parameter for a30
col value for a20
select PARAMETER,VALUE FROM V$OPTION WHERE PARAMETER = 'Unified Auditing';
Unified Auditing为false说明统一审计为关闭状态,此时使用的是传统审计。
–如果使用的是传统审计,可再进一步检查audit_trail参数
select name,value from v$parameter where name like '%audit%';
1)若audit_trail为none,且audit_sys_operations参数为true,则只审计且记录sys登录数据库,其他审计规则无效。
如果audit_syslog_level设为非空值,如LOCAL1.INFO,则oracle会将sys的审计日志写到/var/log/messages日志;
如果数据库是asm管理的(非rac),asm实例默认的audit_syslog_level为LOCAL0.INFO,则会将数据库和asm实例的sys登录记录写到/var/log/messages;此时因为数据库实例的audit_syslog_level为空,默认写到audit_file_dest下,asm实例的audit_syslog_level不为空,默认写到/var/log/message下,导致写了双份。
(2)若为非none(os,db,xml,extended等),且audit_sys_operations默认为true,则会记录sys登录和执行的sql。建议将audit_trail设为os,而不是db,os相对较为容易清理(设为db查询较容易)。
关于传统审计,我只说这么多,有需要深入了解的朋友,可以查找相关资料。
三、开启和关闭统一审计
3.1,开启纯统一审计(12C及以上版本)
1)先关库,shutdown immediate
Linux system:
cd $ORACLE_HOME/rdbms/lib
make -f ins_rdbms.mk uniaud_on ioracle
Windows systems:
重命名 %ORACLE_HOME%/bin/orauniaud19.dll.dbl 文件为 %ORACLE_HOME%/bin/orauniaud19.dll
2)开启数据库,startup,再确认统一审计开启是否成功(true):
col parameter for a30
col value for a20
select PARAMETER,VALUE FROM V\$OPTION WHERE PARAMETER = 'Unified Auditing';
3.2,关闭统一审计
先关库,shutdown immediate
再编译:make -f ins_rdbms.mk uniaud_off ioracle
四、统一审计的相关查询
4.1,检查默认enabled的统一审计策略
col policy_name format A18
col audit_option format A40
col ENTITY_NAME for a20
set lines 400 pages 9999 long 9999
select * from audit_unified_enabled_policies;
POLICY_NAME ENABLED_OPTION ENTITY_NAME ENTITY_ SUC FAI
------------------ --------------- -------------------- ------- --- ---
ORA_SECURECONFIG BY USER ALL USERS USER YES YES
ORA_LOGON_FAILURES BY USER ALL USERS USER NO YES
这两个统一审计策略(ORA_SECURECONFIG和ORA_LOGON_FAILURES)是12c之后默认创建的,分别包含的审计内容可通过如下语句查询:
select AUDIT_OPTION from audit_unified_policies where POLICY_NAME='ORA_LOGON_FAILURES' order by AUDIT_OPTION;
select AUDIT_OPTION from audit_unified_policies where POLICY_NAME='ORA_SECURECONFIG' order by AUDIT_OPTION;
在这里我要多说两句,在本文开头,我提到的那个案例中,我通过以上查询,发现对方的数据库确实是开启了统一审计,且只有这两个默认的统一审计策略。并且我也发现,我即使查看这两个默认的策略中包含的审计内容,也并没有看到有对expdp的相关审计策略。那为什么expdp会被审计呢?后来,我在官方文档中看到了相关说明,但我当时没有截图,大意就是:开启统一审计后,exp是默认被审计的,且无法单独关闭,除非直接关闭统一审计。
4.2,查询统一审计写入模式
SELECT PARAMETER_VALUE
FROM DBA_AUDIT_MGMT_CONFIG_PARAMS
WHERE PARAMETER_NAME = 'AUDIT WRITE MODE';
PARAMETER_VALUE
------------------------------
QUEUED WRITE MODE
4.3,在统一审计中创建定制的审计策略
1)查看可以统计的标准系统行为:
set pages 9999 lines 400
col name for a60
SELECT name FROM auditable_system_actions WHERE component = 'Standard' ORDER BY name;
select * from auditable_system_actions where name like '%EXP%'
10 Datapump 1 EXPORT
2)手动关闭某些审计策略:
noaudit policy ORA_SECURECONFIG;
关闭审计策略只会在新连接中关闭生效,已有的连接依旧会审计响应的策略
3)开启审计策略:
audit policy ORA_SECURECONFIG;
同理,开启审计策略只有新连接才能生效,已有的连接仍旧不会审计
4)删除定制的审计策略:
NOAUDIT POLICY audit_dp_export_pol;
DROP AUDIT POLICY audit_dp_export_pol;
5)查询当前审计日志中包含的分类:
select unified_audit_policies,system_privilege_used,AUDIT_TYPE from UNIFIED_AUDIT_TRAIL
group by unified_audit_policies,system_privilege_used,AUDIT_TYPE order by 1;
6)统一审计相关视图:
DBA_AUDIT_MGMT_CLEAN_EVENTS --Displays the cleanup event history
DBA_AUDIT_MGMT_CLEANUP_JOBS --Displays the currently configured audit trail purge jobs
DBA_AUDIT_MGMT_CONFIG_PARAMS --Displays the currently configured audit trail properties
DBA_AUDIT_MGMT_LAST_ARCH_TS --Displays the last archive timestamps set for the audit trails
例:
SELECT PARAMETER_VALUE FROM DBA_AUDIT_MGMT_CONFIG_PARAMS WHERE PARAMETER_NAME = 'AUDIT WRITE MODE'; --查询统一审计写入模式
select * from DBA_AUDIT_MGMT_CONFIG_PARAMS order by parameter_name,audit_trail; --查看当前配置的所有审计属性
五、清理统一审计日志
既然开启统一审计后,无法单独关闭exp的审计行为,那么当前可能就只剩下3个方案:
方案1)更改统一审计日志保存的表空间位置
创建专用表空间
▼▼▼
SQL> CREATE TABLESPACE audit_tbs01 DATAFILE '+DATA' SIZE 30G AUTOEXTEND OFF;
SQL> ALTER TABLESPACE audit_tbs01 ADD DATAFILE '+DATA' SIZE 30G AUTOEXTEND OFF;
调整分区间隔
调整审计数据内部表分区间隔为 1 天。
▼▼▼
BEGIN
dbms_audit_mgmt.alter_partition_interval(interval_number => 1,interval_frequency => 'DAY');
END;
更改审计记录保存的表空间
▼▼▼
BEGIN
dbms_audit_mgmt.set_audit_trail_location(audit_trail_type => dbms_audit_mgmt.AUDIT_TRAIL_UNIFIED,
audit_trail_location_value => 'AUDIT_TBS01');
END;
方案2)彻底关闭统一审计
方案3)定时清理审计日志
–设置自动清理统一日志:
统一审计UNIFIED_AUDIT_TRAIL视图的基表是AUDSYS.AUD$UNIFIED,此表不允许ddl或dml,所以清理统一审计记录只能通过DBMS_AUDIT_MGMT包来处理。
select max(EVENT_TIMESTAMP),min(EVENT_TIMESTAMP) from UNIFIED_AUDIT_TRAIL;
相关存储过程:
DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(
audit_trail_type IN PLS_INTEGER,
last_archive_time IN TIMESTAMP,
rac_instance_number IN PLS_INTEGER DEFAULT NULL,
container IN PLS_INTEGER DEFAULT CONTAINER_CURRENT,
database_id IN NUMBER DEFAULT NULL,
container_guid IN VARCHAR2 DEFAULT NULL);
BEGIN
DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(
audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
last_archive_time => systimestamp-2 /* days */); --清理多少天之前的审计日志
END;
SELECT * FROM dba_audit_mgmt_last_arch_ts;
--初始化clean job,通过第1个过程来判断是否已经初始化,如果为NO,则需要初始化
SET SERVEROUTPUT ON
BEGIN
IF sys.DBMS_AUDIT_MGMT.is_cleanup_initialized(sys.DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD) THEN
DBMS_OUTPUT.put_line('YES');
ELSE
DBMS_OUTPUT.put_line('NO');
END IF;
END;
/
--如果为NO,则执行下面的过程
BEGIN
sys.DBMS_AUDIT_MGMT.init_cleanup(
audit_trail_type => sys.DBMS_AUDIT_MGMT.AUDIT_TRAIL_ALL,
default_cleanup_interval => 48 /* hours */);
END;
/
--创建自动清理job
BEGIN
DBMS_AUDIT_MGMT.CREATE_PURGE_JOB(
audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_ALL,
audit_trail_purge_interval => 48 /* hours */,
audit_trail_purge_name => 'AUD_CLEANUP',
use_last_arch_timestamp => TRUE);
END;
/
BEGIN
DBMS_AUDIT_MGMT.SET_PURGE_JOB_STATUS(
audit_trail_purge_name => 'AUD_CLEANUP',
audit_trail_status_value => DBMS_AUDIT_MGMT.PURGE_JOB_ENABLE);
END;
/
--如果要手动清理统一审计日志
BEGIN
sys.DBMS_AUDIT_MGMT.clean_audit_trail(
audit_trail_type => sys.DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
use_last_arch_timestamp => FALSE /*IF SET TRUE,MUST SET LAST_ARCHIVE_TIMESTAMP */);
END;
/
--禁用默认开启的统一审计策略
SQL> noaudit policy ORA_SECURECONFIG;
SQL> noaudit policy ORA_LOGON_FAILURES;
好了,问题暂时告一段落,希望oracle能够优化统一审计相关策略,希望也能够根据用户的意愿,可以选择对exp审计进行关闭。