DB2는 OS 사용자를 대상으로 권한/특권 부여하여 관리한다. 따라서 계정 인증처리는 db2ckpwd 프로세스를 통하여 처리된다.

권한/특권 부여는 인스턴스 레벨 (OS 그룹을 dbm cfg 구성 변수에 설정), DB 레벨, 테이블 공간 등의 하위 object 레벨로 이뤄진다.

대부분은 DB 레벨에서만 권한 관리하는 방식으로 고객에게 제시를 하는 편이여서, 하위 object에 대한 특권 관리를 자세히 보지는 않았었다.

 

고객으로부터 특정 사용자가 테이블 생성, DML, LOAD 정도만 되도록 권한 관리 방안을 요청해 와서 살펴 보았다.

V10.1에서는 V9보다 조금 더 DB레벨 권한 종류가 다양해졌다.

모든 권한을 다 테스트해 본 것은 아니지만, DATAACCESS 권한이 상당히 비중이 큰 권한이라는 것을 이번 테스트를 통해서 알게 된 것 같다.

 

테스트 시나리오는 다음과 같다. (CentOS 6.2, V10.1 FixPack1)

데이터베이스 명 test
인스턴스 이름 inst10
사용자 명 db2user
스토리지 그룹 명 IBMSTOGROUP
테이블 공간 명 TS_DATA
TS_IDX
TS_LOB
버퍼풀 IBMDEFAULTBP
페이지 단위 4K
테이블 이름 t1

 

<데이터베이스 생성>

$ locale
LANG=ko_KR.UTF-8

$ db2 "create db test restrictive"

 

(참고) restrictive 옵션은 DB의 PUBLIC 그룹에 권한 부여를 하지 않아 권한없는 OS 사용자가 테이블 접근을 하지 못하도록 하겠다는 것을 의미한다.

         작년 한 고객사에서 보안 강화 작업을 한다고 하여, DB 레벨의 PUBLIC 접속 권한 회수하면서 접속 장애가 발생한 적이 있었다. 명시적으로 권한부여되지 않는 OS 계정으로 업무 처리를 하도록 되어 있었기 때문이였다.

 

<테이블공간 생성>

db2 +p -tv << EOF
connect to test ;
create large tablespace TS_DATA pagesize 4K managed by automatic storage using stogroup IBMSTOGROUP extentsize 16 bufferpool IBMDEFAULTBP ;
create large tablespace TS_IDX pagesize 4K managed by automatic storage using stogroup IBMSTOGROUP extentsize 16 bufferpool IBMDEFAULTBP ;
create large tablespace TS_LOB pagesize 4K managed by automatic storage using stogroup IBMSTOGROUP extentsize 16 bufferpool IBMDEFAULTBP ;
terminate ;
EOF

 

<권한 및 특권 부여>

db2 +p -tv << EOF
connect to test ;
grant CONNECT,CREATETAB,EXPLAIN,LOAD on database to user db2user ;    
grant USE of tablespace TS_DATA to user db2user ;
grant USE of tablespace TS_IDX to user db2user ;
grant USE of tablespace TS_LOB to user db2user ;
grant usage on workload sysdefaultuserworkload to user db2user ;
terminate ;
EOF

 

이 상태에서 테이블을 생성하면 에러 메시지가 발생한다.

SQL0551N  "DB2USER" does not have the required authorization or privilege to perform operation "EXECUTE" on object "NULLID.SQLC2J23".

SQL3015N  An SQL error "" occurred during processing.

 

위와 같이 에러가 발생한 이유는 object 관리를 위한 시스템(메타) object에 대한 특권이 부족해서 발생한다. 그래서 시스템 object 에 대한 접근특권을 부여해 주어야 한다.

 

 

다음과 같이 shell script 롤 SYSPROC, SYSIBMADM, SYSCAT, SYSIBM,NULLID 에 속한 object의 실행 및 조회특권을 부여한다. 이 작업을 하지 않고 가능하게 하는 방법은 DATAACCESS 권한을 부여하는 것이다.

단, 타인이 생성한 object에 대해서도 DML이 가능해진다.

db2 connect to test
USER=db2user

db2 -x "select rtrim(varchar(PKGSCHEMA,10))|| '.' || varchar(PKGNAME,50) packname from syscat.packages where PKGSCHEMA='NULLID'" > pack.lst
db2 -x "select rtrim(varchar(a.TABSCHEMA,10))|| '.' || varchar(a.TABNAME,50) tabname from syscat.tables a, (values ('SYSIBMADM'),('SYSCAT'),('SYSIBM')) as b(sname) where a.TABSCHEMA=b.sname" > tab.lst
#db2 -x "select rtrim(varchar(PROCSCHEMA,10))|| '.' || varchar(SPECIFICNAME,50) procname from syscat.procedures where PROCSCHEMA='SYSPROC'" > proc.lst
db2 -x "select rtrim(varchar(ROUTINESCHEMA,10))|| '.' || varchar(SPECIFICNAME,50) funcname from syscat.routines where ROUTINESCHEMA='SYSPROC' AND ROUTINETYPE='F'" > func.lst

exec < pack.lst
while read PACKNAME
do
  db2 -v "grant execute on package ${PACKNAME} to user ${USER}"
done
rm -f pack.lst

exec < tab.lst
while read TABNAME
do
  db2 -v "grant select on table ${TABNAME} to user ${USER}"
done
rm -f tab.lst

#exec < proc.lst
#while read PROCNAME
#do
# db2 -v "grant execute on specific procedure ${PROCNAME} to user ${USER}"
#done
#rm -f proc.lst


exec < func.lst
while read FNAME
do
  db2 -v "grant execute on specific function ${FNAME} to user ${USER}"
done
rm -f func.lst

db2 terminate

 

<테이블 생성>

db2 +p -tv << EOF
connect to test user db2user using db2user ;
create schema db2user ;
create table t1 (c1 varchar(10), c2 clob(1k)) IN TS_DATA INDEX IN TS_IDX LONG IN TS_LOB ;
insert into t1 values ('가나다','가가가'),('라마바','라라라') ;
terminate ;
EOF

 

<데이터 import>

db2 connect to test user db2user
db2 "import from t1.ixf of ixf lobs from /instance/inst10/lobs commitcount automatic  messages t1.imp.msg insert into t1"

 

db2 "select c1, varchar(c2,10) c2 from t1"

C1         C2
---------- ----------
가나다     가가가
라마바     라라라
가나다     가가가
라마바     라라라

  4 record(s) selected.

 

<데이터 load>

db2 "load from t1.ixf of ixf lobs from /instance/inst10/lobs messages t1.imp.msg insert into t1"

db2 "select c1, varchar(c2,10) c2 from t1"


C1         C2
---------- ----------
가나다     가가가
라마바     라라라
가나다     가가가
라마바     라라라
가나다     가가가
라마바     라라라

  6 record(s) selected.

 

인스턴스 계정으로 생성된 테이블 조회

db2 "select * from inst10.t1"
SQL0551N "DB2USER" does not have the required authorization or privilege to perform operation "SELECT" on object "INST10.T1". SQLSTATE=42501
db2 “terminate”

 

테스트를 해보면서 DATAACCESS 권한이 내가 생각한 것과는 달라서 실망을 했었다.

“CREATETAB 권한만 있어도 테이블 생성은 되도록 해야 하는데, 이게 뭐냐?”

나름 이유가 있었겠지만, 하위 object에 대해서 특권을 부여해야만 테이블 생성이 제대로 되니 작업이 많아 진 것은 안타깝다.

 

개인적으로 DATAACCESS 권한을 시스템 object 접근하는 것으로 한정한다면,

테이블 생성 작업은 위처럼 번잡스럽지 않을 것이고, 또한 타 계정의 object는 건들지 못하므로 보안적인 측면도 좋을 것이고..

 

개인적으로 DATAACCESS 권한에 개선이 있었으면 하는 바램을 가져 본다.

+ Recent posts