'[오라클 11g] 보안'에 해당되는 글 1건

  1. 2009.06.27 [오라클 11g] 보안
02.Oracle/DataBase2009. 6. 27. 10:51
반응형
출처: http://www.dbguide.net/oracle11g_guide/oracle11g_guide_10.jsp

간략한 개요

Oracle Database 11g는 패스워드 대소문자 구분, Transparent Tablespace Encryption, UTL_TCP/HTTP/SMTP를 위한 액세스 컨트롤 리스트 등 다양한 보안 관련 신기능을 제공합니다.

디폴트 패스워드

2006년에 게시된 OTN 아티클 "프로젝트 락다운: 데이터베이스 인프라스트럭처의 보안을 위한 단계별 접근법(한글)"에서, 필자는 디폴트 패스워드의 사용, 데이터베이스 스캔과 같은 보안 문제를 해결하기 위한 방안을 설명한 바 있습니다.


이제 이 아티클 내용의 일부는 이제 더 이상 참고할 필요가 없게 되었습니다. Oracle Database 11g는 DBA_USERS_WITH_DEFPWD 데이터 딕셔너리 뷰를 조회하는 기막힐 정도로 간단한 방법으로 디폴트 패스워드를 사용 중인 사용자들을 신속하게 확인할 수 있는 기능을 제공합니다. (DBA_는 표준 접두어로, 이 뷰가 DBA 사용자들의 정보만을 포함하고 있음을 의미하는 것은 아닙니다.) 디폴트 패스워드를 사용 중인 사용자 목록을 확인하는 방법이 아래와 같습니다:


select *
from dba_users_with_defpwd


실행 결과는 아래와 같습니다:


USERNAME
------------------------------
DIP
MDSYS
WK_TEST
CTXSYS
OLAPSYS
OUTLN
EXFSYS
SCOTT
MDDATA
ORDPLUGINS
ORDSYS
XDB
LBACSYS
SI_INFORMTN_SCHEMA
WMSYS


위에서 디폴트 패스워드인 TIGER가 사용되고 있는 SCOTT 사용자를 확인할 수 있습니다. 아래와 같이 변경해 줍니다:


SQL> alter user scott identified by tiger1;
User altered.


이제 다시 뷰를 확인해 보면


SQL> select * from dba_users_with_defpwd;


SCOTT가 리스트에서 사라진 것을 확인할 수 있습니다. 아주 간단합니다!


패스워드의 대소문자 구분

Oracle Database 11g 이전 버전에서는 사용자 패스워드의 대소문자 구분은 지원되지 않았습니다. 예를 들자면 아래와 같습니다:


SQL> conn scott/tiger
Connected.
SQL> conn scott/TIGER
Connected.


하지만 이는 패스워드의 대소문자 구분을 요구하는 PCI(Payment Card Industry) 데이터 보안 표준과 같은 업계 표준에 위배되는 것이어서 많은 문제의 소지가 있었습니다.


Oracle Database 11g는 패스워드의 대소문자 구분을 지원합니다. DBCA를 통해 데이터베이스를 생성하는 과정에서, 오라클 데이터베이스는 "새로운 보안 표준"으로 업그레이드할 것인지의 여부를 묻습니다. 이 보안 표준에는 패스워드의 대소문자 구분이 포함되어 있습니다. 업그레이드를 승인하면, 패스워드는 최초 생성된 것과 동일한 대/소문자 단위로 저장됩니다. 새로운 보안 표준을 승인한 경우 아래와 같은 실행 결과를 확인할 수 있습니다:


SQL> conn scott/tiger
Connected.
SQL> conn scott/TIGER
ERROR:
ORA-01017: invalid username/password; logon denied

Warning: You are no longer connected to ORACLE.


"tiger"와 "TIGER"가 다르게 취급되는 것을 확인할 수 있습니다.


하지만 애플리케이션 중 일부는 패스워드를 전달할 때 올바른 대소문자 구분을 사용하지 않고 있을 수 있습니다. 대표적인 예가 사용자 입력 폼입니다. 사용자 입력 폼에서 패스워드를 입력 받으면서 대소문자 변환을 전혀 수행하지 않는 경우가 많습니다. Oracle Database 11g에서 대소문자를 구분한 포맷으로 사용자가 패스워드를 입력하거나, 애플리케이션에서 대소문자 변환을 수행하도록 개발자가 바꾸어 주지 않는 이상 로그인이 실패할 가능성이 있습니다.


필요하다면 아래와 같이 SEC_CASE_SENSITIVE_LOGON 시스템 매개변수를 변경하여 대소문자를 구분하지 않는 체제로 변환하는 것도 가능합니다.


SQL> conn / as sysdba
Connected.
SQL> alter system set sec_case_sensitive_logon = false;

System altered.

SQL> conn scott/TIGER
Connected.


기존의 Oracle 10g 데이터베이스를 11g로 업그레이드하는 경우에는 패스워드를 새로운 표준으로 마이그레이션 할 수 있습니다. 패스워드의 상태는 DBA_USERS 뷰의 PASSWORD_VERSIONS 컬럼을 통해 확인할 수 있습니다.



위에서 패스워드 컬럼이 NULL로 설정되어 있음을 확인할 수 있습니다. Oracle Database 10g 또는 그 이전 버전에서는 여기에 해쉬 값이 저장되어 있습니다. 그렇다면 패스워드는 어디로 간 것일까요? 패스워드는 여전히 데이터베이스(USER$ 테이블)에 저장되어 있지만 DBA_USERS 뷰를 통해서는 조회될 수 없습니다. 사용자가 글로벌하게 또는 외부 인증을 통해 생성된 경우, GLOBAL, EXTERNAL과 같이 상태 정보가 나타나지만 패스워드의 해쉬 값은 표시되지 않습니다.


다음으로, Oracle Database 11g에 새로 추가된 PASSWORD_VERSIONS 컬럼에 주목하시기 바랍니다. 이 컬럼은 패스워드의 대소문자 구분 여부를 표시합니다. "10G 11G"의 값은 사용자가 10g에서 생성되어 11g로 마이그레이션 되었거나 11g에서 직접 생성되었음을 의미합니다.


원한다면 패스워드 파일을 생성하는 과정에서 새로운 매개변수인 ignorecase를 입력하여 SYSDBA 패스워드도 대소문자를 구분하도록 강제할 수 있습니다.


$ orapwd file=orapwPRODB3 password=abc123 entries=10 ignorecase=n


위의 예제에서 SYSDBA 패스워드는 abc123이며, ABC123은 허용되지 않습니다.


패스워드의 대소문자 구분은 외부 침입자에 의한 패스워드 해킹을 더욱 어렵게 만듭니다. 또 법규 준수를 보장할 수 있다는 이점도 있습니다. 더욱 중요한 사실은, 데이터베이스 셧다운 과정을 거치지 않고도 패스워드의 대소문자 구분 설정을 다이내믹하게 변경할 수 있다는 사실입니다. 이 기능은 레거시 애플리케이션을 업그레이드하면서 발생할 수 있는 로그인 문제를 해결하는데 큰 도움이 됩니다.


프로파일, 패스워드 검증 함수

오라클 데이터베이스가 제공하는 패스워드 검증 함수에 대해 알고 계십니까? 여러분들 중 상당수가 그 존재조차도 모르고 계시리라 짐작합니다. 이 함수는 데이터베이스 패스워드의 품질을 확인하는 가장 쉽고 빠른 방법을 제공합니다. 예를 들어 패스워드가 일정한 수 이상의 문자로 구성되었는지, 유저네임과 동일하지는 않은지 등을 확인할 수 있습니다. 또 기능이 기본 내장되어 있으므로 활성화 작업만 거치면 함수를 사용할 수 있습니다.


Oracle Database 11g의 패스워드 관리 함수는 한층 개선된 검증 로직을 제공합니다. $ORACLE_HOME/rdbms/admin 디렉토리의 utlpwdmg.sql 패스워드 검증 파일은 verify_fnction_11g라는 새로운 패스워드 함수를 생성합니다. 이 스크립트의 하단에서 아래와 같은 코드를 확인할 수 있습니다:


ALTER PROFILE DEFAULT LIMIT
PASSWORD_LIFE_TIME 180
PASSWORD_GRACE_TIME 7
PASSWORD_REUSE_TIME UNLIMITED
PASSWORD_REUSE_MAX UNLIMITED
FAILED_LOGIN_ATTEMPTS 10
PASSWORD_LOCK_TIME 1
PASSWORD_VERIFY_FUNCTION verify_function_11G;


이 스크립트는 DEFAULT 프로파일에 이 스크립트는 DEFAULT 프로파일에 함수를 연결합니다. DEFAULT는 (별도로 명시되지 않는 이상) 모든 사용자를 위한 디폴트 프로파일로 설정되어 있습니다. 이러한 방법으로 인증 체계에 관련된 법규 준수를 보장할 수 있습니다. 패스워드 검증 함수의 11g 버전을 생성하는 스크립트를 실행하기만 하면, 스크립트가 디폴트 프로파일에 자동으로 연결되고 패스워드 검증 기능이 활성화됩니다.



개선된 감사 기능

감사 문제 역시 관리자들의 골칫거리 중 하나입니다. 오라클 데이터베이스는 사용자 작업의 추적을 위한 강력한 감사 기능을 제공합니다. 하지만 대부분의 사용자들은 I/O 성능 저하를 우려하여 감사 기능을 적용하지 않고 있습니다. 하지만 실제로는 일부 감사 기능은 활성화하더라도 성능 오버헤드를 우려할 필요가 없습니다.


그 한 가지 예가 CREATE SESSION입니다. CREATE SESSION은 세션이 시작될 때, 그리고 종료될 때 한 번씩 기록을 저장합니다. 이 감사 옵션은 I/O에 미치는 영향은 극히 미미하지만 그 혜택은 매우 강력합니다.


Oracle Database 11g에서는 한층 강력한 감사 솔루션의 구현을 가능하게 하는 두 가지 간단한 변경 사항이 적용되었습니다. 먼저, 데이터베이스 매개변수 audit_trail이 디폴트로 NONE이 아닌 DB로 설정되어 있습니다. 따라서 데이터베이스를 재시작하지 않고도 임의의 오브젝트, 구문, 권한에 대한 감사 기능을 활성화하는 것이 가능합니다.


두 번째로 디폴트 설정에서 감사 대상에 포함되는 구문의 종류가 많아졌습니다. 그 목록이 아래와 같습니다.


ALTER SYSTEM
SYSTEM AUDIT
CREATE SESSION
CREATE USER
ALTER USER
DROP USER
ROLE
CREATE ANY TABLE
ALTER ANY TABLE
DROP ANY TABLE
CREATE PUBLIC DATABASE LINK
GRANT ANY ROLE
ALTER DATABASE
CREATE ANY PROCEDURE
ALTER ANY PROCEDURE
DROP ANY PROCEDURE
ALTER PROFILE
DROP PROFILE
GRANT ANY PRIVILEGE
CREATE ANY LIBRARY
EXEMPT ACCESS POLICY
GRANT ANY OBJECT PRIVILEGE
CREATE ANY JOB
CREATE EXTERNAL JOB


위의 작업들을 감사 대상에 포함시키더라도 I/O는 크게 증가하지 않으며, 따라서 성능 오버헤드를 최소화한 상태에서 합리적인 수준의 감사를 수행할 수 있습니다.


이 두 가지 변경 사항 덕분에 별도의 설정 작업을 거치지 않고도 강력한 감사 기능을 활용할 수 있게 되었습니다. 물론 이것은 단순한 데이터베이스 매개변수와 감사 설정에 불과하며, 필요한 경우 쉽게 비활성화할 수 있습니다. 하지만 구문 리스트를 주의 깊게 살펴 본다면, 심지어 개발 데이터베이스에서도 감사가 필요할 수 있음을 깨닫게 될 것입니다. 물론 좀 더 세부적인 튜닝은 필요할 수 있습니다. (예를 들어, 데이터 웨어하우스 환경에서는 사용자들이 많은 수의 임시 테이블을 생성, 삭제하므로 CREATE/DROP TABLE에 대한 감사가 성능 문제를 발생시킬 수 있습니다.)


주의: Oracle Database 11g로 업그레이드한 경우, 위에서 언급된 구문에 대해 감사 기능이 기본적으로 활성화됩니다. 감사 로그는 SYSTEM 테이블스페이스의 AUD$ 테이블에 저장되며 매우 빠른 속도로 차오를 수 있습니다. 이 공간에 대한 감시를 게을리 하지 마십시오.


Transparent Tablespace의 암호화

보안과 관련한 새로운 법규들이 제정되면서, 암호화 기능에 대한 관심이 점점 더 증가하고 있습니다. 데이터에 대한 암호화는 필요합니다. 하지만 정말 중요한 것은 어떻게 암호화할 것인가의 문제입니다.


Oracle Database 10g Release 1 또는 그 이전 버전에서는 DBMS_CRYPTO, DBMS_OBFUSCATION_TOOLKIT 툴킷을 이용하여 암호화 프레임워크를 직접 구현할 수 있었습니다. 하지만 Oracle Database 10g Release 2의 Transparent Data Encryption 기능이 소개되면서 이 프레임워크는 용도폐기 되어 버렸습니다.


Transparent Data Encryption 기능을 이용하면 특정 컬럼을 선택적으로 암호화하는 것이 가능합니다. 하지만 이 기능은 성능과 관련된 문제를 갖고 있습니다. 암호화된 컬럼에는 인덱스 레인지 스캔이 적용될 수 없으므로 성능이 심각하게 저하될 수 있습니다.


Oracle Database 11g의 Transparent Tablespace Encryption 기능이 돋보이는 것은 바로 이러한 이유 때문입니다. 테이블스페이스가 암호화된 것으로 선언되면, 테이블뿐 아니라 테이블스페이스 내의 모든 데이터(Transportable Tablespace, 백업 포함)가 암호화됩니다. 하지만 인덱스 스캐닝 작업은 데이터가 해독된 메모리 공간에서 실행되므로 성능 저하 문제는 발생하지 않습니다.


아직 감이 안 잡히셨습니까? 그 동작 원리에 대해 좀 더 알아 봅시다. 암호화 프로시저는 Transparent Data Encryption의 경우와 동일합니다. 이를 위해 마스터 암호화 키가 저장되는 월렛(wallet)을 생성해야 합니다. Transparent Data Encryption이 셋업 되지 않은 상태라면 월렛과 키를 생성해 주어야 합니다.


먼저, 월렛이 저장될 디렉토리를 생성합니다. 디폴트 디렉토리는 $ORACLE_BASE/admin//wallet입니다. 월렛 서브디렉토리는 디폴트 상태에서는 존재하지 않으므로 별도로 생성해 주어야 합니다. 아래의 예제에서는 /home/oracle/app/admin/PRODB3/wallet을 디렉토리로 선택하였습니다.


다음으로 아래 구문을 실행하여 월렛에 암호화 키를 생성합니다.


alter system set encryption key identified by "abcd1234!";

이 구문은 월렛과 키를 함께 생성해 줍니다. 이제 디렉토리를 조회하면 방금 생성한 월렛 파일(ewallet.p12)을 확인할 수 있습니다.


$ cd /home/oracle/app/admin/PRODB3/wallet
$ ls
ewallet.p12


월렛은 패스워드(abcd1234)를 사용해서만 열 수 있습니다. 이 구문은 월렛을 여는 작업도 함께 수행합니다. 따라서 월렛을 별도로 생성할 필요가 없습니다. 데이터베이스가 기동되고 나면 아래 구문을 실행하여 월렛을 열기만 하면 됩니다:


alter system set wallet open identified by "abcd1234!"


월렛에 관련한 자세한 정보는 다른 오라클 매거진 아티클에서 확인하실 수 있습니다.


이제 테이블스페이스를 생성합니다:


create tablespace secure1
datafile '/home/oracle/oradata/PRODB3/secure1_01.dbf'
size 1M
encryption using 'AES128'
default storage (encrypt)
/


"encryption using ... default storage (encrypt)" 구문은 테이블스페이스를 암호화된 상태로 선언합니다. (참고: 이 테이블스페이스에는 AES 128비트 암호화가 적용되었습니다. 그 밖에도 Triple DES 168-bit key, AES 192-bit key, AES 256-bit key 등의 옵션이 제공됩니다.)


테이블스페이스를 생성한 다음에는 다른 테이블스페이스의 경우와 마찬가지 방법으로 테이블을 생성할 수 있습니다.


create table secure_trans
tablespace secure1
as
select * from trans
where rownum < 201
/

create table secure_res
tablespace secure1
as
select * from res
where rownum < 201
/


위 구문은 암호화된 테이블스페이스 SECURE1에 테이블을 생성하고 있습니다. 비교를 위해 암호화가 적용되지 않은 테이블스페이스 INSECURE1을 생성하고 이 안에 SECURE_TRANS, INSECURE_RES 테이블을 생성합니다. INSECURE_TRANS 테이블과 SECURE_TRANS 테이블은 그 구조가 동일하며 다른 테이블스페이스에 저장되었다는 차이만을 갖습니다. SECURE_RES, INSECURE_RES의 경우도 마찬가지입니다.


이제 데이터파일 검색에 사용할 데이터를 테이블의 텍스트 필드를 업데이트합니다:


update secure_trans set comments = 'Transaction Comments';
update insecure_trans set comments = 'Transaction Comments';
commit;


테이블스페이스를 오프라인/온라인 처리하여 컨텐트가 디스크에 기록되도록 합니다:


alter tablespace secure1 offline;
alter tablespace secure1 online;
alter tablespace insecure1 offline;
alter tablespace insecure1 online;


이제 캐시의 데이터가 디스크에 기록되었습니다. 여기서 검색을 수행하면 어떤 결과를 얻게 될까요?


$ strings insecure1_01.dbf | grep Transaction
Transaction Comments
...


문자열은 데이터파일에 일반 텍스트로 저장되어 있습니다. 이제 같은 작업을 암호화된 SECURE1 테이블스페이스에 반복합니다.

$ strings secure1_01.dbf | grep Transaction
$


데이터파일이 암호화되었기 때문에 아무것도 반환되지 않습니다. 또 컬럼의 값을 일반 텍스트 포맷으로 조회할 수도 없습니다. 여기까지는 좋습니다. 그렇다면 성능은 어떨까요? 아래 쿼리를 실행해서 테스트해 봅시다.


select hotel_id, sum(amt)
from secure_trans t, secure_res r
where t.res_id = r.res_id
group by hotel_id


쿼리를 실행하면서 트레이스를 걸어 보겠습니다. 아래는 트레이스파일에서 발췌한 정보입니다.



Now, run the same test against INSECURE_RES and INSECURE_TEST, which are on a normal (unencrypted) tablespace.



양쪽의 실행 시간이 거의 차이가 없습니다. 암호 해독으로 인한 CPU 사용량도 그리 많지 않습니다. 따라서 테이블스페이스의 암호화로 인한 성능 영향은 거의 없다는 결론을 내릴 수 있습니다.


DBA_TABLESPACES 뷰에 새로 추가된 ENCRYPTED 컬럼은 테이블스페이스의 암호화 정보를 제공합니다. 또 새로운 뷰 V$ENCRYPTED_TABLESPACES를 이용하면 테이블스페이스를 위해 어떤 종류의 암호화 기능이 활성화 되었는지 확인할 수 있습니다.



이 뷰를 V$TABLESPACE 뷰의 TS# 컬럼과 조인하면 전체 그림을 한 눈에 파악할 수 있습니다. V$TABLESPACE 뷰의 구조가 아래와 같습니다:



여기서 ENCRYPT_IN_BACKUP 컬럼은 Transparent Tablespace Encryption과 전혀 무관하다는 점을 참고하시기 바랍니다. 이 컬럼은 Oracle Database 10g Release 2에서 처음 소개된, 백업 과정에서 RMAN이 제공하는 테이블스페이스 암호화 기능과 연관되어 있습니다.


지금까지 확인한 것처럼 Transparent Tablespace Encryption은 꽤 우아한 방법으로 두 가지 문제를 해결해 줍니다. 데이터 관리가 SGA 내부에서 수행되기 때문에 디스크에 저장된 암호화된 데이터는 성능 저하 문제를 동반하지 않습니다.


Data Pump 덤프파일의 암호화

Oracle Database 10g는 데이터 이동을 위한 가장 강력한 툴, Data Pump 제공합니다. Data Pump는 기존에 제공되던 export/import 툴을 대체하는 역할을 합니다. Data Pump는 그 전송 속도가 매우 빠를 뿐 아니라 프로세스의 병렬화, 테이블스페이스의 리매핑과 같은 다양한 신기능을 제공합니다. Oracle Database 11g에서는 ENCRYPTION이라는 새로운 매개변수를 통해 덤프파일의 보안을 한층 강화할 수 있게 되었습니다..


덤프파일은 데이터베이스 외부에 존재하며 데이터베이스의 보안 범위에 포함되지 않습니다. 이 때문에 보안과 관련한 여러 가지 문제들이 발생할 수 있습니다. 보안에 민감한 일부 기업 환경에서는 DBA들이 데이터의 익스포트 작업 이후 써드 파티 유틸리티를 이용하여 덤프파일을 암호화하는 절차를 거칩니다. 하지만 익스포트 데이터의 양이 많다면 무척 번거로운 작업이 될 것입니다.


일반적인 덤프파일이 얼마나 보안에 취약할 수 있는지 한 번 알아 보기로 합시다. 여기 COMMENTS라는 이름의 컬럼을 포함하는 TRANS 테이블이 있습니다. 이 컬럼에는 "Transaction Comments"라는 값이 저장되어 있습니다. 이 테이블을 아래와 같이 일반적인 방법으로 익스포트 했습니다:


$ expdp scott/tiger tables=trans dumpfile=insec.dmp directory=tmp_dir

덤프파일에서 컬럼 값을 조회하면:


$ strings /tmp/insec.dmp | grep Transaction


검색 조건에 매치되는 텍스트가 여럿 발견됩니다. 따라서 덤프파일의 데이터는 암호화되지 않은 일반 텍스트임을 알 수 있습니다.

이제 11g에 새로 추가된 매개변수 ENCRYPTION을 이용하여 익스포트 작업을 수행해 봅시다. 이때 사용할 알고리즘의 타입도 함께 지정해 주어야 합니다. 여기서는 AES 128비트 알고리즘을 사용하기로 하겠습니다.



이 덤프파일에 대해 텍스트 문자열을 검색해 보겠습니다


$ cat /tmp/sec.dmp | grep Transaction
$


덤프파일의 값이 암호화되어 있기 때문에 검색 결과가 전혀 표시되지 않습니다.


여기서 여러분들은 이렇게 질문할지도 모릅니다. "하지만 암호화에는 키가 필요하지 않나요? 앞 과정에서 키를 입력한 적이 없는데요? 키가 없는 상태에서 암호화된 데이터를 해독할 수 있는 건가요?"


해답은 아주 간단합니다. 바로 앞에서 설명한 Transparent Tablespace Encryption의 월렛의 키가 사용됩니다. Data Pump 암호화에서 Transparent Tablespace Encryption 기능을 이용할 필요는 없습니다. 하지만 월렛 생성을 위한 과정은 거쳐야 합니다. 말할 필요도 없는 사실이지만 월렛은 암호화/해독 과정에서 열 수 있어야 합니다.


Data Pump 툴 사용에 익숙한 사용자분들이라면 ENCRYPTION_PASSWORD 매개 변수를 통해 이와 유사한 기능이 제공되었음을 기억하실 것입니다. 그렇다면 과거에 제공되던 기능과 어떻게 다른 것일까요?


네, 좋은 질문입니다. 10g 버전은 전체 덤프파일을 암호화하는 것이 아니라, Transparent Data Encryption의 적용을 받는 컬럼만을 암호화합니다. Transparent Data Encryption을 사용하지 않고 있다면 덤프파일은 전혀 암호화되지 않습니다. 11g 버전에서는 Transparent Data Encryption의 사용 여부에 관계없이 전체 덤프파일을 암호화하는 것이 가능합니다. 이처럼 11g 버전의 암호화 기능이 훨씬 유연하고 실용적임을 알 수 있습니다. 사용자들은 성능과 같은 여러 가지 이유로 데이터베이스에 저장된 데이터를 직접 암호화하는 것을 원하지 않을 수 있습니다. 하지만 데이터베이스의 외부에 저장되는 데이터라면 암호화하는 것이 바람직합니다. 이런 경우에 Data Pump 암호화 기능은 매우 요긴하게 활용될 것입니다.


UTL_TCP/HTTP/SMTP를 위한 액세스 컨트롤 리스트

UTL_TCP, UTL_HTTP, UTL_SMTP 패키지에 대해 이미 알고 계신 분들이 많을 것입니다. 이 패키지들은 데이터베이스 외부의 서버들과의 커뮤니케이션을 위해 사용됩니다. 예를 들어, utl_tcp는 데이터베이스 링크를 통하지 않고 2대의 호스트 간에 TCP/IP 커뮤니케이션을 설정하는데 활용됩니다. 마찬가지로, utl_http는 웹 서버에 대해 http 요청을 생성하는 용도로, utl_smtp는 호스트 간의 SMTP 메일 호출을 위해 사용됩니다.


이 패키지들은 개발자들에 의해 주로 활용됩니다. 예를 들어, utl_smtp는 데이터베이스 내에서 이메일을 전송하는데, utl_http는 PL/SQL 프로그램 내부에서 웹 페이지를 처리하는 데 활용되곤 합니다. 하지만 이러한 툴들은 심각한 보안 리스크를 수반합니다. utl_tcp를 이용하는 데이터베이스에서 사용자는 시스템 프롬프트를 거치지 않고도 데이터베이스의 접근이 허용되는 다른 호스트로 쉽게 접속할 수 있습니다. 이는, 불과 1년 전 오라클 사용자 커뮤니티에 대혼란을 초래한 보이저(Voyager) 웜이 사용한 공격 수법이었습니다.


이러한 리스크를 해결하기 위해, 많은 전문가들은 이 패키지들의 "execute from public" 권한을 삭제할 것을 권고하고 있습니다. 필자 역시 OTN 프로젝트 락다운 시리즈 아티클을 통해 같은 방법을 권장한 바 있습니다. 하지만 개발자들이 이 패키지들을 꼭 실행해야 하는 상황이라면 어떻게 해야 할까요?


Oracle Database 11g는 이를 위한 참신한 해법을 제공합니다. 바로 실행 권한을 모든 사용자에게 허용하되, 호출 가능한 리소스를 통제하는 방법입니다. 예를 들어, utl_tcp 패키지에서 일부 IP 주소만을 호출할 수 있도록 제한할 수 있습니다. 이러한 메커니즘을 액세스 컨트롤 리스트(ACL)라 부릅니다. 사용자는 utl_tcp의 실행 권한을 갖고 있다 하더라도, 호스트가 ACL에 등록된 경우에만 해당 호스트에 연결할 수 있습니다. 따라서 utl_tcp 패키지를 이용한 악성 프로그램의 접근 시도를 원천적으로 차단할 수 있습니다.


그 동작 원리를 살펴 봅시다. 먼저 ACL을 생성합니다:



'CONNECT' 매개변수는 ACL이 CONNECT 역할에 적용됨을 의미합니다. 이곳에서 사용자 또는 역할을 정의할 수 있습니다. ACL은 utlpkg.xml 파일 내에 생성됩니다.


생성 작업을 완료한 후 아래와 같은 방법으로 ACL이 추가되었는지 확인할 수 있습니다:


SELECT any_path
FROM resource_view
WHERE any_path like '/sys/acls/%.xml';


실행 결과가 아래와 같습니다:



출력의 마지막 라인에서 방금 생성된 ACL을 확인할 수 있습니다. 다음으로, 이 ACL에 권한을 추가해 줍니다. 예제에서는 SCOTT 사용자만이 이 ACL을 사용할 수 있도록 제한합니다. 또 시작, 종료일도 정의가 가능합니다.



이 ACL에 관련된 호스트 및 기타 상세 정보를 적용합니다:



위의 코드는 "사용자 SCOTT은 호스트 www.proligence.com에만 접속할 수 있으며 포트 22에서 55 사이만을 사용할 수 있음"을 의미합니다. 이제 테스트해 봅시다:


SQL> grant execute on utl_http to scott
2 /

Grant succeeded.

SQL> conn scott/tiger
Connected.
SQL> select utl_http.request('http://www.proligence.com') from dual;
select utl_http.request('http://www.proligence.com') from dual
*
ERROR at line 1:
ORA-29273: HTTP request failed
ORA-06512: at "SYS.UTL_HTTP", line 1577
ORA-24247: network access denied by access control list (ACL)
ORA-06512: at line 1

Note the error "ORA-24247: network access denied by access control list (ACL)." The user called the http server on port 80, which is outside the allowed range 22-55. Therefore the action was prevented.


문제를 해결하기 위해 새로운 룰을 추가해 봅시다:


1 begin
2 dbms_network_acl_admin.assign_acl (
3 acl => 'utlpkg.xml',
4 host => 'www.proligence.com',
5 lower_port => 1,
6 upper_port => 10000);
7* end;
8 /

PL/SQL procedure successfully completed.

SQL> conn scott/tiger
Connected.
SQL> select utl_http.request('http://www.proligence.com') from dual;

UTL_HTTP.REQUEST('HTTP://WWW.PROLIGENCE.COM')
--------------------------------------------------------------------------------
</iframe><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">


<HTML><HEAD><TITLE>Proligence Home</TITLE>
<META http-equiv=Content-Language content=en-us>
...


위 룰은 www.proligence.com 호스트에 대해서만 접근 허용됩니다. 다른 웹 사이트를 호출하면 ORA-24247 에러와 함께 실패할 것입니다. 이는 매우 세분화된 보안 정책이 적용된 것으로 볼 수 있습니다. 호스트 www.proligence.com에 접속해야 할 비즈니스 상의 이유가 있다면, 이 호스트만 허용하고 다른 호스트에 대한 접근은 차단함으로써 악성 사용자의 접근 시도를 통제할 수 있습니다.


ACL의 상세 정보를 확인하려면 DBA_NETWORK_ACLS 뷰를 조회합니다:



필자의 의견으로는 이 기능이야 말로 Oracle Database 11g에서 최고로 손꼽을 만한 보안 기능이 아닐까 합니다.


데이터 마스킹

많은 기업들이 수시로 운영 데이터베이스의 이미지를 스테이징 또는 QA 데이터베이스에 업데이트함으로써, 개발자들이 운영 시스템과 유사한 환경에서 개발된 코드를 테스트하도록 하고 있습니다. 하지만 이러한 절차에는 잠재적인 보안 문제가 수반됩니다. 운영 데이터베이스의 내용이 QA 데이터베이스와 동기화될 때 민감한 개인 정보가 유출될 수 있기 때문입니다. 이러한 리스크를 해결하기 위해, 많은 기업들이 중요한 데이터들을 의미 없는 값으로 대체하는 방법을 사용하고 있습니다. 이러한 방법을 데이터 마스킹(data masking)이라 부릅니다. 예를 들어, 실제 사회보장번호를 입력하는 대신 9개의 무작위 숫자로 업데이트하는 방법이 사용됩니다.


하지만 실제로 변경하는 작업은 매우 까다로울 수 있습니다. SQL 스크립트를 직접 작성하고, 프로세스에 문제가 없는 지, 운영 시스템에 부담이 되지 않을지 등을 점검해야 합니다. 그렇다면 오라클 데이터베이스가 직접 데이터 임포트 작업을 관리할 수 있다면 좋지 않을까요? Oracle Database 11g에는 Data Pump의 임포트 과정에서 데이터 변경을 지원하기 위한 remap_data 매개변수가 새로 추가되었습니다.


이를 위해 먼저, 리매핑 함수를 생성합니다:



이 함수는 varchar 변수를 취한 후 9개의 문자를 반환합니다. 이 함수를 이용하여 SSN의 마스킹을 수행하도록 하겠습니다. ACCOUNTS 테이블은 다음과 같이 정의되어 있습니다.



계좌 소유자의 SSN 정보를 저장한 ACC_SSN 컬럼의 마스킹을 수행하고 합니다. 이제 Data Pump를 이용하여 테이블을 익스포트 합니다. 익스포트 과정에서 새로운 매개변수, remap_data를 이용하여 익스포트 덤프 파일의 데이터를 마스킹 처리합니다.

$ expdp scott/tiger tables=scott.accounts dumpfile=
accounts.dmp directory=tmp_dirremap_data=accounts.acc_ssn:pkg_mask.fn_mask_ssn

이 매개변수는 pkg_mask 패키지의 fn_mask_ssn 리매핑 함수로부터 생성된 값을 이용합니다. 매개변수의 포맷에 주의하시기 바랍니다. 매개변수는 다음과 같은 패턴을 갖습니다:


[.].:[.].


은 마스크 대상 컬럼의 이름입니다. 실제 리매핑 로직은 .에 위치하고 있습니다.



이제 개발 데이터베이스로 테이블을 임포트할 수 있습니다. 임포트 작업이 완료된 후 테이블의 데이터를 점검한 결과가 아래와 같습니다:

ACC_SSN 값이 달라져 있음을 확인할 수 있습니다. 이 값들은 앞에서 작성한 pkg_mask.fn_mask_ssn 리매핑 함수로부터 생성되어, 임포트 과정에서 함께 임포트된 것입니다.


remap_data 매개변수를 사용하지 않고 이미 테이블을 익스포트 처리했다면, 덤프파일에는 실제 값이 저장되어 있을 것입니다. 이런 경우에도 같은 매개변수를 사용하여 임포트 과정에서 마스킹을 수행할 수 있습니다.


$ impdp scott/tiger dumpfile=accounts.dmp remap_data=
accounts.acc_ssn:pkg_mask.fn_mask_ssn directory=tmp_dir tables=accounts

여기서는 randomizer 함수가 사용되고 있으며, 그 밖의 어떤 로직을 사용하더라도 무방합니다. 예를 들어, SSN의 마지막 4개 숫자를 X로 변환하는 방법도 가능합니다. 이를 위해 사용되는 함수는 아래와 같이 구현됩니다:



이 패키지 함수는 나중에 어떤 컬럼에서든 재활용이 가능하다는 이점이 있습니다.


기타 보안 기능

이전 버전에서는 대부분의 보안 작업이 Oracle Security Manage라는 툴을 통해 수행되었습니다. Oracle Database 11g의 Oracle Enterprise Manager는 이러한 작업을 수행하는데 필요한 모든 툴들을 제공하고 있습니다. OEM의 Database 홈페이지에 위치한 Server 탭의 스크린샷이 아래와 같습니다. 오른쪽 하단에 Security라는 이름의 섹션이 위치한 것을 확인하실 수 있습니다.



이 섹션은 사용자, 프로파일, 역할 관리 등의 프로세스에 관련한 전체 보안 관련 도구의 하이퍼링크를 제공하고 있습니다. 그 밖에도 Virtual Private Database, Oracle Label Security 등을 위한 마법사를 이용하거나 Enterprise Manager 스크린으로부터 애플리케이션 컨텍스트를 생성, 관리할 수 있습니다. "Oracle Database 11g: DBA와 개발자가 알고 있어야 하는 새로운 기능" 홈페이지로 돌아가기 

[출처] [오라클 11g] 보안|작성자 형기

Posted by 1010