정책 유틸리티 사용

setools-console 패키지는 명령행에서 SELinux 의 보안 정책을 조회하고 다룰 수 있는 유틸리티의 묶음으로 사용법을 익혀두면 SELinux 의 동작에 대해서 더 자세히 이해할 수 있고 이를 통해 데몬 프로세스가 오작동할 때 문제 해결에 큰 도움이 되므로 익혀둘 필요가 있습니다.


사용하려면 먼저 다음 명령어로 패키지를 설치합니다.

$ sudo yum install setools-console
setools 유틸리티 설치


avcstat

avcstat 는 부팅 이후 AVC(Access Vector Cache) 에 대한 간략한 통계를 보여주는 명령어입니다.  AVC 캐시 통계의 소스 파일은  /sys/ fs/selinux avc/cache_stats 이며 -f /path/to/file 옵션을 사용하여 다른 캐시 파일을 지정할 수 있습니다.

$ avcstat


   lookups       hits     misses     allocs   reclaims      frees
 111659996  111644834      15162      15162      14624      14653
AVC 캐시 통계 출력

실행시 마지막 옵션으로 초 단위의 interval 을 주어서 업데이트 된 통계를 표시할 수 있습니다.

$ avcstat 3


   lookups       hits     misses     allocs   reclaims      frees
  111659996  111644834      15162      15162      14624      14653
   58686     258685          1          1          0         16
   266008     265976         32         32         32         32
3초마다 AVC 캐시 통계 출력

업데이트된 통계를 표시할 경우 표시 주기(위의 예에서는 3초)내에서 처리한 AVC 캐시 통계를 보여주므로 최초 출력보다 숫자가 작게 되며 -c  옵션을 주면 누적된 통계를 표시해 줍니다.

seinfo

seinfo 는 정책 클래스 갯수, 타입, 허용하는 규칙등 SELinux 의 보안 정책을 조회하고 보고서를 출력해주는 유용한 유틸리티입니다.

seinfo 를  옵션없이 실행하면 현재 정책을 요약해서 볼 수 있습니다.

$ seinfo


Statistics for policy file: /etc/selinux/targeted/policy/policy.24
Policy Version & Type: v.24 (binary, mls)

   Classes:            81    Permissions:       238
   Sensitivities:       1    Categories:       1024
   Types:            3916    Attributes:        295
   Users:               9    Roles:              12
   Booleans:          236    Cond. Expr.:       276
   Allow:          320389    Neverallow:          0
   Auditallow:        141    Dontaudit:      273303
   Type_trans:      42419    Type_change:        38
   Type_member:        48    Role allow:         19
   Role_trans:        386    Range_trans:      6258
   Constraints:        90    Validatetrans:       0
   Initial SIDs:       27    Fs_use:             23
   Genfscon:           84    Portcon:           483
   Netifcon:            0    Nodecon:             0
   Permissives:        90    Polcap:              2


TODO: Types, Booleans, Portcon 진하게,

보안 정책 요약

등록된 정책은 3,916 개의 Types 을 갖고 있으며 236 개의 불린, 483개의 포트 컨텍스트가 있음을 알수 있습니다.


--portcon 옵션을 사용하면 포트 번호에 할당된 보안 컨텍스트를 확인할 수 있으며 --protocol 옵션을 같이 사용하면 tcp 나 udp 를 구분하여 조회할 수 있습니다.

다음 명령어는 tcp 443 포트에 할당된 컨텍스트를 출력합니다.

$ seinfo --portcon=443 --protocol=tcp


portcon tcp 443 system_u:object_r:http_port_t:s0
portcon tcp 1-511 system_u:object_r:reserved_port_t:s0

TODO httpd_t, reserved_port_t  진하게

seinfo 로 443 포트 컨텍스트 조회

첫 줄의 의미는 portcon 이라는 포트 컨텍스트가 tcp 443이며 http_port_t 레이블이 할당되어 있으므로 이 레이블이 할당된 프로세스에서 접근할 수 있다는 의미이며 두 번째 줄은 tcp 1 에 511 포트는 reserved_port_t 라는 레이블이 적용되어 있음을 확인할 수 있습니다.

기본적으로 SELinux 는 1024 미만의 포트는 reserved_port_t 라는 레이블을 붙이며 1024 이상의 포트는 port_t 레이블을 부여합니다.

sesearch

sesearch seinfo 처럼 SELinux 의 규칙을 조회할 수 있는 유틸리티이며 seinfo 보다 더 세밀한 규칙으로 조회할 수 있는 특징이 있습니다.

많이 사용하는 옵션은 허용하는 정책을 조회하는 --allow(줄여서 -A) 로 소스 컨텍스트를 지정하는 -s 옵션과 타겟 컨텍스트를 지정하는 -t 옵션과 함께 사용합니다.


다음 예제는 소스 타입이 httpd_t 이고 타겟이 http_port_t 일 경우 허용하는 정책을 표시합니다.

$ sesearch -d --allow  -s httpd_t -t http_port_t


Found 4 semantic av rules:
   allow httpd_t http_port_t : udp_socket name_bind ; 
   allow httpd_t http_port_t : tcp_socket name_bind ; 
   allow httpd_t http_port_t : tcp_socket name_connect ; 
   allow httpd_t http_port_t : tcp_socket name_connect ; 
sesearch 로 허용 정책 검색

--direct(-d) 옵션은 -s-t 로 지정한 컨텍스트 타입과 정확하게 일치하는 type 만 표시합니다.

출력 결과중 다음 내용의 의미는 httpd_t 컨텍스트가 지정된 프로세스는 http_port_t 타입의 udp 소켓에 bind 할 수 있다는 의미로 허용한 전체 정책을 합산하면 httpd_t 프로세스는 http_port_t 타입의 udp, tcp 에 bindconnect 를 할 수 있으므로  클라이언트로 해당 포트에 연결하거나 서버로 포트 리슨이 가능합니다.

allow httpd_t http_port_t : udp_socket name_bind ;

SELinux 사용시 많이 하는 실수는 웹 컨텐츠 디렉터리에 적절한 컨텍스트를 지정하지 않아 웹 서버가 읽지 못하는 경우가 많습니다.

이런 문제 방지를 위해 httpd 프로세스가 httpd_sys_content_t 에 대해 어떤 권한을 갖고 있는지 다음 명령으로 확인해 봅시다.

$ sesearch -d --allow  -s httpd_t -t httpd_sys_content_t

Found 4 semantic av rules:
   allow httpd_t httpd_sys_content_t : dir { ioctl read getattr lock search open } ; 
   allow httpd_t httpd_sys_content_t : lnk_file { read getattr } ; 
   allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ; 
   allow httpd_t httpd_sys_content_t : dir { ioctl read write getattr lock add_name remove_name search open } ; 

TODO dir 진하게, file 진하게

httpd_sys_content_t 조회

첫 번째 allow 로 시작하는 라인의 출력의 의미는 다음과 같습니다.

  •  httpd_thttpd_sys_content_t 가 설정된 파일에 대해 ioctl, read, getattr, lock, open system call 이 가능


풀어서 설명하면 httpd_thttpd_sys_content_t 가 지정된 파일과 디렉터리를 읽을 수 있습니다.

하지만 3번째 allow 로 시작하는 file 항목을 보면 system call 중에서 write 가 빠져 있으며 이때문에 httpd_t 가 지정된 프로세스는 httpd_sys_content_t 타입에 대해 쓸수 없습니다.

allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ;

이는 최신 버전의 SELinux 의 주요 변경 사항으로 예전에는 httpd_sys_content_t 가 설정되었을 경우 웹 서버가 읽기/쓰기가 모두 가능하므로 첨부 파일 업로드 기능이 있는 웹 사이트라면 해킹 프로그램을 업로드해서 공격하는 경우가 많았습니다.


이런 문제때문에 최신 버전의 SELinux는 httpd_sys_content_t 는 읽기 전용,  httpd_sys_rw_content_t 는  쓰기 가능으로 정책이 분리되었습니다.

이런 변경 사항을 모른다면 워드프레스등의 CMS 를 사용할 경우 http 이미지나 첨부 파일을 업로드하는 폴더에 대해 쓰기를 못하므로 서비스가 제대로 안 되어 급한 마음에 SELinux 를 끄게 하는 원인이 됩니다.


복잡하지만 좋은 해결책은 업로드 폴더같이 명시적으로 쓰기가 필요한 폴더에 httpd_sys_rw_content_t 컨텍스트를 부여하는 것입니다.

그러면 httpd_sys_rw_content_t 는 어떤 설정을 갖고 있길래 쓰기가 가능한지를 sesearch 명령을 사용하여 조회해 봅시다.

$ sesearch -d --allow  -s httpd_t -t httpd_sys_rw_content_t

Found 11 semantic av rules:
   allow httpd_t httpd_sys_rw_content_t : file { ioctl read write create getattr setattr lock append unlink link rename open } ;
   allow httpd_t httpd_sys_rw_content_t : lnk_file { ioctl read write create getattr setattr lock append unlink link rename } ;
   allow httpd_t httpd_sys_rw_content_t : dir { ioctl read write create getattr setattr lock unlink link rename add_name remove_name reparent search rmdir open } ;

TODO dir 과 file 탭의 write, create,remove 를 진하게

httpd_sys_rw_content_t 조회

위와 같이 file, lnk_file, dir 의 권한에 write, create,remove 가 설정되어 있는 것을 확인할 수 있으며 이때문에 웹 서버는 해당 컨텐스트가 부여된 컨텐츠에 쓰기가 가능해 집니다.

findcon

findcon 은 SELinux context  를 검색해 주는 유틸리티로 아래와 같은 형식으로 사용합니다.

findcon FCLIST [OPTIONS] [EXPRESSION]


FSLIST 는 File Context List 의 약자로 어디에서 컨텍스트를 읽을 지를 의미하며 아래의 3가지 항목을 입력할 수 있습니다.

  • directory 
    해당 디렉토리와 그 하위 디렉터리에서 주어진 조건에 맞는 정책을 검색합니다. 

  • file_contexts 
    FCLIST가 file_contexts 파일의 이름(예: /etc/selinux/targeted/contexts/files/file_contexts) 이면 해당 정책 파일에서 일치하는 항목을 검색합니다.

  • database 
    indexcon 또는 apol 이라는 SELinux 정책 유틸리티의 실행으로 생성된 데이타 베이스를 분석할 경우에 사용합니다.


만약 현재 디렉터리내의 모든 파일과 폴더에 대해서 컨텍스트를 출력하며 필드 값은 다르지만 ls -RlaZ 과 비슷한 결과를 출력합니다.

$ findcon .


.	-d	system_u:object_r:user_home_dir_t:s0
./.bash_logout	--	system_u:object_r:user_home_t:s0
./.bash_profile	--	system_u:object_r:user_home_t:s0
./.bashrc	--	system_u:object_r:user_home_t:s0
./.cache	-d	system_u:object_r:cache_home_t:s0
현재 폴더의 컨텍스트 출력

-t 옵션을 주어서 원하는 컨텍스트를 가진 파일과 폴더를 찾을 수도 있습니다. 아래는 웹 서버의 컨텐츠 디렉터리에서 웹 서버가 쓰기 가능한 httpd_sys_rw_content_t 가 부여된 파일과 폴더를 출력합니다.

$ findcon -t httpd_sys_rw_content_t /var/www/

/var/www/wordpress/wp-content/uploads	-d	unconfined_u:object_r:httpd_sys_rw_content_t:s0
/var/www/wordpress/wp-content/uploads/2017	-d	unconfined_u:object_r:httpd_sys_rw_content_t:s0
/var/www/wordpress/wp-content/uploads/2017/11	-d	unconfined_u:object_r:httpd_sys_rw_content_t:s0
특정 폴더내 컨텍스트 출력

FCLIST가 file_contexts 일 경우 정책 파일내에서 일치하는 내용을 찾게 되며 이는 httpd_sys_rw_content_t 같은 특정 컨텍스트가 부여되는 디렉터리의 목록을 조회하는데 유용합니다.


다음 명령어로 httpd_sys_rw_content_t 가 부여되는 경로를 확인해 볼 수 있습니다.

Find entries user system_u and type bin_t within a file_contexts file, assuming that file_contexts is a file contexts file.

$ findcon -t httpd_sys_rw_content_t /etc/selinux/targeted/contexts/files/file_contexts

/etc/glpi(/.*)?	  	system_u:object_r:httpd_sys_rw_content_t:s0
/etc/drupal.*	  	system_u:object_r:httpd_sys_rw_content_t:s0
/var/lib/svn(/.*)?	  	system_u:object_r:httpd_sys_rw_content_t:s0
/var/www/svn(/.*)?	  	system_u:object_r:httpd_sys_rw_content_t:s0
/etc/owncloud(/.*)?	  	system_u:object_r:httpd_sys_rw_content_t:s0
/var/www/html(/.*)?/uploads(/.*)?	  	system_u:object_r:httpd_sys_rw_content_t:s0
/var/www/html(/.*)?/wp-content(/.*)?	  	system_u:object_r:httpd_sys_rw_content_t:s0
/var/www/html(/.*)?/wp_backups(/.*)?	  	system_u:object_r:httpd_sys_rw_content_t:s0
/var/www/html(/.*)?/sites/default/files(/.*)?	  	system_u:object_r:httpd_sys_rw_content_t:s0


TODO: svn, wp-content 진하게

정책 파일에서 일치하는 컨텍스트 출력

진하게 표시한 /var/www/svn(/.*)?  과 /var/www/html(/.*)?/wp-content 을 보면 정규식으로 폴더를 기술해 놓았으며 이는 /var/www/svn/myproj/var/www/html/wordpress-site/wp-content 와 일치합니다.

즉 위 경로에 서브버전 저장소를 만들거나 워드프레스 사이트를 구성할 경우 SELinux는 자동으로 해당 폴더에 웹 서버의 쓰기를 허용하므로 정책을 손대지 않고도 견고하게 편리하게 웹 서비스를 제공할 수 있습니다.