基于系统级触发器的审计功能
從Oracle8i開始,Oracle引入了特殊的觸發器,這些觸發器并不是和特殊的DML事件相關聯的(DML事件,如,INSERT,UPDATE和DELETE)。這些系統級別的觸發器包括:
l?????????數據庫啟動/關閉觸發器
l?????????DDL觸發器
l?????????最終用戶登陸/注銷觸發器
l?????????系統錯誤觸發器
l?????????DDL觸發器
使用這些觸發器,可以對數據庫發生的一些重要事件進行審計。
當觸發事件發生的時候,可以啟動觸發器。在觸發器中,可以通過DML操作將審計操作記錄在日志表中,或者通過拋出一個EXCEPTION來制止某種操作。在觸發器中,可以通過使用系統事件函數(Event Attribute Functions)來獲取一些信息。以下是系統事件函數的詳細情況:
| 系統事件函數 | |||
| 函數名稱 | 類型 | 描述 | 備注 |
| ora_client_ip_address | VARCHAR2 | 客戶端的IP地址 | ? |
| ora_database_name | VARCHAR2(50) | 數據庫名稱 | ? |
| ora_dict_obj_name | VARCHAR2(30) | DDL發生的對象名稱 | ? |
| ora_dict_obj_owner | VARCHAR2(30) | DDL發生對象的宿主 | ? |
| ora_dict_obj_type | VARCHAR2(20) | 對象類別 | ? |
| ora_is_alter_column | BOOLEAN | 當某列被修改的時候返回真,否則返回假 | ? |
| ora_is_drop_column | BOOLEAN | 當某列被刪除的時候返回真,否則返回假 | ? |
| ora_login_user | VARCHAR2(30) | 登錄的用戶名 | ? |
| ora_sysevent | VARCHAR2(20) | 系統事件的名稱 | ? |
| is_servererror(error_num in integer) | BOLEAN | 返回系統是否產生某個錯誤 | ? |
ORACLE 8I開始,提供了一個新的函數“SYS_CONTEXT”。通過使用SYS_CONTEXT函數可以獲得一些和用戶相關的信息,比如:
SELECT sys_context('USERENV','TERMINAL') FROM DUAL;
用戶環境的取值包括:
l?????????TERMINAL:客戶端操作系統終端的名稱????
l?????????LANGUAGE:NLS_LANG的值?
l?????????LANG?:ISO字符集的名稱.?
l?????????SESSIONID:SESSION的ID
l?????????INSTANCE:實例的ID
l?????????ISDBA:是否具有DBA權限
l?????????CLIENT_INFO:64字節的用戶信息,可以用DBMS_APPLICATION_INFO設置的值:
l?????????NLS_TERRITORY?:當前SESSION的?territory
l?????????NLS_CURRENCY:當前SESSION的貨幣符
l?????????NLS_CALENDAR:當前SESSION的歷法
l?????????NLS_DATE_FORMAT:當前SESSION的日期格式
l?????????NLS_DATE_LANGUAGE?:顯示日期的語言
l?????????NLS_SORT:排序方式(BINARY?或者linguistic)
l?????????CURRENT_USER:當前SESSION擁有權限的用戶的名稱(比如說當前SESSION是SYS,但是正在執行system.myproc,那么current_user就是system)
l?????????CURRENT_USERID?:當前SESSION擁有的權限的用戶的ID
l?????????SESSION_USER:session所屬的用戶名
l?????????SESSION_USERID:當前SESSION所屬的用戶id
l?????????CURRENT_SCHEMA:當前SESSION缺省的SCHEMA名稱,可以用SESSION SET CURRENT_SCHEMA?語句修改.?
l?????????CURRENT_SCHEMAID?:當前SESSION缺省的SCHEMA的ID
l?????????PROXY_USER:打開當前SESSION的用戶的名稱
l?????????PROXY_USERID:打開當前SESSION的用戶的ID
l?????????DB_DOMAIN:當前數據庫的DOMAIN
l?????????DB_NAME:當前數據庫的名稱
l?????????HOST:客戶端的主機名稱
l?????????OS_USER:客戶端的操作系統用戶名
l?????????EXTERNAL_NAME:用戶的外部名稱。對于SSL用戶,使用v.503協議,返回的值是證書中的DN
l?????????IP_ADDRESS:客戶端的IP地址
l?????????NETWORK_PROTOCOL:連接串中的PROTOCOL=protocol指明的網絡協議
l?????????BG_JOB_ID?:如果當前的SESSION是由ORACLE后臺進程啟動的,那么返回JOB_ID,否則返回空值
l?????????FG_JOB_ID:如果當前SESSION是由ORACLE客戶端進程啟動的一個JOB,那么返回JOB_ID,否則返回空值?
l?????????AUTHENTICATION_TYPE:返回數據庫鑒權的方法,返回值包括:
l?????????DATABASE:?使用數據庫的用戶名口令
l?????????OS:使用操作系統外部用戶鑒權
l?????????NETWORK:網絡鑒權
l?????????PROXY:OCI的代理連接鑒權?
l?????????AUTHENTICATION_DATA:使用X.503證書鑒權的時候,返回HEX2的證書
?
1.5.1?oracle 8i新增的數據庫事件觸發器
從ORALCE 8i開始,用戶可以通過常見系統級觸發器來追蹤一些系統事件。通過這些觸發器,用戶可以進行一些操作,包括審計、把一些對象PIN入共享池、進行一些維護操作等。以下是一些系統級觸發器的類型:
?
| 觸發器 | 觸發時間 | 觸發條件 |
| Logon | After | 用戶登錄成功后 |
| Logoff | Before | 用戶退出登錄前 |
| Startup | After | 數據庫啟動后 |
| Shutdown | Before | 數據庫關閉前 |
| Servererror | After | 系統發生故障后 |
Logon/Logoff觸發器可以用來記錄用戶等入和退出的時間。數據庫啟動和關閉觸發器可以用來進行一些數據庫啟動后和關閉前的前處理和后處理。比如在數據庫啟動的時候把一些PL/SQL對象固定倒內存中。Servererror觸發器可以用于記錄某些重要的錯誤信息,以便于跟蹤系統,發現故障。在使用系統級觸發器前,首先要確認系統參數_system_trig_enabled是否設置為TRUE。
?
?
1.5.2?DDL觸發器概述
通過DDL觸發器可以記錄特定的DDL操作。DDL觸發器是從ORACLE 8i開始具有的觸發器類型。在ORACLE 9i中,DDL觸發器得到了加強。DDL觸發器的觸發事件���括:
l?????????BEFORE / AFTER ALTER
l?????????BEFORE / AFTER CREATE
l?????????BEFORE / AFTER DROP
l?????????BEFORE / AFTER RENAME
l?????????BEFORE / AFTER ANALYZE
l?????????BEFORE / AFTER ASSOCIATE STATISTICS
l?????????BEFORE / AFTER DISASSOCIATE STATISTICS
l?????????BEFORE / AFTER AUDIT
l?????????BEFORE / AFTER NOAUDIT
l?????????BEFORE / AFTER COMMENT
l?????????BEFORE / AFTER DDL
l?????????BEFORE / AFTER GRANT
l?????????BEFORE / AFTER REVOKE
l?????????BEFORE / AFTER TRUNCATE
l?????????AFTER SUSPEND
要創建DDL觸發器,需要一定的系統權限,這些權限包括:
l?????????create trigger
l?????????create any trigger
l?????????administer database trigger
l?????????alter any trigger
l?????????drop any trigger
DDL觸發器可以用于細化的DDL操作審計。一般的做法是設計一張日志表,當DDL觸發器激活后,通過系統相關的系統事件函數獲取鎖需要的信息,然后把數據插入日志表中。這樣,就可以記錄系統中需要審計的DDL操作。DDL觸發器可以針對Database級或者SCHEMA級���
要注意的是,DDL觸發器僅對以下的對象有效:cluster, function, index, package, procedure, role, sequence,?synonym, table, tablespace, trigger, type, view,?user。
1.5.3?使用系統級觸發器審計用戶登錄情況
????本節的例子介紹了使用系統的LOGON/LOGOFF觸發器來審計用戶登錄的情況。對于需要掌握用戶在線時間的系統中十分有用。首先要創建一張表,該表保存用戶登錄的信息。然后創建三個觸發器,分別對LOGON/LOGOFF和相關的SERVERERROR進行審計。
創建審計記錄表:
CREATE TABLE log_audit (
login_date DATE,
logoff_date date,
username VARCHAR2(20),
user_ip?varchar2(20),
error_code varchar2(15)
);
創建記錄登錄錯誤的觸發器:
CREATE OR REPLACE TRIGGER log_errors AFTER SERVERERROR ON DATABASE
BEGIN
?IF (IS_SERVERERROR (1017)) THEN
?insert into system.log_audit (login_date,error_code) values(sysdate,'ORA-1017');
?END IF;
END;
?
創建登錄審計觸發器:
CREATE OR REPLACE TRIGGER logon_audit AFTER LOGON ON DATABASE
BEGIN
?insert into system.log_audit(login_date,username,user_ip) values(sysdate,user,ora_client_ip_address);
END;
?
創建退出審計觸發器:
CREATE OR REPLACE TRIGGER logoff_audit BEFORE LOGOFF ON DATABASE
BEGIN
?insert into system.log_audit (logoff_date,username,user_ip) values(sysdate,user,ora_client_ip_address);
END;
/
????本例子可以對數據庫的登錄和退出記錄日志。當觸發器發生故障的時候(比如log_audit表所在的表空間滿的時候,會導致用戶登錄失敗。此時,需要使用具有ADMINISTER DATABASE TRIGGER權限的帳號登錄,然后將審計所使用的觸發器disabale,或者修正觸發器的錯誤。因此在使用系統事件觸發器的時候要十分謹慎。
?
1.5.4?使用系統級觸發器禁用DDL語句
對于一個上線運行的系統,使用DDL操作是十分謹慎的。為了防止不必要的誤操作,可以通過DDL觸發器對某些表禁用DDL操作。可以在需要禁止的操作類型上使用raise_application_error函數來禁止操作,比如:
CREATE OR REPLACE TRIGGER DDL_FB before?ALTER OR DROP?OR RENAME
on schema?
BEGIN
?Raise_application_error(-20030,’此系統已經運行,不允許對表進行DDL維護’);
end;
對于設置了這類觸發器的用戶,如果需要修改表結構,那么需要首先把這個觸發器關掉。
1.5.5?使用系統級觸發器審計重要帳號的DDL語句
如果要審計數據庫中的DDL操作,那么可以通過DDL觸發器來實現,本節介紹一個例子,把數據庫中的所有DDL操作都記錄下來。本例子可以在oracle 8i或更高的版本中使用。
第一步,創建表空間和相關的日志表:
create tablespace statlog datafile '/oradata/statlog.dbf' size 200m;
?
create table stat$log_ddl
(
?ddl_date date,
?user_name varchar2(30),
?ip_addr VARCHAR2(30),
obj_name VARCHAR2(50),
?ddl_type????? VARCHAR2(30),
?object_type?? VARCHAR2(18),
?owner???????? VARCHAR2(30),
?SQL_TEXT????? VARCHAR2(1000)
) TABLESPACE STATLOG;
第二步,創建數據庫級的DDL觸發器,把所有的DDL操作都記錄下來
?
CREATE OR REPLACE TRIGGER DDL_audit AFTER CREATE OR ALTER OR DROP OR TRUNCATE OR
GRANT OR REVOKE OR RENAME
on DATABASE?
declare
?ipaddr varchar2(20);
?STEXT VARCHAR2(1000);
BEGIN
?begin
?select sys_context('USERENV', 'IP_ADDRESS') into ipaddr FROM dual;
?exception when others then
?ipaddr:='-';
?end;
?begin
?select SQL_TEXT INTO STEXT FROM v$open_cursor????? WHERE UPPER(sql_text) LIKE 'ALTER%';
?exception when others then
?STEXT:='-';
?end;
?insert into sys.stat$log_DDL values
?(sysdate,
?user,
?nvl (ipaddr,'-'),
?NVL(ora_dict_obj_name,'-'),
?NVL(ORA_SYSEVENT,'-'),
?NVL(ora_dict_obj_type,'-'),
?NVL(ora_dict_obj_owner,'-'),
?STEXT
?);
exception when others then
?null;
end;
/
總結
以上是生活随笔為你收集整理的基于系统级触发器的审计功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux stty
- 下一篇: Oracle 11g 新特性简介