유닉스에서 ORACLE의 자원 활용 상태 점검 방법

유닉스에서 ORACLE의 자원 활용 상태 점검 방법
=============================================

PURPOSE


이 문서의 목적은 DBA로 하여금, 오라클에 의해
사용되는 자원 활용 정도를 전반적으로 살펴보는
방법과, 자원 활용 상태를 점검하는데 사용되는
툴에 대한 설명을 기술하는데 목적이 있다.

Explanation

데이터베이스 성능은 시스템 자원 상태에 의해 제약된다. 때때로,
데이터베이스 상의 성능 문제는, 데이터베이스의 구성이나 물리 구성이
효과적으로 이루어 지지 않아 발생하는 경우가 있으며, 오라클의
트랜잭션이나 사용자나, 프로세스에 의한 비 정상적인 자원 점유에
의해 발생 하기도 한다. 데이터베이스 관리자는 기본적으로, 자원
활용 상태를 점검할 수 있어야 하며, 심각한 문제로 번지기 전에
조치를 취할 수 있어야 한다.

메모리,CPU, I/O는 오라클에서 사용하는 공통된 자원이다. 이 문서에서
위 자원들에 대한 성능 점검을 위해 사용되어 지는 툴과, 사용 방법을
기술한다. 이 자원들에 대한 성능 정보는 오라클 서버 또는 시스템에서
수집할 수 있다. DBA가 필요한 세부 정보는 시스템 관리자나, O/S 공급
업체를 통해 얻을 수 있다.

1. 오라클 인스턴스

오라클 인스턴스는, SGA (System Global Area) 및 백그라운드 프로세스
로 구성되어 있다.
SGA 할당 및 백그라운드 프로세스 기동은, ‘startup nomount’시
이루어 지게되며, 인스턴스의 특성은 다음과 같다.

- 이름은 환경변수 ORACLE_SID 값에 의해 결정된다.
- 각 인스턴스는 각자의 SGA와 백그라운드 프로세스를 사용한다.
- OPS 구성에서는 여러 인스턴스가 동일한 데이터베이스를
액세스 할 수 있다.

동일한 $ORACLE_HOME을 사용하더라도, 여러개의 오라클 인스턴스
구동이 가능하다. 여러 인스턴스를 구동 시키는 것은 디스크나, 메모리,
커널 파라미터와 같은 시스템 자원에 의해 제약을 받을 뿐, 오라클 자체의
제약 사항은 없다.
인스턴스가 구동될 때 마다, 오라클은 init<SID>.ora 파일에 지정된
파라미터에 따라 주요 자원 할당 요청을 O/S에게 한다. 각 오라클
인스턴스는 메모리상의, 공용 SGA (System Global Area) 와, 백그라운드
프로세스를 위한 PGA(Program Global Area)를 사용하게 된다.

2. 시스템 자원

1) 메모리

오라클에서 사용하는 메모리 구조에는 SGA, PGA, UGA 및 sort area가 있다.

A. Shared Memory, Semaphore
오라클에서는, 성능 향상을 위해 공유 메모리 (shared memory)를 사용한다.
O/S에서 동일한 동일한 주소의 페이지를 프로세스에서 참조할 때 마다 매번
메모리에 로스 시키지 않아도 된다. 대신, 프로세스는, 메모리 상에
올라간 데이터에 대한 주소 정보를 가지고, read/write를 수행하게
된다. 따라서, 데이터는 한 프로세스의 주소 공간 (address space) 에서
다른 프로세스의 주소 공간으로 옮겨질 필요가 없다. 데이터에 대한
정합성을 보장하기 위해, 한 시점에서 오직 한개의 프로세스만이
액세스 할 수 있어야 하는데, 이를 위해 세마포어가 사용된다.

세마포어에는 두가지 값만 설정이 가능하다. ( set / unset ) 프로세스가
메모리의 특정 위치를 참조할 때, 프로세스에서는 참조하려는
위치에 세마포어가 할당 되어 있는지여부와, 값이 set 상태인지 여부를
확인한다. 만약 세마포어가 할당되어 있고 값이 set 상태이라면,
해당 위치의 상태가 가용한 상태가 될 때까지 대기한다.

해당 메모리 영역이 액세스 가능하게 되면, 먼저 세마포어의 값을 set
상태로 만들어, 다른 프로세스에서 read/write 작업을 수행하는데
끼어 들지 못하도록 한다.

SGA의 크기는 shared pool, database buffer cache, redo log buffer,
large pool 및 java pool 크기를 더한 값으로 정해진다. 일반적으로
사용되는 SGA 크기 계산 공식은 다음과 같다.

((db_block_buffers * block size) + (shared_pool_size +
large_pool_size + java_pool_size + log_buffers) + 1MB

데이터베이스 성능 최적화를 위해, SGA는 real memory ( 시스템 메모리
에서 virtual memory 영역은 제외 ) 크기 이내로 지정되어야 하며,
real memory 크기를 초과할 경우 swapping이 발생하게 된다. SGA 크기는
OS 커널 파라미터에 의해 제약을 받게 되는데, 유닉스에서는 SHMMAX와
같은 파라미터에 의해 결정된다.

SGA는 연관된 모든 프로세스에서 액세스 가능하므로, 다중 사용자
환경에서, 여러 프로세스가 정보를 공유하기 위해 사용된다.

오라클이 사용하는 shared memoory 세그먼트와, semaphore 관련
커널 파라미터에는 다음과 같은 것들이 있다.

- SEMMNI => Semaphore set / 식별자의 최대 갯수
- SEMMNS => 시스템레벨에서 사용 가능한 semaphore의 최대 갯수
- SHMMNI => 미리 할당 가능한 shared segment의 갯수
- SHMMAX => Shared segment의 최대 크기

도움이 되는 관련 정보는 오라클 설치 가이드에 자세히 나와 았으며,
설치 가이드에 제시된 수치는, semaphore나 shared memory 관련 최소
값이다.

B. Private Memory

PGA는 하나의 서버 프로세스 또는 백그라운드 프로세스의 데이터나
컨트롤 정보를 담는 메모리 공간이다. PGA의 크기는, 데이터베이스
구성 및 프로세스의 역할에 따라 다르다. Dedicated server 구성에서는
하나의 프로세스가, 하나의 사용자 프로세스의 작업을 처리하며, PGA에
UGA의 stack 공간을 포함한다. UGA는 다시, 사용자 세션 데이터 및
커서 상태 정보, sort area 등을 포함한다.
Multithreaded server 구성에서는, 하나의 shared server가 여러개의
사용자 프로세스의 작업을 처리하며, UGA 영역은 shared pool의 일부를
차지하게 된다.

PGA는 다음과 같은 역할을 한다.

- 프로세스가 기록 가능한, 비공유 메모리 영역
- 각각의 서버 프로세스 또는 백그라운드 프로세스별로 PGA가 존재한다.
- 사용자가 연결되면, 사용자는 PGA 공간이 부족하지 않게 할당
된다. 만약 PGA 공간을 할당할 수 없으면, 아예 사용자 연결 자체가
ORA-4030 에러하 함께 실패하게 된다.

PGA 크기와 관련된 오라클 파라미터에는 다음과 같은 것들이 있다.

- open_links
- db_files
- sort_area_retained_size
- sort_area_size

현재 사용중인 PGA 크기를 구하기 위해서는 다음과 같이 한다.

SESSION PGA MEMORY => 세션의 현재 PGA크기와 관련된 통계 정보
SESSION PGA MEMORY MAX => 세션의 PGA 크기의 최대 값 통계 정보

PGA = dedicated server processes - UGA = Client machine process

모든 세션에 대한 PGA 및 UGA 메모리 크기를 조사하기 위해서는,
Bulletin No: 11842 을 참조한다.

참고 : RS/6000 플랫폼에는, 각각의 shadow process는,
PGA를 shared memory segment 영역에 저장한다.

오라클 백그라운드 프로세스를 위한 (DBWR, LGWR 등) PGA 영역 내 stack
공간의 크기는 위에 언급되지 않은 추가 파라미터들에 의해 결정된다.

2) CPU

CPU 사용은, 프로세스의 작업 유형에 따라 다르다. 시스템 상의 부하가
최대일 경우, 데이터베이스 관리자나, 시스템 관리자는 CPU 활용율이
90% 이상을 나타내는 것을 확인하게 된다. 일반적으로 데이터베이스 관리자는
시스템 부하가 일시적으로 집중되는 현상을 피하도록 할 필요가 있다.

3) I/O

I/O의 양 또한 프로세스의 작업 유형에 따라 다르다. 메모리 상의 I/O는
필요한 반면, 디스크 상의 I/O는 가급적 많이 발생하지 않도록 하는 것이
중요하다. 디스크의 I/O 경합을 피하게 하기 위해서는, 파일이 여러
디바이스에 걸쳐 분산되도록 배치할 필요가 있다. 일부 백그라운드 프로세스
는 I/O 작업을 많이 일으키는데, 그와 같은 프로세스에는 DBWn, LGWn, ARCn,
CKPT 프로세스가 있다. 일부 상황에서는 DBA가 여러 개의 DBWn/ARCn 을
구동시키거나, 또는 DBWR/ARC0/LGWR I/O slave를 두는 것이 유리한지
여부를 판단할 필요가 있다.

3. 서버 레벨의 성능 점검

V$로 시작하는 dynamic performance view는, 자원 활용에 대한 통계
정보를 시스템 레벨과, 세션 레벨로 누적 시킨 결과를 보여준다. STATSPACK
과, Utlbstat/Utlestat 리포트는, 일정 주기동안 이와 같은 v$ view 값의
차이를 보여주는 역할을 하며, tkprof 유틸리티는 query 별 통계정보를
보여준다. tkprof을 사용하여 각 query에 대한 통계 정보를 조사하기
위해서는, Init<SID>.ora 파일에 TIMED_STATICS 값이 TRUE로 지정되어
있어야 한다.

각종 v$ view에 대한 설명은 Oracle 7/8/8i Server Referenece Manual에
자세히 기술되어 있다.

STATSPACK 또는 utlbstat/utlestat 리포트를 분석하는 방법에
대해서는, 각각 <Bulletin No: 10441 , 17118 >에 자세히 기술되어 있다.

Tkprof 결과를 해석하는 방법에 대해서는, <Bulletin No: 10134>에 자세히
기술되어 있다.




다음 예는, 오라클에 가용한 다양한 툴을 이용해 얻은 결과의 예를
보여주고 있다.

1) STATSPACK 과 bstat/estat 리포트

Statistic Total Per Transact Per Logon Per Second

-------------
-----------------
CPU used by this session 2278466 222.59 1974.41 203.6
CPU used when call started 2239857 218.82 1940.95 200.15
CR blocks created 2938 .29 2.55 .26
session pga memory 7138227 34521 991 191
session pga memory max 40327524 745091 98305 756
session uga memory 326143 96312 57843 654
session uga memory max 2483564 185735 12386 700

2) tkprof .prf 결과 파일

OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS

call count cpu elapsed disk query current rows


---------
------------
-----------

Parse 3 0.04 0.05 0 0 0 0
Execute 4 0.00 0.05 0 0 0 0
Fetch 2 0.00 0.06 2 17 68 1

---------
------------
-----------

total 9 0.04 0.16 2 17 68 1

3) 스크립트 실행 결과

REM Monitor memory usage
SQL> select sid, name, value
2 from v$statname n, v$sesstat s
3 where n.statistic# = s.statistic#
4 and n.name like '%memory%'
5 order by sid;

SID NAME VALUE


---------------------------------
1 session uga memory 18252
1 session uga memory max 18252
1 session pga memory max 59568
1 sorts (memory) 0
1 session pga memory 59568
. .

REM monitor CPU usage
SQL> select sid, name, value
2 from v$statname n, v$sesstat s
3 where n.statistic# = s.statistic#
4 and n.name like '%cpu%'
5 order by sid;

SID NAME VALUE

------------------------------
1 recursive cpu usage 0
1 parse time cpu 0
1 OS Wait-cpu (latency) time 0
. .

REM monitor I/O
SQL> select file#, phyrds, phywrts
2 from v$filestat;

FILE# PHYRDS PHYWRTS

--------------
1 3239 141
2 80 246
3 9 163
4 6 3
5 5 3
. .

4. O/S 레벨의 성능 점검

1) OS Semaphore

각각의 오라클 인스턴스는 일정 갯수 만큼의 semaphore가 필요하다. 필요한
semaphore의 전체 갯수는, init.ora 파일의 'processes' 파라미터로부터
유도된다. 시스템에 인스턴스 또는 데이터베이스의 갯수를 추가시킬 때마다
O/S 커널 파라미터의 SEMMNS 값이 적절하게 변경되어야 한다.

2) Ulimits

기본적으로 설정하여야 할 커널 파라미터는 설치 가이드에 기술되어 있다.
유닉스 시스템에서 인스턴스나 데이터베이스 갯수를 늘리기 위해서는,
커널 파라미터 값을 적절하게 변경해 주어야 한다.

유닉스 환경에서 오라클 계정의 limit을 확인하기 위해서는 다음과 같이
한다.

% ulimit -Sa

(다음은 결과 예제이다)

time(seconds) unlimited
file(blocks) unlimited
data(kbytes) unlimited
stack(kbytes) unlimited
memory(kbytes) unlimited
coredump(blocks) 2097151
nofiles(descriptors) unlimited

5. 성능 점검에 필요한 툴

성능 점검을 위해 흔히 사용되어지는 툴에는 vmstat, iostat, pstat, size,
ipcs, ps, sar, 그리고 O/S 별로 제공되는 툴이 있다. 각각의 툴에 대한
플랫폼 별 설명은 매뉴얼 페이지를 참조하여야 한다.

다음은 유닉스에서 제공하는 툴을 이용하여 O/S 상태를 점검하는 예이다.

1) 메모리: 메모리 이용 상태를 보기 위해서는 vmstat (virtual memory statistics)
을 사용하며, 이 툴에서는 기본적으로 CPU와 메모리 상황을 보여준다.

OS 명령어
~~~~~~~~~~ ~~~~~~~~~
Sun Solaris: vmstat
HP: vmstat -n
IBM: /bin/vmstat
Compaq: /sbin/hwmgr
Linux: xosview

플랫폼 별로 제공되는 툴과 관련하여 참조 가능한 문서는 다음과 같다.

HPUX GLANCE: <Note:166490.1>

AIX SVMON: <Note:166491.1>

SUN SOLARIS PMAP: <Note:163763.1>

2) I/O: I/O와 관려된 상황은 "sar -d" 또는 "iostat" 등의 툴을 사용하여
정기적으로 점검해 볼 필요가 있다. 평균 서비스 시간이 50ms 이하가 계속
해서 유지되는 상황은 점검 대상이 된다. 이 경우, 디스크 간 부하를 조정
하여 분산시킬 필요가 있다.

디스크 공간 사용과 관련해서는, 다음과 같은 명령을 실행시켜
점검 해 볼 수 있다 : df -k
ORACLE_HOME의 위치와 데이터파일이 존재하는 디스크에 대해 충분한
공간이 있는지를 살펴보아야 한다. 일반적으로, mount 시킨 디스크 별로
90% 이상의 공간을 사용하지 않도록 유지시켜야 한다.

3) CPU:

OS 명령어
~~~~~~~~~~ ~~~~~~~~~
Sun Solaris: sar -u
IBM: ps av (또는) iostat 3 20
Digital: /usr/sbin/pset_info
Linux: xosview

CPU 활용율을 모니터 하는 것 이외에도, 프로세스가 가용한
프로세서에서 실행 가능할 때까지 대기하는지 여부를 살펴보기 위해
runqueue의 길이도 살펴볼 필요가 있다. runqueue의 길이는 "sar -q"
명령을 실행시켜 알 수 있다.

4) CPU가 여러 개인 장비에서, 프로세서별 CPU time을 알아 보기 위해서는
다음과 같은 명령을 수행시킨다.

OS 명령어
~~~~~~~~~~ ~~~~~~~~~
Sun Solaris: /usr/bin/mpstat
HP: /usr/sbin/sar -M 5 5
IBM: vmstat -> cpu 항목에 나와있다. 만약 "us" 값이 매
우 클 경우, 시스템에 CPU intensive한 프로세스가
존재하는 것을 의미한다.

5) 시스템에 설치된 CPU와 각각의 상태를 조사하기 위해서는 다음과
같은 명령을 수행시킨다.

OS 명령어
~~~~~~~~~~ ~~~~~~~~~
Sun Solaris: /usr/sbin/mpstat
HP: /usr/sbin/sar -M 2 2
IBM: /usr/sbin/bindprocessor -q
Digital: /usr/sbin/psrinfo -v
Linux: xosview

6) 시스템의 swap 공간 및 활용 상태를 조사하기 위해서는 다음과
같은 명령을 수행시킨다.

OS 명령어
~~~~~~~~~~ ~~~~~~~~~
Sun Solaris: /etc/swap -l and /etc/swap -s
HP: /etc/swapinfo -m (root 계정에서 실행해야만 함)
IBM: lsps -a
Digital: /usr/sbin/swapon -s
Linux: free -t

7) shaerd memory 및 semaphore와 관련된 정보를 얻기 위해서는 다음과
같은 명령을 수행시킨다.

"ipcs -b"

by Dave Kim | 2010/08/11 17:56 | UNIX / LINUX | 트랙백 | 덧글(0)

DataGuard Raw Device 문제 해결방법

 Using the STANDBY_FILE_MANAGEMENT Parameter with Raw Devices

By setting the STANDBY_FILE_MANAGEMENT parameter to AUTO whenever new datafiles are added or dropped on the primary database, corresponding changes are made in the standby database without manual intervention. This is true as long as the standby database is using a file system. If the standby database is using raw devices for datafiles, then the STANDBY_FILE_MANAGEMENT initialization parameter will continue to work, but manual intervention is needed. This manual intervention involves ensuring the raw devices exist before log apply services on the standby database recover the redo data that will create the new datafile.On the primary database, create a new tablespace where the datafiles reside in a raw device. At the same time, create the same raw device on the standby database. For example:

SQL> CREATE TABLESPACE MTS2 DATAFILE '/dev/raw/raw100' size 1m;
Tablespace created.
SQL> ALTER SYSTEM SWITCH LOGFILE;
System altered.

The standby database automatically adds the datafile as the raw devices exist.
The standby alert log shows the following:

Fri Apr  8 09:49:31 2005
Media Recovery Log /u01/MILLER/flash_recovery_area/MTS_STBY/archivelog/2005_04_08/o1_mf_1_7_15ffgt0z_.arc
Recovery created file /dev/raw/raw100Successfully added datafile 6 to media recovery
Datafile #6: '/dev/raw/raw100'Media Recovery Waiting for thread 1 sequence 8 (in transit)

However, if the raw device was created on the primary system but not on the standby, then the MRP process will shut down due to file-creation errors. For example, issue the following statements on the primary database:

SQL> CREATE TABLESPACE MTS3 DATAFILE '/dev/raw/raw101' size 1m;
Tablespace created.
SQL> ALTER SYSTEM SWITCH LOGFILE;
System altered.

The standby system does not have the /Dave/raw/raw101 raw device created. The standby alert log shows the following messages when recovering the archive:

Fri Apr  8 10:00:22 2005
Media Recovery Log /u01/MILLER/flash_recovery_area/MTS_STBY/archivelog/2005_04_08/o1_mf_1_8_15ffjrov_.arc
File #7 added to control file as 'UNNAMED00007'.Originally created as:'/dev/raw/raw101'
Recovery was unable to create the file as:'/dev/raw/raw101'
MRP0: Background Media Recovery terminated with error 1274
Fri Apr 8 10:00:22 2005Errors in file /u01/MILLER/MTS/dump/mts_mrp0_21851.trc:
ORA-01274: cannot add datafile '/dev/raw/raw101' - file could not be created
ORA-01119: error in creating database file '/dev/raw/raw101'
ORA-27041: unable to open fileLinux Error: 13:
Permission deniedAdditional information: 1
Some recovered datafiles maybe left media fuzzy
Media recovery may continue but open resetlogs may fail
Fri Apr 8 10:00:22 2005Errors in file /u01/MILLER/MTS/dump/mts_mrp0_21851.trc:
ORA-01274: cannot add datafile '/dev/raw/raw101' - file could not be createdORA-01119:
error in creating database file '/dev/raw/raw101'ORA-27041:
unable to open fileLinux Error: 13: Permission deniedAdditional information: 1
Fri Apr 8 10:00:22 2005MTS;
MRP0: Background Media Recovery process shutdownARCH: Connecting to console port...
8.3.1.2.2 Recovering From Errors

To correct the problems described in Section 8.3.1.2.1, perform the following steps:

  1. Create the raw slice on the standby database and assign permissions to the Oracle user.

  2. Query the V$DATAFILE view. For example:

    SQL> SELECT NAME FROM V$DATAFILE;
    NAME
    --------------------------------------------------------------------------------
    /u01/MILLER/MTS/system01.dbf
    /u01/MILLER/MTS/undotbs01.dbf
    /u01/MILLER/MTS/sysaux01.dbf
    /u01/MILLER/MTS/users01.dbf
    /u01/MILLER/MTS/mts.dbf
    /dev/raw/raw100/u01/app/oracle/product/10.1.0/dbs/UNNAMED00007







    SQL> ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=MANUAL;
    SQL> ALTER DATABASE CREATE DATAFILE
    2 '/u01/app/oracle/product/10.1.0/dbs/UNNAMED00007'
    3 AS 4 '/dev/raw/raw101';
  3. In the standby alert log you should see information similar to the following:

    Fri Apr  8 10:09:30 2005
    alter database create datafile'/dev/raw/raw101' as '/dev/raw/raw101'
    Fri Apr 8 10:09:30 2005Completed: alter database create datafile'/dev/raw/raw101' a
  4. On the standby database, set STANDBY_FILE_MANAGEMENT to AUTO and restart Redo Apply:

    SQL> ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO;
    SQL> RECOVER MANAGED STANDBY DATABASE DISCONNECT;

At this point Redo Apply uses the new raw device datafile and recovery continues.

 


by Dave Kim | 2010/08/10 18:09 | DataGuard / EM | 트랙백 | 덧글(0)

데이터베이스 인프라스트럭처의 보안을 위한 단계별 접근법 - PART03 1단계 (작업 기간: 1일)

데이터베이스 인프라스트럭처의 보안을 위한 단계별 접근법 - PART03 1단계 (작업 기간: 1일)

Lockdown

데이터베이스 인프라스트럭처의 보안을 위한 단계별 접근법

 

Arup Nanda
| arup@proligence.com

 

PART 01/개요
PART 02/보안기초
PART 03/1 단계 (작업 기간: 1일)
PART 04/2 단계 (작업 기간: 1주)
PART 05/3 단계 (작업 기간: 1 개월)
PART 06/4 단계 (작업 기간: 1 분기)

프로젝트 Lockdown 아티클 PDF로 다운받기(영문)
여기 처음으로 DBA의 임무를 맡게된 직원이 있습니다. 출근 첫 날, DBA는 사베인즈-옥슬리 법을 기준으로 한 보안 감사가 조만간 시행될 예정이라는 루머를 접합니다. DBA는 환경을 최단 시간 내에 파악하고, 어느 곳을 먼저 살펴보아야 하는지, 즉각적인 조치가 필요로 하는 곳이 어디인지를 살펴 보아야 합니다.

 

 

1 단계 (기간: 1 일)

보안/컴플라이언스 프로젝트의 1 단계에서는, 24시간 이내에 인프라스트럭처 보안 체계를 구현하기 위한 방법을 알아 봅니다.

 

1.1 디폴트 패스워드의 제거

 

배경

오라클 소프트웨어를 설치하고 데이터베이스를 생성하는 과정에서 생성된 계정을 잊고 방치하는 경우가 많습니다. 이러한 계정에는 디폴트 패스워드(예: SCOTT/tiger)가 그대로 사용되므로 침입자들의 진입 경로로 즐겨 활용됩니다. 필자가 진단한 운영 데이터베이스 중에서 SYS 계정의 암호로 “change_on_install” 또는 “oracle”을 그대로 사용하는 경우가 얼마나 많았는지 안다면 놀라실 수 밖에 없을 것입니다. 그러므로 이러한 디폴트 패스워드를 가장 먼저 확인하고 제거해야 합니다.

 

전략

디폴트 패스워드가 설정된 계정을 어떻게 확인할까요? 디폴트 패스워드를 사용해서 각 계정에 로그인을 시도하는 것이 한 가지 방법입니다. 하지만 이것은 매우 번거로운 방법일 뿐 아니라 시간적으로도 낭비입니다.

좀 더 간편한 대안이 있습니다. DBA_USERS 뷰의 패스워드 컬럼을 조회해 봅시다:

 

SQL> select username, password
2 from dba_users
3 where username = 'SCOTT';
USERNAME                                PASSWORD
------------------------------ ------------------
SCOTT                                    F894844C34402B67

 

패스워드가 해쉬 처리 되어 있기 때문에 해독이 불가능하지만, SCOTT의 암호가 “tiger”라는 사실은 알고 있습니다. 따라서 사용자 아이디가 “scott”인 경우 “tiger”의 해쉬값은 F894844C34402B67입니다. SCOTT의 패스워드가 변경되면 해쉬값도 역시 변경됩니다. DBA_USERS 뷰를 통해 SCOTT의 암호가 이 해쉬값과 일치하는지 확인하면 암호가 “tiger”인지 알 수 있습니다. 하지만 패스워드의 문자열 만으로 해쉬값이 결정되는 것은 아니라는 사실을 참고하실 필요가 있습니다. 다른 사용자가 “tiger”라는 암호를 갖는 경우, 그 해쉬값은 달라지게 됩니다.

 

SQL> create user scott2 identified by tiger;
User created.
SQL> select username, password
2 from dba_users
3 where username = 'SCOTT2';
USERNAME                                    PASSWORD
------------------------------ --------------------
SCOTT2                                    C44C11D4C34DB67D

 

위의 예와 같이, 패스워드가 동일함에도 다른 해쉬값( C44C11D4C34DB67D)이 표시되고 있습니다.

그렇다면 이 정보를 어떻게 활용할 수 있을까요? 간단합니다. 디폴트 사용자를 디폴트 패스워드로 설정한 경우, 패스워드의 해쉬 값을 미리 알 수 있습니다. 미리 알고 있는 계정과 디폴트 패스워드의 해쉬값 목록을 테이블 형태로 작성하고 데이터 딕셔너리에 저장된 패스워드 해쉬와 비교하면 됩니다.

1706년 1월, 오라클은 디폴트 패스워드와 사용자를 확인하기 위한 유틸리티를 작성하여 다운로드 형식으로 배포하였습니다. 이 유틸리티는 MetaLink 문서ID 340009에서 확인할 수 있습니다. 유틸리티는 위에서 설명한 것과 유사한 방법으로 몇 가지 디폴트 계정에 대한 점검 작업을 수행합니다. 하지만 여러분이 이 문서를 읽고 있을 즈음에는 더욱 개선된 기능이 제공되고 있을 가능성이 높습니다.

또 보안 전문가 피트 피니건(Pete Finnigan)이 오라클 및 써드 파티 프로그램의 설치 과정에서 생성되는 디폴트 계정의 정보를 수집하여 개인 웹 사이트에 게시하고 있습니다. (법적고지사항: 오라클은 써드 파티 웹 사이트의 컨텐트에 대한 보증을 제공하지 않습니다.) 다른 이들의 수고를 덜어준 피트에게 이 자리를 빌어 감사 드립니다. 하지만 본 문서에서는 피트와는 약간 다른 접근법을 사용하고 있습니다.

먼저, 디폴트 계정과 디폴트 패스워드를 저장할 테이블을 생성합시다.

 

CREATE TABLE osp_accounts
(
product VARCHAR2(30),
security_level NUMBER(1),
username VARCHAR2(30),
password VARCHAR2(30),
hash_value VARCHAR2(30),
commentary VARCHAR2(170)
)

 

다음으로 피트가 수집한 데이터를 테이블에 로드합니다. (스크립트는 이곳에서 다운로드할 수 있습니다.) 테이블이 로드되었다면, 디폴트 패스워드를 검색할 준비를 모두 마친 셈입니다. 간단한 SQL 구문을 사용하여 사용자를 검색해 봅시다.)

 

col password format a20
col account_status format a20
col username format a15
select o.username, o.password, d.account_status
from dba_users d, osp_accounts o
where o.hash_value = d.password
/

USERNAME            PASSWORD          ACCOUNT_STATUS
--------------- -------------------- --------------------
CTXSYS            CHANGE_ON_INSTALL            OPEN
OLAPSYS            MANAGER                      OPEN
DIP                      DIP                       EXPIRED & LOCKED
DMSYS            DMSYS                       OPEN
EXFSYS            EXFSYS                    EXPIRED & LOCKED
SYSTEM            ORACLE                       OPEN
WMSYS            WMSYS                       EXPIRED & LOCKED
XDB            CHANGE_ON_INSTALL            EXPIRED & LOCKED
OUTLN            OUTLN                       OPEN
SCOTT            TIGER                       OPEN
SYS            ORACLE                       OPEN

 

위에서, 가장 우려했던 문제가 발견되었습니다. 마지막 라인에서 SYS의 패스워드가 “ORACLE”로 설정되어 있습니다!
“change_on_install”보다는 낫겠지만, 그래도 쉽게 알아맞힐 수 있는 패스워드임에는 분명합니다.

패스워드와 관련된 보안 취약점은 버전에 따라 달라집니다. Oracle Database 10g와 이후 버전에서는 데이터베이스 설치 과정에서 패스워드를 “change_on_install” 대신 다른 것으로 설정할 것인지 묻는 프롬프트가 뜹니다. 이처럼 사용자에게 선택을 강요하는 환경에서는 패스워드가 디폴트로 설정되지 않았을 가능성이 높습니다. 하지만, 사용자가 “oracle”처럼 뻔한 암호를 선택한다면, 그 취지 또한 무색해집니다. (아마도 “oracle”이라는 암호는 운영 환경으로의 전환이 이루어지기 전에 DBA가 편의상 설정해 둔 것으로 짐작됩니다.)

Oracle Database 10g 이전 버전에서는 패스워드를 입력하는 프롬프트가 표시되지 않으며, 따라서 디폴트 패스워드(예: SYS/“change_on_install”, SYSTEM/”manager”)가 여전히 활성화되어 있을 확률이 큽니다. 이 툴을 이용하면 이러한 사례를 쉽게 확인할 수 있습니다.

또 SCOTT(SQL 학습을 위한 데모 계정)이라는 아이디는 개발용 데이터베이스에서는 문제가 없겠지만 운영 데이터베이스에는 적절하지 않은 계정입니다. SCOTT 계정은 침입을 위한 백도어로 사용될 수 있으므로 설치 후 바로 삭제하는 것이 좋습니다.

그 밖에 오라클 툴에 의해 사용되는 계정으로 CTXSYS, DMSYS, OLAPSYS 등이 있습니다. 관련 옵션을 사용하지 않는다면 이 계정들 역시 삭제하는 것이 권장됩니다. 이 계정의 사용 여부를 확신할 수 없거나 만약을 위해 남겨두고자 한다면, 계정을 잔류시키되 외부 연결로부터 잠금 설정을 하는 것이 가능합니다. 계정을 잠그고 암호를 만료 처리하기 위한 구문이 아래와 같습니다:

 

alter user dmsys account lock expire password;

 

위 구문을 실행하면 계정이 EXPIRED & LOCKED 상태로 설정되었습니다. 사용자가 로그인을 시도하면 아래와 같은 에러가 발생합니다.

 

ERROR:
ORA-28000: the account is locked
Warning: You are no longer connected to ORACLE.

 

잠금 설정을 할 수 없는 계정에 대해서는 패스워드를 변경해 줍니다. 그 한 가지 예로 DBNSMP를 들 수 있습니다 (여기에 대해서는 뒷부분에서 다시 설명합니다.)

 

주의 사항

사용되지 않는 계정을 잠그는 것으로 인해 문제가 발생할 이유는 없습니다

 

실행 계획

사용되지 않는 계정의 검색.
계정 잠금 및 패스워드 만료 처리.

 

1.2 오라클 바이너리 권한의 설정

 

배경 정보

오라클 데이터베이스는 여러 가지 바이너리 파일을 사용합니다. 그 중 가장 중요한 파일로 UNIX/Linux의 “oracle”, Windows의 “oracle.exe”를 꼽을 수 있습니다.

이 파일들의 실행 권한을 확인해 봅시다. UNIX에서는 다음과 같은 결과를 얻을 수 있습니다

 

# cd $ORACLE_HOME/bin
# ls -l oracle
-rwsr-s--x    1 oracle oinstall    69344968 Jun 10 14:05 oracle

 

실행 권한은 디폴트 값으로 설정되어 있습니다. (권한은 오라클 버전에 관계없이 동일하게 설정됩니다.) 각각의 설정이 의미하는 바를 확인해 보시다 (UNIX 실행 권한의 개념에 익숙하다면, 이 섹션을 생략하고 "2-태스크 아키텍처"로 바로 진행하셔도 됩니다.)

첫 번째 문자는 파일의 타입을 의미합니다. UNIX에서는 모든 것(정규 파일, 디렉토리, 디바이스 등)이 파일로 취급됩니다. 위의 경우 “-“으로 표시되고 있으므로 정규 파일임을 알 수 있습니다. 디렉토리의 경우는 “d”, 특수 문자 디바이스인 경우에는 “c” 등으로 표시됩니다.

두 번째 이후의 문자는 파일에 설정된 권한을 의미합니다. 권한은 3개 문자 단위로 표시되며 각각 읽기,쓰기,실행 권한의 설정 상태를 의미합니다. 앞의 세 문자는 소유자(owner)의 권한을, 그 다음 세 문자는 파일이 소속된 그룹(group)의 권한을, 그리고 마지막 세 문자는 다른 모든 사용자에 제공되는 권한을 표시합니다.

위치 1 2 3 4 5 6 7 8 9 10
- r w s r - s - - x
Owner Group Other


각 권한은 특정 값 또는 “-“의 값을 갖습니다. “-“은 해당 권한이 부여되지 않았음을 의미합니다. 실행 예의 6 번째 위치에서 Group에 대한 쓰기 권한이 “-“로 표시되어 있습니다. 따라서 (파일이 소속된) “dba” 그룹은 이 파일에 쓰기 작업을 수행할 수 없습니다. 권한이 부여된 경우에는, 해당되는 값이 문자로 표시됩니다. 실행 예에서 그룹의 읽기 권한(5번째 문자)이 “r”로 표시되어 있으므로 “dba” 그룹은 이 파일을 읽을 수 있습니다.

마지막 3 개의 문자는 다른 사용자(oracle 사용자 또는 “dba” 그룹에 속하지 않은 사용자)들의 권한을 의미합니다. 실행 예에서 다른 사용자들은 이 파일을 실행할 수 있으나 읽거나 쓸 수 없습니다.

“r”, “w”, “x”는 각각 읽기(read), 쓰기(write), 실행(execute)를 의미합니다. 그렇다면 “x” 대신 표시된 “s”는 무엇을 의미할까요? 위에서 “s”는 프로그램이 setid에 대해 활성화되어 있음을 뜻합니다. setid가 활성화되어 있는 경우, 프로그램이 어떤 사용자에 의해 실행되든 실제로 프로그램을 소유한 사용자(“oracle”)의 이름으로 실행됩니다. 따라서 오라클 소프트웨어가 프로그램을 소유하고 있지만 오라클에 접속하는 어떤 사용자든 프로그램의 실행이 가능한 것입니다. 또 프로그램이 다른 사용자가 아닌 “oracle”의 권한으로 실행되므로, 데이터베이스 파일의 오픈과 같은 작업이 가능합니다.

“Two-Task” 아키텍처. 오라클 데이터베이스가 사용자 프로세스와 서버 프로세스를 구분하여 실행한다는 사실을 기억하고 계실 줄 압니다. 기억이 잘 나지 않는다면, Oracle Database 10g Concepts Manual 의 앞 부분 몇 챕터를 읽어 보시기 바랍니다. 이 자료는 오라클 데이터베이스의 실행 방식에 대해 매우 간략한 형태로 설명하고 있으며, 권한에 대한 기본적인 개념을 이해하는데 도움이 됩니다. (하지만 제품 매뉴얼의 내용만큼 자세하지는 않습니다.)

사용자가 SQL*Plus와 같은 프로그램을 사용하여 오라클 데이터베이스에 접속하는 경우, 오라클은 사용자 프로그램에 서비스를 제공하기 위해 새로운 프로세스를 생성합니다. 이 새로운 프로세스는 Oracle server process라 불리며 사용자 프로세스(sqlplus, splplus.exe, TOAD.exe 등)와 구분됩니다. 이 서버 프로세스는 SGA(System Global Area)와 같은 메모리 구조에 접근하며, SGA의 데이터 블록 버퍼에 데이터가 존재하지 않는 경우 데이터 파일로부터 직접 데이터를 읽어 들입니다. 어떠한 경우에도 사용자 프로세스(sqplus)가 오라클 데이터베이스에 직접 접근할 수는 없습니다. 작업을 완료하기 위해 두 가지 프로세스(사용자 프로세스와 서버 프로세스)가 병렬적으로 실행되므로, 이러한 구조를 “two-task” 아키텍처라 부르기도 합니다. 사용자 프로세스가 수행한 작업으로 인해 데이터베이스 손상의 위험이 있는 경우(예: 호스트 머신의 메모리 관리를 위반하는 경우)에도 오라클 데이터베이스는 영향을 받지 않으며, 피해 범위는 사용자 프로세스로만 한정됩니다.

(위의 설명은 “dedicated” 서버 환경의 오라클 연결에만 적용됨을 참고하시기 바랍니다. “multi-threaded” 서버 환경에서는 단일 서버 프로세스가 두 개 이상의 사용자 프로세스에 서비스를 제공할 수 있으므로 그 개념이 다소 달라집니다. “two-task” 아키텍처는 여전히 유효하지만, 서버와 사용자 프로세스의 관계는 1:1이 아닌 1:N으로 구성됩니다.)

서버 프로세스는 오라클 소프트웨어를 소유한 사용자의 이름으로 실행됩니다. 그 예가 아래와 같습니다. 사용자가 SQL*Plus를 이용하여 데이터베이스에 로그인했다고 가정해 봅시다.

 

$ sqlplus arup/arup

 

다음으로 프로세스를 조회해 봅시다:

 

$ ps -aef|grep sqlplus

 

그러면 아래와 같은 결과가 표시됩니다:

 

$ ps -aef|grep sqlplus

 

여기서는 다른 SQL*Plus 세션이 서버에서 실행 중이지 않음을 가정하고 있습니다.
이번에는 프로세스 아이디 6339를 기준으로 다시 조회해 보겠습니다.

 

$ ps -aef|grep 6339

 

두 개의 프로세스가 결과로 출력됩니다:

 

oracle    6339    6185    0 13:06 pts/0    00:00:00 sqlplus
oracle    6340    6339    0 13:06 ?    00:00:00 oracleDBA102 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))

 

첫 번째 프로세스(SQL*Plus 세션을 위한 프로세스)는 이미 우리가 잘 알고 있는 것입니다. 두 번째 프로세스(프로세스 ID 6340)은 오라클이 사용자를 위해 생성한 서버 프로세스입니다. 여기서 프로세스의 Parent Process ID(6339)가 SQL*Plus 세션의 프로세스 ID임을 알 수 있습니다.

프로세스 이름("oracleDBA102 (DESCRIPTION=(LOCAL=YES) (ADDRESS=(PROTOCOL=beq)))")에서도 몇 가지 정보를 얻을 수 있습니다. 먼저 “LOCAL=YES”는 이 프로세스가 로컬(데이터베이스가 실행되는 서버)에서 실행 중인 다른 프로세스에 의해 시작되었음을 의미합니다. 또 “PROTOCOL=beq”는 “bequeath” 연결을 통해 연결이 설정되었음을 의미합니다.

다이내믹 뷰를 통해 서버 프로세스에 대한 정보를 확인할 수도 있습니다.

 

select spid
from v$session s, v$process p
where s.sid = (select sid from v$mystat where rownum < 2)
and p.addr = s.paddr;

 

위 쿼리를 실행하면 서버 프로세스의 프로세스 ID가 반환됩니다. 클라이언트 프로세스가 다른 서버에서 실행 중이라면(예: 사용자의 노트북에서SQL*Plus으로 데이터베이스에 접속한 경우), 이 쿼리가 프로세스 ID를 확인하기 위한 유일한 방법입니다.

이제 사용자가 다른 방법을 사용하여 접근하는 경우, 서버에 직접 접속하는 대신 TNS 문자열을 사용하는 경우를 가정해 봅시다. oradba 서버의 TNS 문자열은 아래와 같습니다.

 

DBA102 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = oradba)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = DBA102)
)
)

 

이제 사용자가 아래와 같은 방법으로 oradba 서버에 연결합니다:

 

sqlplus arup/arup@dba102

 

다이내믹 뷰에서 프로세스 ID를 확인해 봅시다:

 

SQL> select spid
2 from v$session s, v$process p
3 where s.sid = (select sid from v$mystat where rownum < 2)
4 and p.addr = s.paddr
5 /

SPID
------------
6428

 

프로세스 ID는 6428입니다. 프로세스 ID를 기준으로 서버의 프로세스를 조회해 보겠습니다

 

$ ps -aef|grep sqlplus | grep -v grep oracle    6426    6185    0   13:20 pts/0   00:00:00 sqlplus

 

이제 데이터베이스 서버의 서버 프로세스를 검색하면 아래와 같은 결과를 얻습니다

 

$ ps -aef|grep 6426 | grep -v grep
oracle 6426 6185 0 13:20 pts/0 00:00:00 sqlplus

 

서버 프로세스가 확인되지 않았습니다. 사용자 프로세스 6426의 자식 프로세스가 존재하지 않습니다. 하지만 다이내믹 성능 뷰를 통해 서버 프로세스의 ID가 6428이라는 사실은 이미 확인했습니다. 그렇다면 프로세스 ID 6428의 부모 프로세스는 누구일까요?

 

$ ps -aef|grep 6428 | grep -v grep oracle    6428    1 0 13:20 ? 00:00:00 oracleDBA102 (LOCAL=NO)

 

부모 프로세스는 “1”입니다. 왜 6426이 아니고 1일까요?

그 답을 얻으려면, 먼저 오라클 서버 프로세스가 생성되는 방법을 이해해야 합니다. 사용자가 TNS 문자열을 사용하지 않은 첫 번째 예의 경우, 연결은 리스너를 거치지 않고 데이터베이스로 직접 전달되었습니다. 데이터베이스는 사용자 프로세스를 생성하고 프로세스의 컨트롤을 프로세스 소유자에게 넘겨 줍니다. 이러한 절차를 “bequeathing”이라 부르며, “bequeath” 프로세스라는 용어 역시 여기에서 유래합니다.

두 번째의 예에서는 사용자가 여전히 동일한 서버에 위치하지만 이번에는 리스너를 통해 연결을 시도합니다. 리스너는 사용자를 위한 프로세스를 생성하며 이 과정을 “forking”이라 부릅니다. 사용자 프로세스가 랩탑과 같은 다른 머신에서 실행되는 경우에도, 연결은 리스너로 전달되고 리스너가 프로세스를 생성하게 됩니다. 이 경우 프로세스가 원격 서버에 의해 생성되므로 프로세스 이름에 “LOCAL=NO”라는 문자열이 포함됩니다. 설사 SQL*Plus가 같은 서버에서 실행되고 있다 하더라도, “bequeath” 연결이 아닌 이상 “LOCAL=NO”로 표시됩니다.

(참고: 일부 운영체제에서는 “bequeath” 프로세스로 생성된 서버 프로세스의 부모 ID를 확인할 수 없을 수도 있습니다. 또 “bequeath” 연결임에도 불구하고 부모 ID가 “1”로 표시되는 경우도 있습니다. 따라서 서버 프로세스의 타입을 확인할 때에는 부모 ID가 아닌 프로세스 이름을 참고해야 합니다.)

이제 “two-task” 모델에 대해 이해하셨으리라 생각합니다. 그렇다면 지금까지 설명한 내용의 가장 중요한 교훈은 무엇일까요? 바로 SQL*Plus와 같은 클라이언트 프로세스가 아닌 데이터베이스가 서버 프로세스를 생성하고 실행한다는 사실입니다. “oracle” 또는 “oracle.exe” 실행 파일은 서버 프로세스에 의해 실행되며, 따라서 오라클 소프트웨어의 소유자(“orasoft”)만이 해당 바이너리를 실행할 권한을 가져야 합니다. 그렇다면 왜 다른 사용자들에게 실행 권한을 부여할 필요가 있는 것일까요?

간단히 답부터 말한다면, 그럴 필요가 없습니다. 아래와 같이 실행하여 불필요한 권한을 제거할 수 있습니다.

 

$ chmod 4700 $ORACLE_HOME/bin/oracle

 

명령을 실행한 후의 권한 설정이 아래와 같습니다.

 

-rws------ 1 orasoft oinstall 248754168 Oct 8 07:11 oracle

 

여기서는 SUID 비트를 이용하여 설정을 변경하는 방법을 사용하기로 합니다. 이 경우 (소유자의 rws 권한에 명시된 대로) SUID 비트는 ON으로 설정되어 있습니다.

 

전략

오라클 소프트웨어 소유자(“orasoft”) 이외의 어떤 사용자도 오라클 실행 파일을 실행할 필요가 없으므로, SUID 비트를 제거하고 바이너리의 소유자에 의해서만 접근이 가능하도록 설정해야 합니다.

$ chmod 0700 $ORACLE_HOME/bin/oracle

 

변경된 설정이 아래와 같습니다

 

-rwx------ 1 orasoft oinstall 248754168 Oct 8 07:11 oracle

 

주의 사항

이것은 매우 중요한 변경 사항이며, 따라서 그 영향을 이해할 필요가 있습니다. 오라클 소프트웨어의 소유자가 아닌 사용자가 로컬 연결을 사용하여 서버에 접근하는 경우, “oracle” 실행 파일은 “orasoft” 사용자에 의해 실행됩니다. 이것은 매우 중요한 사실입니다. 서버 프로세스가 (“orasoft”가 소유한) 데이터 파일을 열게 되므로, 프로세스가 “orasoft”의 이름으로 실행되거나 사용자가 데이터 파일을 열 수 있는 권한을 가져야 합니다.

한 예로, UNIX 사용자 “ananda”가 데이터베이스 서버에 로그인한 후 로컬 연결을 시도하는 경우를 가정해 봅시다.

$ sqlplus arup/arup

 

사용자는 아래와 같은 에러를 확인하게 됩니다.

ERROR:
ORA-12546: TNS:permission denied

Enter user-name:

 

그 이유는 아주 간단합니다. “oracle” 파일의 SUID 권한을 제거했기 때문입니다. 사용자가 로컬 연결을 시도한다는 것은, 결국 사용자가 “oracle” 실행 파일을 실행함을 의미합니다. 하지만 SUID가 설정되어 있지 않으므로 “orasoft”가 아닌 “ananda”의 이름으로 실행됩니다. ananda가 이 파일을 실행할 권한이 없으므로 ORA-12546 에러가 발생하는 것입니다.

그렇다면 어떻게 하면 ananda가 데이터베이스에 연결할 수 있을까요? 두 가지 대안이 있습니다. 그 하나는 모든 사용자 프로세스가 데이터베이스 서버와 다른 서버에서 실행되도록 함으로써 “bequeath” 연결이 생성되지 않도록 하는 것입니다. 로컬로 실행되지 않는 모든 연결은 리스너를 거치며, 리스너가 사용자를 위한 서버 프로세스를 대신 생성해 주므로, 서버 프로세스는 클라이언트 프로세스를 실행하는 사용자가 아닌 “orasoft”(오라클 소프트웨어 소유자)에 의해 실행됩니다. 따라서 별도로 권한을 설정해 줄 필요가 없습니다.

또 다른 대안으로, 데이터베이스 서버에서 사용자 프로세스를 로컬 실행해야 하는 경우라면 아래와 같은 방법으로 리스너를 거칠 수 있습니다.

$ sqlplus /nolog
SQL> connect sys/Password_of_SYS@dba102 as sysdba

 

이 경우 SYS 암호를 사용하게 되며, 이는 “/ as sysdba”보다 더 효과적인 방법입니다. 하지만 좀 더 나은 방법은 각각의 DBA를 위해 별도의 Oracle UserID를 생성하는 것입니다.

connect ANANDA/Password_of_ANANDA@dba102 as sysdba

 

해커들은 임의의 계정을 이용하여 데이터베이스에 강제 침입하는 방법을 즐겨 사용하곤 합니다(이때 자주 사용되는 계정이 “nobody”입니다). 해커가 데이터베이스에 진입하지 못한 경우라도 오라클 실행 파일에 버퍼 오버플로우를 발생시켜 DoS 공격을 시도하는 것이 가능합니다. 파일의 실행 권한을 제거하는 방법으로, 공격의 피해를 극적으로 감소시킬 수 있습니다. 이렇게 하더라도, 합법적인 사용자는 아무런 제약을 받지 않습니다. 대부분의 사용자는 리스너를 사용하여 데이터베이스에 연결하므로 설정 변화에 아무런 영향을 받지 않습니다.

 

실행 계획 (준비 작업)

bequeath” 연결을 사용하여 시스템에 접근하는 사용자가 있는지 확인합니다. 두 가지 방법이 가능합니다:

  • 사용자들에게 물어봅니다
  • 서버의 프로세스를 검색하여 SQL*Plus 등을 이용한 연결이 있는지 확인합니다.
  • V$SESSION의 MACHINE 컬럼을 확인합니다.

     

    select program
    from v$session
    where machine = '';

     

    의심스러운 문제가 발견되었다면, 감사(audit) 기능을 활성화하여 실행 중인 프로그램을 확인하고 그 결과를 캡처합니다 (여기에 대해서는 다음 단계에서 상세하게 설명합니다)

     

    Action
    IF <서버로부터 연결된 프로그램이 없는 경우>, THEN
    오라클 실행 파일의 권한을 변경
    chmod 0700 $ORACLE_HOME/oracle
    ELSIF some program connects from the server
    연결을 UserID/Password에서 UserID/Password@Connect_String으로 변경
    END IF
    IF <”sqlplus / as sysdba”를 이용하여 쉘로부터 자주 연결하는 경우> THEN
    DBAUser/Password@Connect_String을 사용하도록 변경
    END IF

     

    1.3 다른 실행 파일의 보안

     

    배경 정보

    $ORACLE_HOME/bin 디렉토리의 다른 실행 파일을 살펴 봅시다. Sqlplus, Isnrctl(리스너 시작을 위한 유틸리티) 등 몇 가지는 눈에 익기도 하지만, 몇 가지는 처음 보는 것일 수도 있습니다.

    tnslsnr(Listener 프로세스가 실행하는 유틸리티), dbsnmp(Oracle Intelligent Agent에 의해 사용)과 같은 일부 파일은 엔드 유저가 직접 접근하지 않습니다. 이러한 실행 파일의 보안을 위해 적절한 조치를 취할 필요가 있습니다.

    앞에서 설명한 것처럼 SUID 비트가 설정되어 있으면, 파일을 실제로 누가 실행하는가에 관계없이 파일이 소유자의 권한으로 실행됩니다. 또 SUID 설정은 보안상 매우 위험할 수 있으며 따라서 가능한 한 사용을 자제해야 합니다.

    SUID가 설정된 몇 가지 실행 파일이 존재합니다. 한 번 찾아 보기로 합시다.

     

    $ cd $ORACLE_HOME
    $ find . -type f \( -perm -1700 -o -perm -4000 \) -exec ls -l {} \;

    Oracle Database10g Release 1 이후 버전에서는 아래와 같은 실행 파일이 반환됩니다:

    -rwsr-s--x    1 orasoft  dba    93300507 Jul 22 11:20 ./bin/oracleO
    -r-sr-s---    1 root    dba    0 Jul 1 23:15 ./bin/oradism
    -rwsr-s--x    1 orasoft    dba    94492 Jul 22 11:22 ./bin/emtgtctl2
    -rwsr-s---    1 root    dba    18944 Jul 22 11:22 ./bin/nmb
    -rwsr-s---    1 root  dba    20110 Jul 22 11:22 ./bin/nmo
    -r-sr-sr-x    1 nobody   nobody    58302 Jul 22 11:23 ./bin/extjob

     

    각각의 파일에 대해 알아 보겠습니다.

    프로그램 설명
    ./bin/oracleO“oracle” 실행 파일의 복사본입니다. relink 커맨드를 사용하여 오라클 실행파일을 재컴파일한 경우, 기존의 파일은 oracle0라는 이름으로 저장됩니다. 이것은 잠재적인 보안 위협으로 작용할 수 있습니다. 대부분의 DBA들이 oracle0의 존재를 간과하고 있기 때문에 해커에게는 손쉬운 진입 경로로 활용됩니다. 따라서 권한을 제거하는 작업을 수행해 주어야 합니다. 이 파일에 대해서는 권한을 완전히 제거하는 것이 바람직합니다

    $ chmod 0000 oracleO

    이제 권한 설정 상태를 확인해 봅시다:

    $ ls -l oracleO
    ---------- 1 orasoft oinstall 248823320 Sep 15 13:27 oracleO

    ./bin/oradismDynamic Intimate Shared Memory를 위해 사용됩니다. 플랫폼에 따라 사용될 수도 있고 사용되지 않을 수 있으며, 경우에 따라 표시되지 않을 수도 있습니다. 이 파일의 권한은 변경하지 않습니다.
    ./bin/emtgtctl2Enterprise Manager Agent를 위해 사용됩니다. 이 실행 파일은 SUID가 설정되어 있을 필요가 없습니다(그 이유는 “oracle” 실행 파일의 경우와 같습니다). 아래와 같이 권한을 제거합니다.

    $ chmod 0700 emtgtctl2

    ./bin/nmbOracle 10g Grid Control 에이전트가 타겟 서버의 성능 통계를 수집하는데 사용합니다. 이 파일의 권한은 변경하지 않습니다.
    ./bin/nmoOracle 10g Grid Control 에이전트가 타겟 서버의 성능 통계를 수집하는데 사용합니다. 이 파일의 권한은 변경하지 않습니다.
    ./bin/extjob EXTJOB (External Jobs; Enterprise Manager 내에서 OS 프로그램을 실행하기 위한 기능)을 위한 실행 파일입니다. 이 파일은 조심할 필요가 있습니다. 외부 작업을 실행할 필요가 있는지 먼저 자문해 보십시오. 필요가 없다면 이 실행 파일 또한 불필요하며, 따라서 권한과 소유권을 변경해 줄 수 있습니다. 사용자는 오라클 소프트웨어 소유자(orasoft)로 권한은 “rwx------”로 설정해 줍니다.

    $ chown orasoft:oinstall extjob
    $ chmod 0700 extjob

    extjobO이라는 이름의 또 다른 프로그램이 존재할 수도 있습니다(동일한 프로그램의 이전 컴파일된 버전입니다). 이 파일의 권한 역시 변경해 줍니다.

    $ chown orasoft:oinstall extjobO
    $ chmod 0000 extjobO



    Oracle9i Database Release 2에서는 ./bin/dbsnmp 파일(Oracle Intelligent Agent 실행 파일)이 존재합니다. 이 파일의 권한은 아래와 같이 설정되어 있습니다:

     

    -rwsr-s--- 1 root dba 2986836 Jan 26 1705 dbsnmp

     

    이 파일은 루트 권한이 있어야만 정상적으로 실행이 가능하며, 따라서 SUID 비트가 설정되어 있어야 합니다. 하지만 이 파일이 루트 계정에 의해 소유되어 있기 때문에, 해커들이 루트 권한을 획득하는 방법으로 활용되기도 합니다. 가장 좋은 방법은 파일을 제거하거나 오라클 소프트웨어의 소유자가 이 파일을 소유하도록 하고 권한을 700으로 설정하는 것입니다. 이로 인해 일부 기능이 제약될 수도 있지만, 그 정도의 위험을 감수할 만한 가치가 있습니다.

    그 밖에 고려해야 할 실행파일로 tnslsnr(Oracle Net Listener)이 있습니다. 이에 관련하여 두 가지 실행 파일이 존재합니다

    tnslsnr ? 리스너의 실행 파일
    lsnrctl ? 리스너의 관리(시작, 중단 등)를 위한 유틸리티.

    설정된 권한을 조회해 봅시다

     

    $ ls -l *lsnr* -rwxr-x--x 1 orasoft oinstall 214720 Oct 25 01:23 lsnrctl
    -rwxr-xr-x 1 orasoft oinstall 214720 Oct 1 18:50 lsnrctl0
    -rwxr-x--x 1 orasoft oinstall 1118816 Oct 25 01:23 tnslsnr
    -rwxr-xr-x 1 orasoft oinstall 1118816 Oct 1 18:50 tnslsnr0

     

    두 파일에 대해 모든 사용자에게 실행 권한이 부여되어 있습니다. oracleO 실행파일과 마찬가지로, 오라클 소프트웨어의 재링크(relink)를 통해 새로운 tnslsnr 파일이 생성되면 기존의 tnslsnr 파일은 tnslsnr0로 이름이 변경됩니다. tnslsnr0 파일은 프로세스를 롤백 해야 하는 경우에 기존의 실행 파일을 새로운 파일에 덮어쓰기 할 때 사용됩니다. tnslsnr0 파일은 기존의 tnslsnr 파일과 동일한 기능을 수행할 수 있습니다. lsnrctl0 파일 역시 마찬가지입니다.

     

    전략

    각 실행 파일의 목적을 이해했다면, 이제 데이터베이스 인프라스트럭처의 보안을 구현하는 방법에 대해 알아봅시다. 대부분의 전략은 위 섹션에서 이미 충분히 설명되었습니다. 결론적으로, DBA가 취해야 할 전략이 아래와 같습니다

    1. 불필요한 파일의 모든 권한을 제거합니다(예: lsnrctl0).
    2. 실행 파일의 권한을 오라클 소프트웨어로만 제한합니다.
    3. 오라클 소프트웨어 소유자가 프로세스를 시작하는 경우 SUID 비트를 제거합니다.

    리스너에 관련된 파일의 권한은 아래와 같은 방법으로 변경합니다.

    $ chmod 700 lsnrctl tnslsnr
    $ chmod 000 lsnrctl0

     

    그 결과를 확인해 봅시다.

    $ ls -l *lsnr*
    -rwx------    1 orasoft    oinstall    214720 Oct 25 01:23 lsnrctl
    ----------   1 orasoft    oinstall    214720 Oct 1 18:50 lsnrctl0
    -rwx------   1 orasoft    oinstall   1118816 Oct 25 01:23 tnslsnr
    ----------   1 orasoft    oinstall    1118816 Oct 1 18:50 tnslsnr0

     

    주의 사항

    몇 가지 주의해야 할 사항이 다음과 같습니다

  • racle 실행 파일을 변경하는 것은 데이터베이스 운영에 아무런 영향을 미치지 않습니다. “oracle” 실행파일의 손상으로 인한 문제를 겪는 경우, “oracleO” 파일의 이름을 “oracle”로 변경하는 방법으로 문제를 해결하는 것이 가능합니다. 이때 권한을 700으로 재설정하도록 주의합니다. lsnrctl0, tnslsnrctl0 파일의 경우도 마찬가지 입니다.

  • 오라클 소프트웨어 소유자의 사용자 아이디를 Enterprise Manager 운영체제 로그인 계정으로 사용하는 경우, emtgtctl2 파일의 권한을 변경해도 아무런 영향이 없습니다. (orasoft가 아닌) 다른 사용자 아이디를 사용하는 경우에는 SUID와 권한을 기존의 값으로 재설정해 주어야 합니다.

  • dbnsmp 실행파일은 until Oracle9i Database Release 2와 그 이전 버전에서만 Oracle Enterprise Manager Intelligent Agent에 의해 사용됩니다. 오라클 소프트웨어 소유자의 사용자 아이디를 운영체제 로그인 계정으로 사용하는 경우에는, 이 파일의 실행 권한을 변경해 주어도 아무런 영향이 없습니다. 다른 사용자 아이디를 사용하는 경우라면 실행 권한을 이전의 값으로 재설정해 주어야 합니다.

     

    실행 계획

    몇 가지 주의해야 할 사항이 다음과 같습니다

    1. oracleO, tnslsnr0, lsnrctl0의 실행 권한을 0000으로 변경합니다.
    2. tnslsnr과 lsnrctl의 권한을 0700으로 변경합니다.
    3. Enterprise Manager에서 외부 작업(external job)을 사용하고 있습니까?
    4. IF <그렇지 않은 경우> THEN
    ELSE
    extjob의 권한을 0700으로 수정하고 소유자와 그룹을 각각 orasoft와 oinstall(또는 오라클 소프트웨어 소유자의 사용자 아이디와 그룹)으로 변경합니다.
    END IF

    IF Oracle9i Database를 사용하는 경우
    Oracle Intelligent Agent를 사용 중입니까?
    IF <그렇지 않은 경우> THEN
    dbsnmp의 오너십을 orasoft로 변경합니다.
    권한을 0700으로 변경합니다.
    ELSE
    변경 작업이 불필요합니다.
    END IF

     

    1.4 umask의 사용

     

    배경 정보

    여러분도 잘 알고 계시다시피, UNIX/Linux 환경에서는 chmod 커맨드를 이용하여 실행 권한을 변경해 줄 수 있습니다. 하지만 chmod는 이미 존재하는 파일에 대해서만 동작합니다. 그렇다면 차후에 생성될 파일에 대해 동일한 권한이 설정됨을 어떻게 보장할 수 있을까요?

    예를 들어 디렉토리의 모든 파일이 r--r--r?(444) 권한을 갖도록 설정해야 하는 경우를 가정해 봅시다. 아래와 같은 방법을 사용하면 됩니다:

     

    $ chmod 444 *

     

    이제 해당 디렉토리에 내용이 없는 파일 하나를 생성하고 그 권한을 확인합니다.

     

    $ touch a_file.txt
    $ ls -l a_file.txt
    -rw-r--r--    1 orasoft    dba    0 Oct 21 13:44 a_file.txt

     

    소유자에 대해 읽기/쓰기, 그룹에 대해 읽기, 그리고 다른 사용자에 대해 읽기 (644) 권한이 설정되어 있습니다. 여러분이 기대했던 444와는 다른 결과입니다. 그 이유가 무엇일까요?

    새로 생성되는 파일의 실행 권한은 umask라는 이름의 매개변수에 의해 결정됩니다. umask는 모든 권한이 부여된 chmod 값(777)에서 새로운 파일의 chmod 값을 뺀 값을 저장하고 있습니다. 예를 들어 umask를 777로 설정하면, 새로운 파일의 권한은 777에서 777을 뺀 값, 즉 000이 됩니다. 그 실행 예가 아래와 같습니다.

     

    $ umask 777
    $ touch b_file.txt
    $ ls -l ?_file.txt
    -rw-r--r--   1 oracrmp dba    0 Oct 21 13:44 a_file.txt
    ----------    1 oracrmp dba    0 Oct 21 13:53 b_file.txt

     

    b_file.txt 파일의 권한이 000으로 설정되어 있음을 확인하시기 바랍니다. 하지만 앞에서 생성된 a_file.txt의 권한은 변경되지 않았습니다. umask의 값(777)은 새로운 파일에만 영향을 미친다는 사실을 알 수 있습니다.

    umask는 오라클이 생성하는 파일의 권한을 제어하기 위한 매우 효과적이고 강력한 도구입니다.

     

    전략

    오라클 소프트웨어 소유자의 umask는 022로 설정되어야 합니다. 즉, 소유자에게는 Read+Write 권한이, 다른 사용자에게는 Read 권한이 할당되어야 합니다. 이 설정을 사용자의 로그인 프로파일에 저장하여 언제든 실행될 수 있도록 할 수 있습니다.

    오라클이 사용하는 파일에는 데이터 파일, 리두 로그 파일, 트레이스 파일 등 여러 가지 종류가 있습니다. 데이터파일은 미리 생성되며 그 권한을 쉽게 변경할 수 있지만, 트레이스 파일은 런타임에 생성됩니다. 따라서 umask를 이용하여 파일이 외부 사용자에게 노출되지 않도록 할 필요가 있습니다. 트레이스 파일은 해커에 의해 악용될 수 있는 민감한 정보를 포함하고 있습니다. 예를 들어, 데이터 파일을 복제하고 별도의 서버에 마운트하는 방법으로 정보를 유출하는 것이 이론적으로 가능합니다.

    각 디렉토리의 umask를 아래와 같이 설정합니다.

    디렉토리
    설명umask
    초기화 매개변수
    background_dump_dest에 지정된 디렉토리
    이 위치에서 일부 트레이스 파일과 데이터베이스 경고 로그가 생성됩니다. 권한은 rw------- (오라클 소프트웨어 소유자에게만 Read+Write 권한 부여)로 설정되어야 합니다.

    0177

    초기화 매개변수
    user_dump_dest에 지정된 디렉토리
    이 위치에서 트레이스 파일이 생성됩니다. 권한은 위와 동일한 방법으로 설정되어야 합니다.
    0177
    $ORACLE_HOME/rdbms/log
    이 위치에서 일부 데이터베이스 로그 파일이 생성됩니다. 권한은 위와 동일한 방법으로 설정되어야 합니다.

    0177

    $ORACLE_HOME/rdbms/audit
    audit_file_dest 초기화 매개변수를 별도로 설정하지 않은 이상, 데이터베이스 감사 로그(audit trail)가 이곳에 저장됩니다. 권한은 위와 동일한 방법으로 설정되어야 합니다. DB 감사 로그를 별도로 관리하는 경우에도, SYSDBA 연결, 데이터베이스 스타트업/셧다운과 같은 일부 이벤트는 항상 이곳에 기록됩니다.
    0177
    초기화 매개변수
    audit_file_dest에 지정된 디렉토리
    audit_file_dest 초기화 매개변수를 별도로 설정한 경우, 데이터베이스 감사 로그(audit trail)가 이곳에 저장됩니다. 권한은 위와 동일한 방법으로 설정되어야 합니다.
    0177

     

    주의 사항

    위와 같은 방법으로 umask를 적용한 경우, user_dump_dest 디렉토리에 생성된 세션 트레이스 파일에 개발자들이 접근할 수 없는 상황이 발생할 수 있습니다. 따라서 이 디렉토리에 대해서만큼은 예외적인 룰을 정의할 필요가 있습니다.

     

    실행 계획

  • background_dump_dest의 umask를 0177로 변경합니다.
  • $ORACLE_HOME/rdbms/log의 umask를 0177로 변경합니다.
  • $ORACLE_HOME/rdbms/audit의 umask를 0177로 변경합니다.
  • audit_file_dest의 umask를 0177로 변경합니다.
  • (선택 사항) user_dump_dest의 umask를 0177로 변경합니다.

     

    1.5 SYSDBA 로그인의 제한

     

    배경 정보 “dba” 그룹에 포함된 UNIX/Linux 사용자는 아래와 같은 명령을 이용하여 SYSDBA 권한으로 로그인할 수 있습니다

     

    sqlplus / as sysdba

     

    DBA가 SYS 패스워드를 기억하거나 입력할 필요가 없다는 편의성 때문에 이러한 방법이 자주 사용되곤 합니다. 하지만 이로 인한 취약점 또한 존재합니다. dba 그룹 멤버로 로그인할 수 있는 모든 사용자는 SYS 권한으로 데이터베이스에 로그인할 수 있습니다. SYS에 아무리 강력한 암호 체계를 적용해도 이는 무용지물과 다름없습니다. SYS 계정의 강력한 권한을 보호하려면 dba 그룹이 SYS 계정으로 로그인하면서 SYS 암호를 반드시 입력하도록 하는 것이 좋습니다. 이런 방법으로 외부 침입을 완전히 차단할 수는 없겠지만, 그 위험을 상당 수준 줄일 수 있습니다.

     

    전략

    이 프로세스는 SQLNET.ORA 파일의 SQLNET.AUTHENTICATION_SERVICES 매개변수에 의해 통제됩니다. 이 매개변수가 NONE으로 설정되었다면, SYSDBA 역할의 자동 로그인 기능은 비활성화됩니다. 자동 로그인의 비활성화를 위해 $ORACLE_HOME/network/admin 디렉토리에 위치한 SQLNET.ORA 파일에 아래 라인을 삽입해 줍니다.

     

    SQLNET.AUTHENTICATION_SERVICES=(NONE)

     

    이제 dba 그룹에 포함된 사용자가 아래와 같은 방법으로 로그인을 시도하면

     

    $ sqlplus / as sysdba

     

    다음과 같은 에러를 확인하게 됩니다.

     

    ERROR:
    ORA-01031: insufficient privileges

     

    성공적으로 연결하기 위햇는 SYS 패스워드를 함께 입력해야 합니다.

     

    $ sqlplus /nolog
    SQL> connect sys/oracle as sysdba

     

    이와 같은 방법으로 SYS 패스워드를 알지 못하는 해커가 dba 계정을 이용하여 접근을 시도하는 것을 차단할 수 있습니다.

     

    주의 사항

    위에서 분명히 확인할 수 있는 것처럼, SYS 패스워드를 명시적으로 입력해야 한다는 사실이 중요합니다. 따라서 SYS 계정으로 연결하는 스크립트에 변경 사항을 적용해 주어야 합니다.

    SYS 패스워드를 분실하더라도 걱정할 필요는 없습니다. SQLNET.ORA 파일의 라인을 주석 처리하고 이전과 같은 방법(/ as sysdba)으로 로그인할 수 있습니다.

     

    실행 계획

    IF <스크립트에서 SYS 계정을 이용하여 연결하는 경우> THEN
    ““/ as sysdba”를 “ sys/ as sysdba”로 변경합니다.
    SQLNET.ORA 파일에 “SQLNET.AUTHENTICATION_SERVICES=(NONE)” 설정을 추가합니다.
    ELSE
    변경 작업이 불필요합니다.
    END IF

     

    1.6 Listener 패스워드의 생성

     

    배경 정보

    해커들이 가장 즐겨 사용하는 트릭 중 하나가 대량의 텍스트를 리스너로 전달하여 실행을 강제 종료하도록 유도하는 것입니다. 이 경우 데이터베이스는 여전히 실행 중이지만 리스너가 다운되기 때문에 새로운 연결을 생성할 수 없게 되므로, “서비스 거부(denial of service)” 공격이 가능합니다.

    해커는 이를 위해 리스너의 속성 변경을 시도할 수 있습니다. 이를 위해 services 커맨드를 이용하여 리스너에 의해 처리되는 서비스의 목록을 조회하는 방법이 자주 사용됩니다. 아래 실행 예에서 볼 수 있는 것처럼 해커에게 필요한 충분한 수준의 정보가 제공되고

     

    LSNRCTL> set displaymode verbose
    LSNRCTL> services
    Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)
    (HOST=prolin1.proligence.com)(PORT=1521)(IP=FIRST)))
    Services Summary...
    Service "PROPRD" has 1 instance(s).
    Instance "PROPRD1", status READY, has 1 handler(s) for this
    service...
    Handler(s):
    "DEDICATED" established:0 refused:0 state:ready
    LOCAL SERVER
    (ADDRESS=(PROTOCOL=BEQ)(PROGRAM=/u01/oracle/products/10.1/db1/bin/ora cle)(ARGV0=oraclePROPRD11)(ARGS='(LOCAL=NO)')(ENVS='_=/u01/oracle/pro ducts/10.1/db1/bin/racgmain,_USR_ORA_CONNECT_STR=/ as sysdba,_CAA_CHECK_INTERVAL=600,SHLIB_PATH=/u01/oracle/products/10.1/d b1/lib32:/u01/oracrs/10gr1crs/lib32:/opt/nmapi/nmapi2/lib/hpux32:,_CA A_ACTIVE_PLACEMENT=0,PATH=,_USR_ORA_ALERT_NAME=,_USR_ORA_IF=,_CAA_OPT IONAL_RESOURCES=,_USR_ORA_START_TIMEOUT=0,ORACLE_BASE=/u01/oracle/pro ducts/10.1/db2,_USR_ORA_DISCONNECT=false,_CAA_SCRIPT_TIMEOUT=600,_CAA _UPTIME_THRESHOLD=7d,_USR_ORA_STOP_TIMEOUT=0,_CAA_FAILOVER_DELAY=0,_U SR_ORA_PRECONNECT=none,_USR_ORA_FLAGS=,_CAA_TYPE=application,_USR_ORA _INST_NOT_SHUTDOWN=,_CAA_REASON=boot,INIT_STATE=3,_USR_ORA_OPEN_MODE= ,_CAA_STATE=:OFFLINE,,_CAA_RESTART_ATTEMPTS=5,_CAA_ACTION_SCRIPT=/u01 /oracle/products/10.1/db1/bin/racgwrap,_CAA_DESCRIPTION=CRS application for Instance,_CAA_HOSTING_MEMBERS=prolin1,ORA_RACG_EXEC_ENV=LD_LIBRARY_PA TH=/u01/oracle/products/10.1/db1/lib:/u01/oracrs/10gr1crs/lib:/opt/nm api/nmapi2/lib/hpux64:/usr/lib:,_CAA_CLIENT_LOCALE=,_CAA_NAME=ora.PRO PRD1.PROPRD11.inst,ORA_CRS_HOME=/u01/oracrs/10gr1crs,_CAA_AUTO_START= 1,_CAA_TARGET=:ONLINE,,_USR_ORA_PFILE=,_USR_ORA_OPI=false,_USR_ORA_CH ECK_TIMEOUT=0,_CAA_PLACEMENT=restricted,_USR_ORA_LANG=,LD_LIBRARY_PAT H=/u01/oracle/products/10.1/db1/lib:/u01/oracrs/10gr1crs/lib:/opt/nma pi/nmapi2/lib/hpux64:/usr/lib:,_CAA_REQUIRED_RESOURCES=ora.prolin1.vi p,_CAA_FAILURE_THRESHOLD=0,ORACLE_HOME=/u01/oracle/products/10.1/db1, _USR_ORA_SRV=,PWD=/u01/oracrs/10gr1crs/bin,_USR_ORA_VIP=,_USR_ORA_STO P_MODE=immediate,_CAA_FAILURE_INTERVAL=0,_USR_ORA_NETMASK=,_USR_ORA_D EBUG=0,ORACLE_SID=PROPRD1,ORA_NET2_DESC=9,12,ORACLE_SPAWNED_PROCESS=1 ')(ENV_POLICY=NONE))

     

    또 다른 해킹 유형으로 리스너를 셧다운하는 방법이 있습니다. 새로운 연결은 거부되며, 따라서 실질적인 서비스 거부 공격이 가능합니다.

    또는 다른 서버에 먼저 침입한 후 리스너의 원격 관리 기능을 이용하여 리스너를 원격에서 종료하는 방법이 가능합니다.

    이러한 위협으로부터 데이터베이스를 보호하려면 어떻게 해야 할까요?

     

    전략

    최선의 대안은 tnslsnr, lsnrctl 실행 파일의 소유자를 제외한 모든 권한을 제거하는 것입니다. (이 방법은 앞 섹션에서 설명한 바 있습니다.) 이러한 방법으로 오라클 소프트웨어의 소유자를 제외한 어느 누구도 리스너를 시작 또는 종료할 수 없도록 통제할 수 있습니다. 실행 파일의 권한은 아래와 같이 설정됩니다.

     

    -rwx------    1 orasoft oinstall    214720 Oct 25 01:23 lsnrctl -rwx------   1 orasoft oinstall   1118816 Oct 25 01:23 tnslsnr

     

    경우에 따라 리스너의 시작/종료 권한을 다른 사용자에게 허용해야 할 수도 있습니다. 이러한 경우라면 아래와 같이 권한을 변경해 주어야 합니다.

     

    $ chmod 0711 lsnrctl

     

    하지만 이와 같은 경우라 하더라도 패스워드 정책을 통해 불법적인 침입을 차단할 수 있어야 합니다. 패스워드를 설정하면 (HELP와 같은 무해한 명령을 제외한) 모든 커맨드가 비활성화됩니다.

    패스워드를 설정하는 방법은 버전에 관계없이 동일합니다. 하지만 그 적용 메커니즘은 버전에 따라 다릅니다.

  • Oracle9i Database Release 2 및 이전 버전에서는 모든 사용자가 패스워드를 입력해야 합니다.
  • Oracle Database 10g Release 1 및 이후 버전에서는 데이터베이스 소프트웨어를 소유한 OS 사용자는 패스워드를 입력할 필요가 없습니다. 다른 모든 사용자는 패스워드를 필요로 합니다.
    패스워드의 설정 방법이 아래와 같습니다

     

    $ lsnrctl

    LSNRCTL> change_password
    Old password: Not displayed
    New password: Not displayed
    Reenter new password: Not displayed
    Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=prolin1)(PORT=1521)(IP=FIRST)))
    Password changed for LISTENER
    The command completed successfully

     

    패스워드를 처음으로 설정하는 경우, “Old Password”를 묻는 프롬프트에서 그냥 ENTER 키를 눌러도 됩니다. 변경 사항을 적용한 뒤 그 결과를 매개변수 파일에 저장합니다.

     

    LSNRCTL> save_config

     

    위 커맨드는 패스워드를 암호화하여 리스너 매개변수 파일에 저장합니다. 그 내용은 나중에 확인이 가능합니다.

     

    #----ADDED BY TNSLSNR 24-OCT-2005 17:02:28---
    PASSWORDS_LISTENER_ODSSDB01 = 75CD180DE6C75466
    #--------------------------------------------

     

    이제 커맨드를 사용하려면 패스워드를 입력해야 합니다 (Oracle Database 10g 및 이후 버전에서는 소프트웨어를 소유한 OS 사용자는 패스워드를 입력할 필요가 없습니다.) LSNRCTL> services Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521)) TNS-01169: The listener has not recognized the password

    패스워드를 입력하는 방법이 아래와 같습니다

     

    LSNRCTL> set password mypassword
    The command completed successfully
    LSNRCTL> status
    Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
    STATUS of the LISTENER
    ------------------------
    Alias LISTENER
    ...

     

    잘못된 패스워드가 입력되면 아래와 같은 에러가 뜹니다.

     

    TNS-01169: The listener has not recognized the password.

     

    패스워드를 입력하지 않고 명령을 실행하면 아래와 같은 에러가 뜹니다.

     

    TNS-01190: The user is not authorized to execute the requested listener command

     

    패스워드가 적용되었는지 확인하기 위해서는 아래와 같이 실행하여 리스너의 STATUS 설정을 조회합니다.

     

    $ lsnrctl status

     

    출력 결과는 버전에 따라 다릅니다. Oracle9i Database 환경의 실행 결과 중 일부가 아래와 같습니다.

     

    STATUS of the LISTENER
    ------------------------
    Alias           LISTENER
    Version      TNSLSNR for Solaris: Version 9.2.0.6.0 - Production
    Start Date      25-OCT-2005 10:26:47
    Uptime           0 days 13 hr. 8 min. 36 sec
    Trace Level      off
    Security           ON

     

    마지막 라인(Security ON)에서 패스워드가 설정되었음을 확인할 수 있습니다.

    Oracle Database 10g에서는 설정 방법이 조금 다릅니다. 10g의 경우 오라클 소프트웨어의 소유자만이 패스워드 없이 리스너를 실행할 수 있도록 설정되어 있습니다. 따라서 패스워드가 설정된 경우, 다른 사용자들은 패스워드를 입력한 경우에만 리스너의 실행이 가능합니다. STATUS 설정값의 확인 결과가 아래와 같습니다.

     

    STATUS of the LISTENER
    ------------------------
    Alias           LISTENER_ODSPDB02
    Version      TNSLSNR for HPUX: Version 10.1.0.4.0 - Production
    Start Date      16-OCT-2005 05:58:35
    Uptime           9 days 17 hr. 44 min. 41 sec
    Trace Level      off
    Security           ON: Local OS Authentication

     

    마지막 라인(ON: Local OS Authentication)에서 패스워드가 설정되지 않았음을 알 수 있습니다. 패스워드가 설정된 경우에는 아래와 같이 표시됩니다.

     

    Security    ON: Password or Local OS Authentication

     

    “Password”라는 단어를 통해 패스워드가 설정되어 있음을 알 수 있습니다.

     

    주의 사항

    Oracle Database 10g 및 이후 버전에서는 특별히 주의할 사항이 없습니다. 사용자 인증을 위해 OS 인증이 사용되며 리스너의 시작/중단을 위해 패스워드를 입력할 필요가 없습니다. Oracle9i 및 이전 버전에서는 패스워드를 입력해 주어야 하며 따라서 스크립트에도 패스워드를 포함시켜야 합니다.

     

    Action Plan

    IF THEN
    소유자를 제외한 모든 사용자의 권한을 제거합니다.
    ELSE
    소유자를 제외한 모든 사용자의 권한을 제거합니다.
    리스너의 패스워드를 설정합니다.
    END IF

     

    1.7 리스너의 보호

     

    배경 정보

    시스템에 침입하기 위한 방법으로 리스너에 매우 긴 문자열을 전송하여 버퍼 오버플로우를 유도하는 테크닉이 자주 사용됩니다. 또 다른 침입 경로로 lsnrctl 유틸리티의 SET DISPLAYMODE VERBOSE 명령을 사용하여 컴포넌트의 목록을 확인하는 방법이 있습니다. 이 경우 해커는 취약한 머신에서 lsnrctl을 실행하여 설정을 조작한 후, 이를 이용하여 타겟 서버의 리스너에 접근합니다. 그 예가 아래와 같습니다.

     

    LSNRCTL> set trc_level support
    Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=prolin1)(PORT=1521)))
    LISTENER parameter "trc_level" set to support
    The command completed successfully
    LSNRCTL> set trc_directory /tmp
    Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=prolin1)(PORT=1521)))
    LISTENER parameter "trc_directory" set to /tmp
    The command completed successfully

     

    전략

    리스너를 보호하기 위한 최상의 대안은 패스워드를 설정하는 것입니다. 또는 lsnrctl 유틸리티를 사용하여 리스너 매개변수의 설정 기능을 제한할 수 있습니다. 이 경우, 매개변수를 변경하기 위해서는 리스너 설정 파일을 변경한 후 다시 로드해야 합니다. 매개변수 설정을 제한 하려면 listener.ora 파일에 아래 라인을 추가하면 됩니다.

     

    ADMIN_RESTRICTIONS_LISTENER = ON

     

    그런 다음 리스너를 재시작합니다. 이제는 lsnrctl 프롬프트에서 SET 커맨드를 사용할 수 없습니다. 실행 예가 아래와 같습니다.

     

    LSNRCTL> set trc_directory /hacker_dir
    Connecting to (ADDRESS=(PROTOCOL=IPC)(KEY=PROPRD1))
    TNS-12508: TNS:listener could not resolve the COMMAND given

     

    위에서 볼 수 있듯 TNS-12508 에러가 발생하였습니다. 이제부터는 설정 값을 변경하려면 listener.ora 파일을 수정하고 커맨드를 다시 로드해야 합니다.

     

    LSNRCTL > reload

     

    이 방법은 모든 오라클 버전에 동일하게 적용됩니다.

    패스워드를 사용하여 리스너를 보호하는 경우에도, 이 테크닉을 추가로 적용하여 해커의 리스너 접근 능력을 제한할 수 있습니다. 특히 오라클 소프트웨어 소유자에게는 리스너 패스워드를 요구하지 않는 Oracle Database 10g 환경에서 이 방법이 유용하게 사용됩니다.

     

    주의 사항

    특별히 주의할 사항은 없습니다. 사용자가 온라인 상태에서 매개변수를 편집하는 경우는 거의 없으며, 대부분 listener.ora를 편집하고 리스너를 다시 로드하는 방법을 사용하기 때문입니다.
    하지만 다른 서버의 리스너를 관리하기 위해 원격 리스너 컨트롤 기능을 사용할 수 없다는 점을 참고해야 합니다. 그 대신, 원격 서버에 로그온한 후 listner.ora 파일을 수정하고 리스너를 다시 로드하는 방법을 사용해야 합니다 (실제로도 이러한 방법이 권장됩니다).

     

    실행 계획

    1. listener.ora 파일에 ADMIN_RESTRICTIONS_LISTENER = ON 매개변수를 설정합니다.
    2. lsnrctl reload 명령을 실행하여 리스너를 다시 로드합니다.

     

    1.8 과도한 권한의 제한

     

    배경 정보

    일반적으로 사용자들은 자신이 주로 수행하는 작업에 관련된 권한만을 필요로 합니다. 각 사용자에게 꼭 필요한 권한만을 부여하는 방법이 현실적인 대안이 되기는 어렵겠지만, 차선책으로 사용자들에게 부여된 강력한 권한 중 일부를 제거하는 작업이 필요할 수 있습니다.

    사용자들에게 불필요한 강력한 권한의 예로 “CREATE ANY TABLE”이 있습니다. 사용자는 이 명령을 사용하여 자신의 스키마 뿐 아니라 다른 어떤 스키마에서도 테이블을 생성할 수 있습니다. 사용자들이 이 권한을 실제로 사용하는 경우는 매우 드물기 때문에, 권한을 취소하더라도 문제는 없습니다. 반면, 사용자 세션에서 함수 기반 인덱스 또는 MV(materialized view)를 이용한 쿼리 재작성을 허용하는 “QUERY REWRITE”와 같은 권한은 상대적으로 무해하다고 볼 수 있습니다.

     

    전략

    먼저, 위험하지 않다고 판단되는 권한의 목록을 작성합니다 (CREATE TYPE, CREATE SESSION 등). 필자는 이 목록에 “UNLIMITED TABLESPACE”를 포함시켰습니다만 동의하지 않는 분도 계실 것입니다.

     

    set pages 50000
    break on privilege skip 1

    select privilege, grantee, admin_option
    from dba_sys_privs
    where privilege not in
    (
    /* list any other privilege here you don't find
    "sweeping"
    */
    'ALTER SESSION',
    'QUERY REWRITE',
    'CREATE DIMENSION',
    'CREATE INDEXTYPE',
    'CREATE LIBRARY',
    'CREATE OPERATOR',
    'CREATE PROCEDURE',
    'CREATE SEQUENCE',
    'CREATE SESSION',
    'CREATE SNAPSHOT',
    'CREATE SYNONYM',
    'CREATE TABLE',
    'CREATE TRIGGER',
    'CREATE TYPE',
    'CREATE USER',
    'CREATE VIEW',
    'UNLIMITED TABLESPACE'
    )
    and grantee not in
    ('SYS','SYSTEM','WKSYS','XDB',
    'MDSYS','ORDPLUGINS','ODM','DBA')
    /* Place all the user names you want to exclude */
    order by privilege, grantee
    /

     

    쿼리 실행 결과의 일부가 아래와 같습니다

    PRIVILEGE                   GRANTEE                        ADM--------------------------- ------------------------------ ---ADMINISTER DATABASE TRIGGER EXFSYS                         NO                            IMP_FULL_DATABASE              NOADMINISTER RESOURCE MANAGER EXP_FULL_DATABASE              NO                            IMP_FULL_DATABASE              NOALTER ANY MATERIALIZED VIEW DWETL                          NO                            REPORTMAN                      NOALTER ANY OUTLINE           REPORTMAN                      NOALTER ANY PROCEDURE         IMP_FULL_DATABASE              NO                            QCO                            NOALTER ANY RULE              CDC_PUB                        YESALTER ANY RULE SET          CDC_PUB                        YESALTER ANY TABLE             IMP_FULL_DATABASE              NO                            CNSMP                          NO                            QCO                            NOALTER ANY TRIGGER           IMP_FULL_DATABASE              NO                            QCO                            NO                            VCHANG                         NOALTER ANY TYPE              IMP_FULL_DATABASE              NOALTER SYSTEM                ORADBA                         NO                            QCO                            NOALTER TABLESPACE            QCO                            NOALTER USER                  QCO                            NO                            SYSMAN                         NOANALYZE ANY                 AFFMAN                         NO                            ARAO                           NO                            CONCASTER                      NOCREATE ANY SYNONYM          ATHOTANG                       YES                            ARUP                           YES                            IMP_FULL_DATABASE              NO                            DB_MONITOR                     YES                            QCO                            YES                            RCHUNG                         YES                            SPOT                           YESCREATE ANY TABLE            IMP_FULL_DATABASE              NO                            CNSMP                          NO                            QCO                            NO                            SYSMAN                         NODROP ANY TABLE              ATHOTANG                       YES                            IMP_FULL_DATABASE              NO                            CNSMP                          NO                            QCO                            YES_ 후략 _


    위 실행 결과에서 DROP ANY TABLE과 같은 권한은 일반 사용자들에게 전혀 필요하지 않은 것으로 볼 수 있습니다. 이제, 어떤 사용자들이 이러한 권한을 부여 받고 있는지 확인해 봅시다.

  • MP_FULL_DATABASE는 전체 데이터베이스의 임포트를 위한 역할로, 일반적으로 임포트 작업을 수행해야 하는 DBA 또는 다른 사용자에게 할당됩니다. 이 권한은 상황에 따라 필요할 가능성이 있습니다.
  • QCO는 데이터베이스 관리를 위해 사용되는 툴인 Quest Central for Oracle의 약자입니다. 이 권한도 필요할 가능성이 있습니다.
  • NSMP, ATHOTANG 사용자는 DBA가 아닌 이상 과도한 권한을 부여해 줄 필요가 없습니다. 따라서 권한을 제거해 줄 필요가 있어 보입니다.

     

    Implications

    이 작업은 결코 한 번에 실행해서는 안됩니다. 사용자에게서 권한을 제거하기 전에 그 영향을 주의 깊게 분석해야 합니다.
    의심스러운 부분이 있다면, 해당 ID를 사용하는 실제 사용자와 인터뷰를 하는 것이 가장 좋은 방법입니다. 예를 들어, ATHOTANG 사용자는 실제로 테이블의 DROP 작업을 수행할 필요가 없음에도 자신이 그러한 권한을 필요로 한다고 생각하고 있을 수도 있습니다. (결코 놀랄 일이 아닙니다. 이런 경우는 매우 흔합니다.)

     

    실행 계획

    이 작업을 수행하기 위해서는 어느 정도 사전 계획이 필요합니다. 따라서 실제 조치는 다음 단계로 연기하고 여기에서는 필요한 정보만 수집해 두도록 합니다.

     

    1.9 DBSNMP 패스워드의 변경

     

    배경 정보

    여러분들도 잘 알고 있다시피, Oracle Intelligent Agent는 Oracle Enterprise Manager와의 커뮤니케이션을 통해 데이터베이스, 리스너, 서버 등의 컴포넌트에 대한 정보를 전달합니다. 데이터베이스에 대한 정보를 얻기 위해 에이전트는 특정 사용자 아이디를 사용하여 데이터베이스에 접근해야 합니다. 디폴트 설정에서 사용되는 사용자 아이디는 DBSNMP입니다.

    데이터베이스가 생성되는 과정에서 dbsnmp의 패스워드는 “dbsnmp”로 설정됩니다. 이 사용자는 UNLIMITED TABLESPACE, SELECT ANY DICTIONARY(다이내믹 성능 뷰와 데이터 딕셔너리 뷰에 대한 쿼리), ANALYZE ANY DICTIONARY(시스템 오브젝트의 분석)와 같은 일부 강력한 권한을 소유하고 있습니다. 침입자들은 이 아이디와 패스워드를 이용하여 데이터베이스의 백도어 진입을 시도하기도 합니다. 따라서 매우 중요한 보안 취약점으로 고려되어야 합니다. .

     

    전략

    DBSNMP의 패스워드를 “dbsnmp”가 아닌 다른 것으로 바꾸어 주어야 합니다. 하지만 패스워드가 에이전트 설정 파일에도 저장되어 있기 때문에, 단순히 데이터베이스 레벨에서 패스워드를 변경해 주는 것만으로는 충분치 않습니다. 설정 파일에서도 새로운 패스워드를 사용하도록 업데이트해 주어야 합니다. Oracle Database 10g 환경에서의 패스워드 변경 방법이 아래와 같습니다.

     

    1. 먼저 DBSNMP 사용자의 패스워드를 다른 것(예: TopSecret:)으로 바꾸어 줍니다.
    SQL> alter user dbsnmp identified by topsecret;
    2. Oracle Agent Home이 설치된 디렉토리로 이동합니다 (예: /u01/app/oracle/10.1/gridc).
    3. /sysman/emd 디렉토리(은 호스트 또는 서버 이름)로 이동합니다. (예를 들어 서버 이름이 prolin1이라면, 디렉토리는 prolin1/sysman/emd입니다.)
    4. 디렉토리에서 targets.xml 이라는 이름의 파일을 찾아 다른 이름으로 복사합니다 (예: targets.xml.old).
    5. targets.xml 파일을 열고 "dbsnmp" 단어를 검색합니다. 아래와 같은 내용을 확인할 수 있을 것입니다.















    6. 아래 라인을 주목하십시오.

    이 곳에서 패스워드를 설정해 주어야 합니다. 위 라인을 아래 라인으로 대체합니다.

    7.
    여기서 ENCRYPTED를 FALSE로 설정하였음에 주의합니다.
    RAC 데이터베이스의 경우, 파일에 위 라인이 두 번 나오므로, 두 개의 항목을 모두 변경해 주어야 합니다. "password" 단어를 기준으로 검색하면 두 항목을 쉽게 찾을 수 있습니다.

    8. 이제 아래 명령을 실행하여 에이전트를 중단시킵니다.
    /u01/app/oracle/10.1/gridc/bin/emctl stop agent

    9. 에이전트를 재시작합니다.
    /u01/app/oracle/10.1/gridc/bin/emctl stop agent

    10. 에이전트를 재시작할 때, 설정 파일에 저장된 패스워드가 자동으로 암호화됩니다. targets.xml 파일을 다시 열어 보면 위 라인이 아래와 같이 수정되어 있음을 확인할 수 있습니다.

    일반 텍스트로 작성된 값이 암호화된 값으로 변경되어 있습니다.

    11. 이제 에이전트에 새로운 패스워드를 설정하는 작업을 완료하였습니다. 12. Grid Control 대신 스탠드얼론 Database Console을 사용하는 경우에도 유사한 방법을 사용합니다. 단 2 단계에서 Agent Home이 아닌 ORACLE_HOME으로 이동해야 한다는 것이 다른 점입니다.

     

    주의 사항

    특별히 주의할 사항은 없습니다.

     

    Action Plan

  • DBSNMP 사용자의 패스워드를 변경합니다.
  • 에이전트 파일의 패스워드를 업데이트합니다.

    본 문서에서 제공되는 정보는 참고 용도로 작성되었으며 오라클에 의해 검증되지 않았습니다. 따라서 실제 적용 작업에 대한 책임은 전적으로 사용자에게 있습니다! 어떠한 경우에도 본 문서의 내용이 컨설팅 또는 서비스의 일부로 해석되어서는 안됩니다.
  • by Dave Kim | 2010/08/10 18:04 | Security | 트랙백 | 덧글(0)

    원격에서 sysdba로 접속하기

    원격에서 sysdba로 접속하기

    출처 :  outspace.egloos.com/2257265

    1. remote_login_passwordfile을 exclusive로 설정


    SQL> show parameter remote_login

    NAME                     TYPE                   VALUE
    ------------------------------------ --------------------------------- ------------------------------
    remote_login_passwordfile         string                   EXCLUSIVE

    * none 이면 alter system set remote_login_passwordfile = exclusive scope=spfile; 로 변경


    2. DB 종료
    SQL> shutdown immediate;
    Database closed.
    Database dismounted.
    ORACLE instance shut down.


    3. 패스워드 파일 생성
    SQL> !orapwd file=orapwDB10 password=oracle entries=3;

    SQL> !ls $ORACLE_HOME/dbs/
    backup            hc_mac10g.dat        initdw.ora        lkDEV10G        orapwDEV10G        spfiledev10g.ora
    hc_DB10.dat        init.ora        initmac10g.ora        lkMAC10G        orapwmac10g        spfilemac10g.ora
    hc_dev10g.dat        initdev10g.ora        lkDB10            orapwDB10        spfileDB10.ora


    4. DB  시작
    SQL> startup
    ORACLE instance started.

    Total System Global Area  532676608 bytes
    Fixed Size            2085256 bytes
    Variable Size          155192952 bytes
    Database Buffers      369098752 bytes
    Redo Buffers            6299648 bytes
    Database mounted.
    Database opened.

    5. 원격지에서 hr user로 접속하되 sysdba권한으로 접속가능하게 설정
    SQL> grant sysdba to hr;  

    6. 원격지에서 테스트
    $ sqlplus hr/hr@DB10 as sysdba

    SQL*Plus: Release 10.2.0.4.0 - Production on Sun Dec 13 10:37:50 2009

    Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.


    Connected to:
    Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing options

    SQL> show user;
    USER is "SYS"

    by Dave Kim | 2010/08/10 16:10 | Administration | 트랙백 | 덧글(0)

    통계정보 운영관리 방법

                   dbtown-rchwin.jpg


    이번 시간에는 파티션 테이블의 통계정보 운영관리 방법에 대해 소개하겠다.
    단 소개하기전에 사전에 미리 언급해 둘 사항이 있다.
    지금 필자가 소개하는 이 방법이 절대 표준은 아니라는 것을 미리 말씀드리고 싶다.
    그럼 표준도 아닌데 왜 소개를 하냐 하겠지만...
    필자가 운영을 위해 고민하고 고민한 결과 우리 사이트는 이 방법을 선택했고 지금 이런 방법으로 아주 안정적으로 잘 운영하고 있기 때문에 필자와 같은 고민을 하는 사람들을 위해 공유하고픈 마음이다.
    그럼 시작하도록 하겠다.

    먼저 파티션 테이블은 일반테이블과 달리 통계정보 갱신을 딱 한번, 한달치의 데이터가 정상적으로 들어갔을때만 실행하고 평상시에는 통계정보 lock 을 걸어둔다.
    그리고 그 한달치의 파티션 통계정보를 가지고 매달 동일하게 넣어준다.
    하지만 필자가 몸담은 사이트 같은 경우는 파티션 테이블만 100 여개다.
    그렇기에 매달 작업하는 것은 여간 번거로운 작업일뿐더러 파티션 테이블은 관리 포인트도 많고 그만큼 무지하게 짜증난다. 그래서 필자가 몸담은 사이트 같은 경우는  매년 말 다음 년도의 1년치의 파티션을 미리 추가하고 파티션 추가작업이 끝날경우 마찬가지로 통계정보도 1년치를 미리 만들어 놓는다.
    이렇게 함으로써 파티션 작업이 누락되는 상황을 최소화 하고 있고 1년에 딱 한번을 제외한 평상시에는 파티션 작업으로 인한 스트레스를 안받고 있다.
    다시 한번 말씀드리지만 지금 소개한 부분은 필자가 몸담은 사이트의 관리 방식일 뿐이고 이게 정답은 아니라는 것을 말씀드린다.
    혹시라도 필자가 운영하는 것보다 더 좋은 방법이 있다면 알려주길 바란다. ^^

    ■ 통계정보를 생성에는 2가지 방법이 있다.

     

    첫째 ANALYZE 사용과

    둘째 DBMS_STATS 패키지 사용  (오라클 8i 버전에서 새롭게 추가된 DBMS_STATS 패키지를 사용하는 방법)

    의 두가지 방법이 있는데

    오라클에서는 DBMS_STATS 패키지 사용을 권고한다.

     

    DBMS_STATS 를 사용하면 좋은 점

     

    - PARALLEL  사용할수 있다.

    - 현재시점의 통계정보를 백업 하고 RECOVERY 할수 있다. (통계정보 이관시 사용한다

     

      통계정보 이관 방법  ( 파티션 테이블 ) 

     

    1. 통계정보를 담을 백업 테이블 생성

    exec dbms_stats.create_stat_table(ownname=>'SYSTEM',stattab=>'stats_backup',tblspace=>'USERS');

     

    2. 통계정보를 생성하기 전 한달치의 통계정보가 존재하는지 확인

      해당 값이 NULL 이면 통계정보 생성이 안되어 있는 것임

    SQL> select TABLE_NAME, PARTITION_NAME, SUBPARTITION_COUNT, LAST_ANALYZED, NUM_ROWS from dba_tab_partitions 

    where table_name = 'HISTORY'

    order by PARTITION_NAME;

     

    SQL> select TABLE_NAME, PARTITION_NAME, SUBPARTITION_COUNT, LAST_ANALYZED, NUM_R

    OWS from dba_tab_partitions

      2  where table_name = 'HISTORY'

      3  order by PARTITION_NAME

      4  /

    TABLE_NAME      PARTITION_NAME  SUBPARTITION_COUNT LAST_ANA   NUM_ROWS

    --------------- --------------- ------------------ -------- ----------

    HISTORY         P_200810                         0

    HISTORY         P_200811                         0

    HISTORY         P_200812                         0

    HISTORY         P_200901                         0

    4 rows selected.

     

     

    3.  통계정보 생성 ( 현재 10월달 한달치의 데이터만 들어가 있다 )

    exec dbms_stats.gather_table_stats(ownname=>'SCOTT', tabname=>'HISTORY', method_opt=> 'FOR ALL COLUMNS', cascade=>true , degree=>8,  granularity=>'ALL');

     

     

    4. 테이블과 인덱스에 통계정보 존재하는지 확인

    SQL> select TABLE_NAME, PARTITION_NAME, SUBPARTITION_COUNT, LAST_ANALYZED, NUM_R

    OWS from dba_tab_partitions

      2  where table_name = 'HISTORY'

      3  order by PARTITION_NAME;

     

    TABLE_NAME      PARTITION_NAME  SUBPARTITION_COUNT LAST_ANA   NUM_ROWS

    --------------- --------------- ------------------ -------- ----------

    HISTORY         P_200810                         0 08/12/12          6

    HISTORY         P_200811                         0 08/12/12          0

    HISTORY         P_200812                         0 08/12/12          0

    HISTORY         P_200901                         0 08/12/12         

     

    5. 생성된 통계정보를 운영DB import 하기위해 export 실행

    EXEC DBMS_STATS.EXPORT_TABLE_STATS

    (OWNNAME=>'SCOTT', TABNAME=>'HISTORY', STATTAB=> 'STATS_BACKUP',

    STATID=> 'STATS_BACKUP',STATOWN=>'SYSTEM', cascade=>true);

     

    6. 현재달을 제외한 0건으로 생선된 통계정보 삭제

    delete from system.STAT_BACKUP

    where c1 in ('HISTORY', 'HISTORY_IDX')

    and c2 in (

               'P_200811');

    commit

     

    7. 10 월달 통계정보를 11월달로 UPDATE

    update system.STATS_BACKUP

    SET c2 = 'P_200811'

    where c1 in ('HISTORY','HISTORY_IDX')

    and c2 = 'P_200810';

     

    commit;

     

    8. 파티션 통계정보를 UNLOCK  

    exec dbms_stats.unlock_table_stats('SCOTT','HISTORY');

     

    9. 새로운 파티션으로 IMPORT 작업

    Exec dbms_stats.import_table_stats(ownname=>'SCOTT',tabname=>'HISTORY',partname=>'P_200811', stattab=>'STATS_BACKUP', statid=>'STATS_BACKUP', statown=>'SYSTEM',cascade=>true);

     

    10. 파티션 통계정보를 LOCK  

    exec dbms_stats.lock_table_stats('SCOTT','HISTORY');

     

    11. IMPORT 한 통계정보 테이블에서 EMP 테이블의 통계정보를 IMPORT 한다..

    SQL> select TABLE_NAME, PARTITION_NAME, SUBPARTITION_COUNT, LAST_ANALYZED, NUM_R

    OWS from dba_tab_partitions

      2  where table_name = 'HISTORY'

      3  order by PARTITION_NAME;

     

    TABLE_NAME      PARTITION_NAME  SUBPARTITION_COUNT LAST_ANA   NUM_ROWS

    --------------- --------------- ------------------ -------- ----------

    HISTORY         P_200810                         0 08/12/12          6

    HISTORY         P_200811                         0 08/12/12          6

    HISTORY         P_200812                         0 08/12/12          0

    HISTORY         P_200901                         0 08/12/12         

     

    by Dave Kim | 2010/08/09 19:52 | Administration | 트랙백 | 덧글(0)

    ◀ 이전 페이지          다음 페이지 ▶