#title 감사기능(Auditing) [[TableOfContents]] ==== 개요 ==== 데이타베이스가 좀 크다 싶으면 관리자는 주기적인 모니터링이 필요합니다. 이러한 데이타베이스 관리 시스템에서 일어난 동작들을 모니터링하는 짓을 Auditing이라고 합니다. 감사의 종류는 문장감사, 권한 감사, 객체 감사 이렇게 3가지로 구분합니다. 이렇게 야그하면 먼지 감은 잡히는데 어케해야하는지 도저히 모르겠습니다. 하시는 분도 계실겁니다. 데이타베이스 시스템은 항상 변하고 있는데 모니터링해도 어디엔가 기록이 남아야 분석을 할 수 있을겁니다. 오라클은 그짓을 Audit Trail에 저장하게 됩니다. 중요한것은 감사의 방법이 아니라 감사의 목적에 맞는 제대로된 감사를 하는 것입니다. 의심스러운 사용자의 액션을 추적하고, 감사 추적 데이타를 보호해야 합니다. 무작정 감사 추적만 한다고 되는 것은 아니지여. 물론 데이타에 대한 감사는 트리거로 하고 또한 필요한 조치를 취하게 됩니다. 감사도 역시 활성화/비활성화 됩니다. 무작정 감사를 한다면 시스템에 또다른 오버헤드로 작용하겠지여. 그러나 무작정 하는 감사도 있습니다. 그 무작정 감사는 오라클 인스턴스의 startup/shutdown, 데이타베이스 관리자 권한을 가진 사용자가 접속할때 입니다. 오라클은 파라미터 파일에 AUDIT_TRAIL 값을 명시함으로써 감사를 활성화 시킬수 있습니다. AUDIT_TRAIL = [DB | OS | NONE] 3가지 값이 들어갈수가 있습니다. NONE은 파라미터의 기본값이구여...DB 파라미터값으로 설정하면 감사 추적데이타는 sys.AUD$ 데이타 사전뷰를 통해 볼수가 있습니다. OS 파라미터값으로 설정하면 추적 파일이 운영체제상에 저장됩니다. 역시 해당세션에서도 감사의 활성화/비활성화가 가능합니다. 파라미터 파일에 감사의 활성화라는 명시가 있을 때만입니다. 세션이 끝나면 감사도 끝이라는 뜻이지여. AUDIT 와 NOAUDIT 문으로 활성화/비활성화 시킵니다. 이 문장을 수행하려면 AUDIT SYSTEM 권한이 있어야 하구여. 일단 감사를 하려면 관리자를 위한 스크립트하나를 실행해야 합니다. 즉, 감사를 위한 테이블과 뷰를 생성하는 것이지여. 이것은 $ORACLE_HOME/rdbms/admin/cataudit.sql 을 실행하면 됩니다. 감사가 끝난후 필요치 않은 테이블과 뷰의 삭제는 $ORACLE_HOME/rdbms/admin/catnoaud.sql을 실행하면 됩니다. 감사를 일단 시작하게 되면 감사의 범위를 결정한 후에 감사를 시작해야 겠지여. 너무 많은 내용의 감사 정보가 저장된다면 이거또한 분석하기 힘들어 질겁니다. 그러니 범위의 결정도 매우 중요한 사항입니다. 범위는 SQL 실행의 성공여부에 따라서 또는 세션당 또는 데이타베이스의 접근에 대한 감사등으로 구분지어 감사하고자 하는 범위를 좁혀야 합니다. 그럼 앞에서 야그한 감사의 종류 3가지에 대한 것을 각각 해보겠습니다. ==== 문장 감사 ==== 문장감사는 SQL문에 대한 감사입니다. 모든 문장이 감사가 가능하지만 원격 데이타베이스에서 이루어지는 데이타베이스의 액션은 감사의 대상에서 제외입니다. 문장감사의 문법은 다음과 같습니다. AUDIT statement_option [BY user] [BY [SESSION | ACCESS]] [WHENEVER [NOT] SUCCESSFUL] BY SESSION 옵션으로 감사를 수행할때는 세션별 감사이므로 DML 문장이 실행될 경우에만 해당하고, BY ACCESS 옵션으로 감사를 수행할 때는 SQL문이 행해지는 객체별로 감사를 하게 됩니다. WHENEVER [NOT] SUCCESSFUL는 문장의 성공/실패에 따라서 감사의 여부를 결정할 수 있습니다. 확인은 DBA_STMT_ADUIT_OPTS ==== 권한감사 ==== 권한 감사는 오라클의 모든 권한에 대해서 감사를 하게 됩니다. 상당히 많은 부분입니다. 아까도 야그했듯이 감사에서 중요한 방법은 범위를 최대한 축소시키는 것입니다. 문법은 문장감사와 비슷합니다. AUDIT system_privileges [BY user] [BY [SESSION | ACCESS]] [WHENEVER [NOT] SUCCESSFUL] system_privileges에 ALL PRIVILEGE를 지정하면 모든 권한에 대한 감사를 실시합니다. 실행된 권한 감사의 확인은 DBA_PRIV_AUDIT_OPTS 뷰로 확인합니다. ==== 객체 감사 ==== 제목 그대로 객체에 대한 감사입니다. 즉, 객체 감사는 DML 문장과 GRANT, REVOKE에 대한 감사입니다. 따라서 객체 감사는 모든 사용자를 대상으로 결정됩니다. 문법은 다음과 같습니다. AUDIT [object_opt] ON [[schema.]object | DEFAULT] [BY [SESSION | ACCESS]] [WHENEVER [NOT] SUCCESSFUL] 실행된 권한 감사의 확인은 DBA_OBJ_AUDIT_OPTS 뷰로 확인합니다. 실제로 해봅시다. {{{ SQL> connect internal 연결되었습니다. SQL> shutdown 데이터베이스가 닫혔습니다. 데이터베이스가 마운트 해제되었습니다. ORACLE 인스턴스가 종료되었습니다. SQL> !vi $ORACLE_HOME/dbs/initORCL.ora . . . . # estimates for computer memory availability. You should adjust values upward # for modern machines. # ############################################################################### AUDIT_TRAIL =DB <------------- 추가 시켜줍니다... db_name = "ORCL" db_domain = yasicom instance_name = ORCL service_names = ORCL.yasicom . . . . SQL> startup ORACLE 인스턴스가 시작되었습니다. Total System Global Area 87818400 bytes Fixed Size 73888 bytes Variable Size 70795264 bytes Database Buffers 16777216 bytes Redo Buffers 172032 bytes 데이터베이스가 마운트되었습니다. 데이터베이스가 열렸습니다. SQL> @$ORACLE_HOME/rdbms/admin/cataudit.sql . . . . . . SQL> audit create table 2 by scott 3 by access 4 whenever successful; 감사 성공입니다. SQL> connect scott/tiger 연결되었습니다. SQL> drop table test; 테이블이 삭제되었습니다. SQL> create table test ( id number); 테이블이 생성되었습니다. SQL> connect system/manager 연결되었습니다. SQL> connect system/manager 연결되었습니다. SQL> select username, timestamp, action_name 2 from dba_audit_trail; USERNAME TIMESTAM ACTION_NAME ------------------------------ -------- --------------------------- SCOTT 01/12/06 LOGOFF SCOTT 01/12/06 DROP TABLE SCOTT 01/12/06 CREATE TABLE SQL> select username, 2 to_char(timestamp, 'mm-dd-yy hh24:mi:ss') login_time, 3 to_char(logoff_time, 'mm-dd-yy hh24:mi:ss') logoff_time, 4 logoff_lread logical_reads, 5 logoff_pread physical_reads, 6 logoff_lread + logoff_pread total_reads 7 from sys.dba_audit_session; USERNAME LOGIN_TIME LOGOFF_TIME LOGICAL_READS PHYSICAL_READS TOTAL_READS ------------------------------ ----------------- ----------------- ------------- -------------- ----------- SCOTT 12-06-01 20:03:32 12-06-01 20:04:05 660 40 700 SQL> desc sys.aud$ 이름 널? 유형 ----------------------------------------- -------- --------------------------- SESSIONID NOT NULL NUMBER ENTRYID NOT NULL NUMBER STATEMENT NOT NULL NUMBER TIMESTAMP# NOT NULL DATE USERID VARCHAR2(30) USERHOST VARCHAR2(128) TERMINAL VARCHAR2(255) ACTION# NOT NULL NUMBER RETURNCODE NOT NULL NUMBER OBJ$CREATOR VARCHAR2(30) OBJ$NAME VARCHAR2(128) AUTH$PRIVILEGES VARCHAR2(16) AUTH$GRANTEE VARCHAR2(30) NEW$OWNER VARCHAR2(30) NEW$NAME VARCHAR2(128) SES$ACTIONS VARCHAR2(19) SES$TID NUMBER LOGOFF$LREAD NUMBER LOGOFF$PREAD NUMBER LOGOFF$LWRITE NUMBER LOGOFF$DEAD NUMBER LOGOFF$TIME DATE COMMENT$TEXT VARCHAR2(4000) SPARE1 VARCHAR2(255) SPARE2 NUMBER OBJ$LABEL RAW(255) SES$LABEL RAW(255) PRIV$USED NUMBER SQL> noaudit create table 2 by scott 3 by access 4 whenever successful; by access * 3행에 오류: ORA-01718: BY ACCESS | SESSION절은 NOAUDIT에 대해서는 허용되지 않습니다 SQL> noaudit create table 2 by scott; 감사 해제 성공입니다. SQL> audit all privilege <---------------------모든 권한에 대해서 감사를 수행한다. 2 by access; 감사 성공입니다. SQL> connect scott/tiger 연결되었습니다. SQL> create user test_user 2 identified by test_user; identified by test_user * 2행에 오류: ORA-01031: 권한이 불충분합니다 SQL> select username, timestamp, action_name 2 from dba_audit_trail; from dba_audit_trail * 2행에 오류: ORA-00942: 테이블 또는 뷰가 존재하지 않습니다 SQL> connect system/manager 연결되었습니다. SQL> select username, timestamp, action_name 2 from dba_audit_trail; USERNAME TIMESTAM ACTION_NAME ------------------------------ -------- --------------------------- SCOTT 01/12/06 LOGOFF SCOTT 01/12/06 DROP TABLE SCOTT 01/12/06 CREATE TABLE SCOTT 01/12/06 LOGOFF SCOTT 01/12/06 EXECUTE PROCEDURE SCOTT 01/12/06 EXECUTE PROCEDURE SCOTT 01/12/06 CREATE USER SCOTT 01/12/06 SELECT SYSTEM 01/12/06 LOGON SYSTEM 01/12/06 EXECUTE PROCEDURE SYSTEM 01/12/06 EXECUTE PROCEDURE 11 개의 행이 선택되었습니다. SQL> noaudit all privilege; 감사 해제 성공입니다. SQL> audit select, insert, update, delete 2 on scott.dept 3 by access 4 whenever successful; 감사 성공입니다. SQL> select * from scott.dept; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON SQL> select username, timestamp, action_name 2 from dba_audit_trail; USERNAME TIMESTAM ACTION_NAME ------------------------------ -------- ---------------------- SCOTT 01/12/06 LOGOFF SCOTT 01/12/06 DROP TABLE SCOTT 01/12/06 CREATE TABLE SCOTT 01/12/06 LOGOFF SCOTT 01/12/06 EXECUTE PROCEDURE SCOTT 01/12/06 EXECUTE PROCEDURE SCOTT 01/12/06 CREATE USER SCOTT 01/12/06 SELECT SYSTEM 01/12/06 LOGON SYSTEM 01/12/06 EXECUTE PROCEDURE SYSTEM 01/12/06 EXECUTE PROCEDURE SYSTEM 01/12/06 SYSTEM NOAUDIT . . . . . . . . SYSTEM 01/12/06 SYSTEM NOAUDIT SYSTEM 01/12/06 SYSTEM NOAUDIT SYSTEM 01/12/06 SYSTEM NOAUDIT SYSTEM 01/12/06 AUDIT OBJECT SYSTEM 01/12/06 SELECT <-------------기록되었다.. 129 개의 행이 선택되었습니다. SQL> noaudit select, insert, update, delete 2 on scott.dept; 감사 해제 성공입니다. }}} 감사를 추적할때는 꼭 필요할 때만 감사를 실행 해야 합니다. 저는 셀400에 램 128 컴에다가 솔라리스8 버전깔구 오라클8i(8.1.7) 깔아서 그런지 몰라두 그 속도차가 느껴지네여. 헐헐~ 네트웍 환경에서 작업하구 있어서 인지는 몰겠습니다. 암튼 감사의 범위도 줄이고 해서 감사의 실행이 시스템 전체의 성능에 미치는 영향을 최대한 줄여주어야 합니다. 그리고 감사 추적을 위한 공간도 충분히 마련되어야 합니다. 저장공간이 꽉차게 되면 오라클이 감사추적 데이타를 sys.AUD$ 에 입력해야 하는데 입력하지 못해서 에러를 리턴하게 됩니다. 주의하시구여. 감사추적의 관리는 주기적으로 감사 추적 데이타를 제거해야 하는 불편함이 있습니다. 몇가지 방법이 있습니다. 첫번째 방법은 선택적으로 삭제하는 방법, 두번째는 테이블자체를 다른 테이블로 복사해서 옮긴후 감사 추적 데이타를 삭제하는 방법, 세번째는 운영체제 상의 파일로 복사하는 방법입니다. 다음은 그 예입니다. {{{ SQL> create table backup_audit_trail -- 15일이 지난 감사추적 데이타를 복사한다. 2 as 3 select * from sys.AUD$ 4 where timestamp# < sysdate - 15; 테이블이 생성되었습니다. yasicom% exp system/manager tables = sys.AUD$ file = /export/home/oracle/audit_trail_1.dmp -- 필요시 임포트 툴을 써서 임포트 시킨다. Export: Release 8.1.7.0.0 - Production on 목 Dec 6 20:47:01 2001 (c) Copyright 2000 Oracle Corporation. All rights reserved. 접속 대상: Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production With the Partitioning option JServer Release 8.1.7.0.0 - Production KO16KSC5601 문자 설정과 KO16KSC5601 NCHAR 문자 설정에서 엑스포트가 종료되었습니다 지정된 테이블을 엑스포트하려고 합니다 via 규정 경로... 현재 사용자는 SYS로 변경되었습니다 . . 테이블 AUD$(를)을 엑스포트 중 131 행이 엑스포트됨 엑스포트가 경고 없이 정상적으로 종료되었습니다. yasicom% ls -l /export/home/oracle/audit_trail_1.dmp -rw-r--r-- 1 oracle dba 16384 12월 6일 20:47 /export/home/oracle/audit_trail_1.dmp yasicom% yasicom% sqlplus system/manager SQL*Plus: Release 8.1.7.0.0 - Production on 목 Dec 6 20:48:25 2001 (c) Copyright 2000 Oracle Corporation. All rights reserved. Connected to: Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production With the Partitioning option JServer Release 8.1.7.0.0 - Production SQL> truncate table sys.AUD$; 테이블이 잘렸습니다. SQL> select count(*) from sys.AUD$; COUNT(*) ---------- 0 }}} 다음은 감사정보를 조회하는 데이타 사전뷰 입니다. * DBA_PRIV_AUDIT_OPTS * DBA_STMT_AUDIT_OPTS * DBA_OBJ_AUDIT_OPTS * STMT_AUDIT_OPTION_MAP * AUDIT_ACTIONS * ALL_DEF_AUDIT_OPTS * USER_OBJ_AUDIT_OPTS * DBA_AUDIT_TRAIL * USER_AUDIT_TRAIL * DBA_AUDIT_SESSION * USER_AUDIT_SESSION * DBA_AUDIT_STATEMENT * USER_AUDIT_STATEMENT * DBA_AUDIT_OBJECT * USER_AUDIT_OBJECT * DBA_AUDIT_EXISTS