보안의 새로운 기능
- 감사
- 권한 분석
- Data Redaction
- 기타 향상된 보안 기능
- 보안 기능의 조합과 호환
감사
- 법률이나 규제 준수 OR 다른 레벨의 감사 ( DBA )
SGA에서의 변경사항
- Unified Audit
- Queue : 메모리에서 감사 활동을 기록하는 데 사용
- 첫 번째 큐가 다 채워지면 두번재 큐에 적재
- 가득찬 첫 번째 큐는 백그라운드 프로세스인 GEN0이 audsys( Read-only )테이블에 메모리의 기록을 내려쓴다.
- 크기 : 1MB(디폴트) ~ 30MB ( unified_audit_sga_queue_size
Unified Audit 활성화
Relink 순서
- 1. ORACLE_HOME에서 구동되는 모든 오라클 프로세스를 정지한다 ( 리스너와 데이터베이스 )
- 2. uniaud_on 파라미터를 사용해서 오라클 데이터베이스 바이너리 파일을 Relink 한다.
- 3. 오라클 프로세스를 재시작한다.
- 4. "and Unified Auditing" 라는 텍스트가 로그인 배너에 마지막에 표시
[oracle@localhost lib]$ cd $ORACLE_HOME/rdbms/lib
[oracle@localhost lib]$ make -f ins_rdbms.mk uniaud_on ioracle ORACLE_HOME=$ORACLE_HOME ( 몇분 소요 )
톰 카이트의 한 마디
- Audit Trail를 시스템의 로드 상황에 따라서 대략적으로 시간 기반으로 3초마다 내려쓸 수 있다.
- 따라서 SGA상에서 오랜기간 동안 Audit Trail 레코드가 머물러 있지 않아도 된다.
- 큐 사이즈에 상관없이 정기적으로 디스크에 내려쓰는 편이 훨씬 안전하다.
EXEC DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_PROPERTY(
DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
DBMS_AUDIT_MGMT.AUDIT_TRAIL_WRITE_MODE,
DBMS_AUDIT_MGMT.AUDIT_TRAIL_IMMEDIATE_WRITE);
의무의 분리
- Role
- AUDIT_ADMIN : 감사 정책을 관리 및 설정
- AUDIT_VIEWER : 감사 결과만을 검토
- MR_SMITH ( 계정 ) : 감사 관리자
- AUDITMAN ( 계정 ) : 감사 결과 리뷰하는 유저
-- 테이블 생성
CREATE TABLE HR.CC_INFO (
FNAME VARCHAR2( 30 ),
LNAME VARCHAR2( 30 ),
CCNUM VARCHAR2( 30 ),
CCCODE VARCHAR2( 10 ),
ZIP_CODE VARCHAR2( 10 )
) TABLESPACE EXAMPLE;
-- 감사 정책을 만드는 AUDIT_ADMIN 롤을 가진 MR_SMITH를 생성한다.
CREATE USER MR_SMITH IDENTIFIED BY sunglasses
DEFAULT TABLESPACE USERS;
GRANT CONNECT, RESOURCE TO MR_SMITH;
ALTER USER MR_SMITH QUOTA 10M ON USERS;
GRANT AUDIT_ADMIN TO MR_SMITH;
-- BAI를 검토할 수 있는 AUDITMAN 유저를 생성한다.
CREATE USER AUDITMAN IDENTIFIED BY auditme
DEFAULT TABLESPACE USERS;
GRANT CONNET, RESOURCE TO AUDITMAN;
ALTER USER AUDITMAN QUOTA 10M ON USERS;
GRANT AUDIT_VIEWER TO AUDITMAN;
-- MR_SMITH 계정으로 HT.CC_INFO 테이블에 T001 정책을 활성화한다.
CREATE AUDIT POLICY T001 ACTIONS SELECT, INSERT, UPDATE, DELETE ON HR.CC_INFO;
AUDIT POLICY T001;
-- 그리고 감사 레코드를 디스크로 바로 쓸 수 있도록 UAT 설정을 변경한다.
EXEC DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_PROPERTY(
DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
DBMS_AUDIT_MGMT.AUDIT_TRAIL_WRITE_MODE,
DBMS_AUDIT_MGMT.AUDIT_TRAIL_IMMEDIATE_WRITE);
-- DML을 수행하기 전에 다음 쿼리로 정책 활성화 유무를 확인한다.
SELECT * FROM AUDIT_UNIFIED_ENABLED_POLICIES
WHERE POLICY_NAME = 'T001';
-- 쿼리 결과가 다음과 같이 표시되어야 한다.
USER_NAME POLICY_NAME ENABLED_OPT SUC FAI
--------- ----------- ----------- --- ---
ALL USERS T001 BY YES YES
-- HR 계정으로 로그인해서 감사 레코드를 생성하기 위해 다음 DML을 수행한다.
INSERT INTO HR.CC_INFO VALUES( 'TOM', 'LEE', '123456789', '1234', '91729' );
INSERT INTO HR.CC_INFO VALUES( 'CHUCK', 'SMITH', '234567891', '2345', '91730' );
INSERT INTO HR.CC_INFO VALUES( 'DAVID', 'KIM', '345678912', '3456', '91731' );
INSERT INTO HR.CC_INFO VALUES( 'VIK', 'MICHELLE', '456789123', '4567', '91732' );
INSERT INTO HR.CC_INFO VALUES( 'FOCUS', 'VISION', '567891234', '5678', '91733' );
COMMIT;
UPDATE HR.CC_INFO SET ZIP_CODE = '99999'
WHERE ZIP_CODE = '91733';
COMMIT;
DELETE FROM HR.CC_INFO
WHERE ZIP_CODE = '99999';
COMMIT;
-- AUDITMAN 유저가 HR.CC_INFO에 발생한 DML 작업을 확인할 수 있도록 위의 모든 문장을 실행하고
-- AUDITMAN 유저로 HR.CC_INFO에 테이블 생성과 DML 작업을 확인하기 위해 다음 쿼리를 실행한다.
SELECT EVNET_TIMESTAMP,
OBJECT_SCHEMA || '.' || OBJECT_NAME AS 'AUDIT_OBJECT",
SQL_TEXT
FROM UNIFIED_AUDIT_TRAIL
WHERE OBJECT_NAME = 'CC_INFO'
AND OBJECT_SCHEMA = 'HR'
AND OBJECT_SCHEMA IS NOT NULL
ORDER BY EVENT_TIMESTAMP;
-- MR_SMITH 계정으로 정책을 비활성화하고 삭제한다.
NOAUDIT POLICY T001;
DROP AUDIT POLICY T001;
-- 쓰기 정책을 디폴트로 변경한다.
EXEC DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_PROPERTY(
DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
DBMS_AUDIT_MGMT.AUDIT_TRAIL_WRITE_MODE,
DBMS_AUDIT_MGMT.AUDIT_TRAIL_QUEUED_WRITE);
- FGA : Fine Grained Auditing
- 데이터 펌프 익스포트 / 임포트
- RMAN 작업
- OLS
- DATABASE VAULT
- RAS
권한 분석 ( PA )
- 유저나 롤에 과도한 권한이 부여되어 있는지를 확인하는 데 사용
권한 분석 개요
- 오라클 12c에서 PA 프로세스는 다음의 과정으로 이루어져 있다.
- 1. 분석 캡쳐 프로세스( ACP )를 생성한다. 다음 4가지 옵션 중 하나를 선택할 수 있다.
전체 데이터베이스 캡쳐, 롤 캡처, 컨텍스트 캡쳐, 롤과 컨텍스트 조합 캡처 - 2. ACP 활성화
- 3. 일정 기긴 동안 ACP가 권한 사용 현황을 기록할 때까지 기다린다.
- 4. ACP 비활성화
- 5. ACP의 결과 생성
- 6. ACP의 결과를 분석
권한 분석 예제
-- 테이터베이스 차원의 분석 캡쳐를 수행
BEGIN DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE(
NAME => 'PRIV_ANALYSIS_DB',
DESCRIPTION => 'ANALYZE ALL PRIVILEGES IN DB',
TYPE => DBMS_PRIVILEGE_CAPTURE.G_DATABASE);
END;
/
-- 롤에 의한 캡처를 수행하려는 경우는 다음 문장을 수행
BEGIN DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE(
NAME => 'PRIV_ANALYSIS_DB',
DESCRIPTION => 'RECORD PRIVILEGES USE BY PUBLIC',
TYPE => DBMS_PRIVILEGE_CAPTURE.G_ROLE,
ROLES => ROLE_NAME_LIST( 'RESOURCE'));
END;
/
-- 롤과 CONTEXT 조합으로 분석 캡처를 하려면 다음을 수행한다.
BEGIN DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE(
NAME => 'PRIV_ANALYSIS_HR_USER_RESOURCE',
DESCRIPTION => 'RECORD PRIVILEGE USE BY HR USER WITH RESOURCE',
ROLES => ROLE_NAME_LIST( 'RESOURCE' );
CONDITION => 'SYS_CONTEXT( ''USERENV'', ''SESSION_USER'' ) = ''HR''');
END;
/
-- 롤과 CONTEXT 조합으로 분석 캡처를 하려면 다음을 수행한다.
BEGIN DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE(
NAME => 'PRIV_ANALYSIS_HR_USER_RESOURCE',
DESCRIPTION => 'RECORD PRIVILEGE USE BY HR USER WITH RESOURCE',
TYPE => DBMS_PRIVILEGE_CAPTURE.G_ROLE_AND_CONTEXT,
ROLES => ROLE_NAME_LIST( 'RESOURCE' );
CONDITION => 'SYS_CONTEXT( ''USERENV'', ''SESSION_USER'' ) = ''HR''');
END;
/
-- HR 유저에 대해서만 분석 캡처생성한다.
BEGIN DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE(
NAME => 'PRIV_ANALYSIS_HR_USER',
DESCRIPTION => 'RECORD PRIVILEGE USE BY HR USER',
TYPE => DBMS_PRIVILEGE_CAPTURE.G_CONTEXT;
CONDITION => 'SYS_CONTEXT( ''USERENV'', ''SESSION_USER'' ) = ''HR''');
END;
/
EXEC DBMS_PRIVILEGE_CAPTURE.ENABLE_CAPTURE( NAME => 'PRIV_ANALYSIS_HR_USER' );
DROP TABLE HR.CC_INFO PURGE;
-- 테이블 생성
CREATE TABLE HR.CC_INFO (
FNAME VARCHAR2( 30 ),
LNAME VARCHAR2( 30 ),
CCNUM VARCHAR2( 30 ),
CCCODE VARCHAR2( 10 ),
ZIP_CODE VARCHAR2( 10 )
) TABLESPACE EXAMPLE;
INSERT INTO HR.CC_INFO VALUES( 'TOM', 'LEE', '123456789', '1234', '91729' );
INSERT INTO HR.CC_INFO VALUES( 'CHUCK', 'SMITH', '234567891', '2345', '91730' );
INSERT INTO HR.CC_INFO VALUES( 'DAVID', 'KIM', '345678912', '3456', '91731' );
INSERT INTO HR.CC_INFO VALUES( 'VIK', 'MICHELLE', '456789123', '4567', '91732' );
INSERT INTO HR.CC_INFO VALUES( 'FOCUS', 'VISION', '567891234', '5678', '91733' );
COMMIT;
UPDATE HR.CC_INFO SET ZIP_CODE = '99999'
WHERE ZIP_CODE = '91733';
COMMIT;
DELETE FROM HR.CC_INFO
WHERE ZIP_CODE = '99999';
COMMIT;
EXEC DBMS_PRIVILEGE_CAPTURE.DISABLE_CAPTURE( NAME => 'PRIV_ANALYSIS_HR_USER' );
EXEC DBMS_PRIVILEGE_CAPTURE.GENERATE_CAPTURE( NAME => 'PRIV_ANALYSIS_HR_USER' );
표 9.1 Previlege Analysis에 관련된 View
- DBA_USED_SYSPRIVS : system privilege가 사용되었는지 분석
- DBA_USED_OBJPRIVS : object privilege가 사용되었는지 분석
- DBA_USED_PRIVS : system과 object privilege가 사용되었는지 분석
- DBA_USED_OBJPRIVS_PATH : 어떻게 Privilege가 부여되었는지 분석
- DBA_UNUSED_PRIVS : system과 object privilege가 사용되지 않앗는지 여부 분석
-- System Previlege가 사용되는지 분석
SELECT USERNAME, USED_ROLE, SYS_PRIV
FROM DBA_USED_SYSPRIVS
WHERE USERNAME = 'HR';
-- Object Privilege가 사용되는지 분석
SELECT USERNAME, OBJECT_OWNER,
OBJECT_NAME, OBJECT_TYPE, OBJ_PRIV
FROM DBA_USED_OBJPRIVS
WHERE USERNAME = 'HR';
-- System과 Object Privilege가 사용되었는지 분석
SELECT USERNAME, SYS_PRIV, OBJ_PRIV,
OBJECT_OWNER, OBJECT_NAME
FROM DBA_USED_PRIVS
WHERE USERNAME = 'HR';
-- 어떻게 Previlege가 획득되었는지 분석
SELECT USERNAME, OBJ_PRIV,
OBJECT_NAME, PATH
FROM DBA_USED_OBJPRIVS_PATH
WHERE USERNAME = 'HR';
-- system과 Object Previlege가 사용되지 않았는지 분석
SELECT USERNAME, SYS_PRIV, OBJ_PRIV,
OBJECT_OWNER, OBJECT_NAME
FROM DBA_UNUSED_PRIVS
WHERE USERNAME = 'HR';
-- 캡처 삭제
EXEC DBMS_PRIVILEGE_CAPTURE.DROP_CAPTURE( NAME => 'PRIV_ANALYSIS_HR_USER' );
Data Redaction
- Data Masking : 실제 데이터 가공
- Data Redaction : 데이터 자체는 변경시키지 않고 단지 보여주는 데이타만 가공한다.
- 11.2.0.4 에서도 사용할 수 있다
- Oracle Redaction : Oracle Advanced Security
Data Redaction 시나리오
-- 적용 전
EMPLOYEE_ID FIRST_NAME LAST_NAME SALARY EMAIL PHONE_NUMBER
----------- ---------- --------- ------ --------- ------------
205 Shelly Higgins 12008 SHIGGINS 515.123.8080
206 William Gletz 8300 WGIETZ 515.123.8181
-- 적용 후
EMPLOYEE_ID FIRST_NAME LAST_NAME SALARY EMAIL PHONE_NUMBER
----------- ---------- --------- ------ --------- ------------
205 Shelly H****** 0 ,T"/& ***.***.***
206 William G**** 0 lii4rw>N ***.***.***
CREATE TABLE HR.RDTEST1 AS SELECT * FROM HR.EMPLOYEES;
-- CLERK 롤
CREATE ROLE CLERK;
GRANT CLERK TO SCOTT;
GRANT SELECT ON HR.RDTEST1 TO SCOTT;
Redaction Policy 생성
BEGIN DBMS_REDACT.ADD_POLICY(
OBJECT_SCHEMA => 'HR'
OBJECT_NAME => 'RDTEST1'
COLUMN_NAME => 'SALARY'
POLICY_NAME => 'REDACT_RDTEST1'
POLICY_DESCRIPTION => 'REDACT_RDTEST1 PII'
FUNCTION_TYPE => DBMS_REDACT.FULL,
EXPRESSION => 'SYS_CONTEXT(''SYS_SESSION_ROLES'',''CLERK'' ) = ''FALSE''');
END;
/
SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, SALARY, EMAIL, PHONE_NUMBER
FROM HR.RDTEST1
WHERE EMPLOYEE_ID IN ( 205, 206 );
-- SALARY 적용
EMPLOYEE_ID FIRST_NAME LAST_NAME SALARY EMAIL PHONE_NUMBER
----------- ---------- --------- ------ --------- ------------
205 Shelly Higgins 0 SHIGGINS 515.123.8080
206 William Gletz 0 WGIETZ 515.123.8181
BEGIN DBMS_REDACT.ALTER_POLICY(
OBJECT_SCHEMA => 'HR',
OBJECT_NAME => 'RDTEST1',
COLUMN_NAME => 'LAST_NAME',
POLICY_NAME => 'REDACT_RDTEST1',
POLICY_DESCRIPTION => 'REDACT_RDTEST1 PII',
ACTION => DBMS_REDACT.ADD_COLUMN, -- 추가
FUNCTION_TYPE => DBMS_REDACT.PARTIAL,
FUNCTION_PARAMETERS => 'VVVVVVVVVVVVVVVVVV,VVVVVVVVVVVVVVVVVV,*,2,25',
EXPRESSION => 'SYS_CONTEXT(''SYS_SESSION_ROLES'',''CLERK'' ) = ''FALSE''');
END;
/
-- LAST_NAME 적용
EMPLOYEE_ID FIRST_NAME LAST_NAME SALARY EMAIL PHONE_NUMBER
----------- ---------- --------- ------ --------- ------------
205 Shelly H****** 0 SHIGGINS 515.123.8080
206 William G**** 0 WGIETZ 515.123.8181
BEGIN DBMS_REDACT.ALTER_POLICY(
OBJECT_SCHEMA => 'HR',
OBJECT_NAME => 'RDTEST1',
COLUMN_NAME => 'EMAIL',
POLICY_NAME => 'REDACT_RDTEST1',
POLICY_DESCRIPTION => 'REDACT_RDTEST1 PII',
ACTION => DBMS_REDACT.ADD_COLUMN,
FUNCTION_TYPE => DBMS_REDACT.PARTIAL,
FUNCTION_PARAMETERS => DBMS_REDACT.RANDOM, --
EXPRESSION => 'SYS_CONTEXT(''SYS_SESSION_ROLES'',''CLERK'' ) = ''FALSE''');
END;
/
-- EMAIL 적용
EMPLOYEE_ID FIRST_NAME LAST_NAME SALARY EMAIL PHONE_NUMBER
----------- ---------- --------- ------ --------- ------------
205 Shelly H****** 0 30fjm2os 515.123.8080
206 William G**** 0 aafaf3-dk 515.123.8181
BEGIN DBMS_REDACT.ALTER_POLICY(
OBJECT_SCHEMA => 'HR',
OBJECT_NAME => 'RDTEST1',
COLUMN_NAME => 'PHONE_NUMBER',
POLICY_NAME => 'REDACT_RDTEST1',
POLICY_DESCRIPTION => 'REDACT_RDTEST1 PII',
ACTION => DBMS_REDACT.ADD_COLUMN,
FUNCTION_TYPE => DBMS_REDACT.REGEXP,
EXPRESSION => 'SYS_CONTEXT(''SYS_SESSION_ROLES'',''CLERK'' ) = ''FALSE''');
REGEXP_PATTERN => ('(\d\d\d).(\d\d\d).(\d\d\d\d)',
REGEXP_REPLACE_STRING => '***.***.****',
REGEXP_POSITION => 1,
REGEXP_OCCURRENCE => 0, REGEXP_MATCH_PARAMETER => 'i' );
END;
/
-- PHONE_NUMBER 적용
EMPLOYEE_ID FIRST_NAME LAST_NAME SALARY EMAIL PHONE_NUMBER
----------- ---------- --------- ------ --------- ------------
205 Shelly H****** 0 30fjm2os ***.***.****
206 William G**** 0 aafaf3-dk ***.***.****
Data Redaction과 뷰
-- Data Redaction 적용된 테이블 : HR.RDTEST1
CREATE OR REPLACE VIEW HR.V1
AS
SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME,
SALARY, EMAIL, PHONE_NUMBER
FROM HR.RDTEST1;
BEGIN DBMS_REDACT.ALTER_POLICY(
OBJECT_SCHEMA => 'HR',
OBJECT_NAME => 'V1',
COLUMN_NAME => 'PHONE_NUMBER',
POLICY_NAME => 'NO_RD_PHONE_NUM',
FUNCTION_TYPE => DBMS_REDACT.NONE,
EXPRESSION => '1=1');
END;
/
-- HR 유저로 다음 쿼리를 수행해서 Data Redaction이 취소된 것을 확인한다.
EMPLOYEE_ID FIRST_NAME LAST_NAME SALARY EMAIL PHONE_NUMBER
----------- ---------- --------- ------ --------- ------------
205 Shelly H****** 0 30fjm2os 515.123.8080
206 William G**** 0 aafaf3-dk 515.123.8181
- CTAS 로 Redaction된 컬럼을 가진 테이블을 복제한다면 Redaction 속성은 상속받지 않지만 편집된 데이터로 해당 컬럼 값이 생성된다. ( == insert select )
기타 향상된 보안 기능