2008. 10. 3. 17:44

[번역] 9. Conditional Policies

 

 9. Conditional Policies

 


 9.1 Overview of Conditional policies


 

초기 발표 후 Selinux 정책 언어에서 첫번째 큰 기능강화의 하나가 Conditional policies의 지원이다.  Conditional policies은 Conditional 표현법에 의해

정의된 환경에 따라 정의된 정책의 설정들을 구별하여 사용 가능케 해준다. ( 그냥 if문하고 같은 의미 )

 

예를 보자 가령 우리가 모바일 컴퓨터를 가지고 있고 도킹되었을 때는 이더넷 네트워크 인터페이스에 접근하고 도킹되지 않았을 때는 wireless 네트워크 인터페이스에 접근하는 특별한 프로그램의 범위 타입의 접근을 위한 정책을 정의한다고 하자.(밑의 예에서는 myprog_t 라고 하자)

아마도 우리는 밑의 예와 같이 작성할 수 있을 것이다.

 

bool docked true;

if(docked){

     #rules to allow my_prog_t access to wired Ethernet device 

} else {

  #rules to allow my_prog_t access to wireless device

}

 

이 예에서 우리는 첫번째 docked라는 boolean 자료형을 선언하였다. 우리는 이 것으로 장치가 연결되었는지 아닌지를 SElinux에 나타낼수 있을 것이다.

다음 if라는 docked라는 Conditional expression를 포함한 Conditional statement를 만들고 true일때와  false일때에 대한 규칙을 적는다.

위 상태에서는 연결되었는지 아닌지에 대한 각 상황에 따하 allow 규칙을 사용하였다. 그리고 우리는 실행하는 서비스상에서 연결되었는지 아닌지에 따라

boolean의 값을 설정 할 수 있을 것이고 따라서 정책 규칙의 설정을 사용 할 수 있는 것이다.

 

이 간단한 예에서 Conditional policies의 기본형태에 대하여 설명 하였다. 다음 섹션에서 우리는 어떻게 동작중인 서비스 시스템에서 boolean 값을 바꾸고 규칙을 어떻게 정의 하는지 배울 것이다.

 ( p186 ~ 191쪽 참조 )

 


boolean 값의 정의


우리는 bool statement를 사용하여 boolean 값을 정의 할 수 있다.

 

 

bool user_ping false;    # controls whether users may use ping program

 


 Conditional Expression and Rule Lists


 가장 간단하고 흔히 쓰이는 Conditional statement의 형태는 Conditional statement에 따른 하나의 boolean값을 가지고 보틍 true값만을 정의한다.

예를 들어 일반 유저가 ping 프로그램을 이용하여 끄거나 켤 수 있는 정책을 만들자고 하고 이때 boolean을 user_ping이라고 하자.(앞의 boolean정의에서 동일)

 

user_ping이 활성화 되었을 때 유저 domain에 allow할 수 있도록 하자면 다음과 같이 작성할 수 있을 것이다.

 

#  Example : controlling user ping via a boolean

#    Assumption (defined elsewhere in policy ):

#       unpriv_userdomain : attribute for all ordinary user domains

#       ping_t : domain type for thr ping process ( which has necessary network interface access for ping to work)

#       ping_exec_t : entrypoint file type of the ping executable

 

 

if( user_ping ) {

# domain transition access to allow user access

allow unpriv_userdomain ping_t : process transition ;

allow unpriv_userdomain ping_exec_t : file { read getattr execute };

# enrypoint might be redundant since ping_t should already have it

# but adding it again is not harmful

allow ping_t ping_exec_t : file entrypoint;

 

         # cause the transition to happen by default

type_transition unpriv_userdomain ping_exec_t : process ping_t

}

 이 예에서 우리는 모든 일반 유저의 범위 타입들에게 접근할 수 있도록 할 수 있는 것을 보았다. domain변환은 ping_t 타입의 domain ping program에

접근하게 한다. 정책의 다른 것에서 우리는 ping 작업의 필요성에 의해 ping domain 타입에 접근하는 이 규칙을 사용할 수 있다.

...

... ( roles and users에 관하여 권한부여를 보장해주어야 한다는 내용 )

...

하지만,  이 예에서는 타겟이 되는 user role을 위한 무조건적인 권한 부여를 받은 ping_t domain 타입을 가지고 앞에서 말했듯이 이 권한부여가 타입변환 허용에 의해 이용될 수 있는지 컨트롤 한다.

 

 

다른 예를 들어보자.. 이번에는 처음에 이야기 했던 true와 false를 모두 이용한 장치에 대한 권한접근에 대해 알아 보겠다.

 

 

#  Example : restricting ping's access based on docked state

#    Assumption (defined elsewhere in policy ):

#       docked : boolean indicating docked state

#       ping_t : domain type for thr ping process

#       wired_netif : attrib for all wired netif types

#        wireless_netif : attrib for all wireless netif types

#  allowed wired access when docked, wireless otherwise

 

if( docked ) {

allow ping_t wired_netif : netif { tcp_send tcp_recv udp_send udp_recv rawip_send rawip_recv };

} else {

allow ping_t wireless_netif : netif { tcp_send tcp_recv udp_send udp_recv rawip_send rawip_recv };

}

 

# Remaining network and other access needed regardless of interface  

 allow ping_t self : capability { net_raw setuid };

 

# etc., remaining rules not listed for simplicity

 

위의 예를 보면 우리는 Conditaional Statement를 이용하여 두개 종류의 인터페이스에 (raw 접근을 포함한) 접근을 제어할 수 있다.

 그리고 여기서는 무조건적인 규칙(Conditaional Statement를 사용하지 않음 - Conditaional Statement내의 규칙을 가지지 않는 boolean값과 상관없이 항상 접근 가능)을 사용하는 네트워크 인터페이스와 상관없이 핑 작업에 필요한 다른 접근을 제공한다.

 

마지막으로 조금 더 복잡한 예를 들어 보겠다. 가령 우리가 일부 사용자 domain에 대하여 접근이 허용한 ping작업과 단지 일반적인 사용자를 위한 ping작업인지에 대한 제어를 하고 싶다고 하자. 먼저 user_ping이라는 boolean 이름 대신에 allow_ping을 사용하자. 게다가 우리는 오직 컴퓨터가 연결되었을때만을

원하기 때문에 다음과 같이 작성할 수 있다.

 

 

#  Example : restricting ping based on docked state and allow Boolean

#    Assumption (defined elsewhere in policy ):

#       docked : boolean indicating docked state

#       allow_ping : Boolean indicating whether ping is allowed

#       ping_t : domain type for thr ping process

#       ping_exec_t : entrypoint file type of the ping executable

#       wired_netif : attrib for all wired netif types

#       userdimain : attrib for all user domains ( priv & unpriv )

 

 

# allowed wired access when docked if allow

 

if( allow_ping && docked ) {

# domain transition permission

allow unpriv_userdomain ping_t : process transition ;

allow unpriv_userdomain ping_exec_t : file { read getattr execute };

allow ping_t ping_exec_t : file entrypoint;

type_transition unpriv_userdomain ping_exec_t : process ping_t

 

         # wired netif access for ping

         allow ping_t wired_netif : netif { tcp_send tcp_recv udp_send udp_recv rawip_send rawip_recv };

}

 

이 예는 Conditaional Expression에서 논리 연산자 &&와 두개의 boolean을 사용한 것을 보여준다. 이 예에서 두개의 boolean값은 상태(Condition)가 true인지와 규칙이 허용하는 지를 제어한다. && 연산자이외에도  ||(or), ^(xor), !(nor), ==, != 의 사용을 지원한다.

 


Nesting Conditional Statement ( 중접 )


 

최근까지 conditional statement 문법은 중첩을 지원하지 않는다. 다음 예를 보자

 

if( docked ) {

if( allow_ping ) {

       # docked and allow statement

}

}else{

 # undocked statement

}

 

위의 예문은 컴파일 에러가 날 것이다.

대신에 우리는 좀더 장황한 나누어진 상태로써 작성해야한다. 다음 예를 보자

 

 

if( docked && allow_ping ) {

       # docked and allow statement

}

 

if( docked )

  # docked statement

}else{

 # undocked statement

}

 

이 중첩에 대한 한계는 가까운 미래에 지원되도록 해야 할 것이다.