정책 유틸리티 사용
setools-console 패키지는 명령행에서 SELinux 의 보안 정책을 조회하고 다룰 수 있는 유틸리티의 묶음으로 사용법을 익혀두면 SELinux 의 동작에 대해서 더 자세히 이해할 수 있고 이를 통해 데몬 프로세스가 오작동할 때 문제 해결에 큰 도움이 되므로 익혀둘 필요가 있습니다.
사용하려면 먼저 다음 명령어로 패키지를 설치합니다.
$ sudo yum install setools-console
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
실행시 마지막 옵션으로 초 단위의 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 캐시 통계를 보여주므로 최초 출력보다 숫자가 작게 되며 -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 진하게
첫 줄의 의미는 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 ;
--direct(-d) 옵션은 -s 와 -t 로 지정한 컨텍스트 타입과 정확하게 일치하는 type 만 표시합니다.
출력 결과중 다음 내용의 의미는 httpd_t 컨텍스트가 지정된 프로세스는 http_port_t 타입의 udp 소켓에 bind 할 수 있다는 의미로 허용한 전체 정책을 합산하면 httpd_t 프로세스는 http_port_t 타입의 udp, tcp 에 bind 와 connect 를 할 수 있으므로 클라이언트로 해당 포트에 연결하거나 서버로 포트 리슨이 가능합니다.
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 진하게
첫 번째 allow 로 시작하는 라인의 출력의 의미는 다음과 같습니다.
- httpd_t 는 httpd_sys_content_t 가 설정된 파일에 대해 ioctl, read, getattr, lock, open system call 이 가능
풀어서 설명하면 httpd_t 는 httpd_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 를 진하게
위와 같이 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는 자동으로 해당 폴더에 웹 서버의 쓰기를 허용하므로 정책을 손대지 않고도 견고하게 편리하게 웹 서비스를 제공할 수 있습니다.