메뉴 건너뛰기

Hodol's Blog

Documents SELinux 개념

2015.04.20 16:21

Hodol 조회 수:1993

SELinux의 개념

목차
SELinux는 미국의 NSA(National Security Agency)에서 개발된 보안 프로그램이며 기존의 리눅스 환경에서 외부의 침입자가 루트 권한을 갖는 경우 모든 시스템이 크랙될 수 있는 위험성을 보완하기 위해서 만들어진 것이다. 사용자의 파일과 디렉토리, 프로세스에 대한 접근을 달리하여 시스템 데몬의 버그를 통해서 루트 권한을 획득하더라도 해당 데몬에서만 루트 권한을 행할 수 있을 뿐 다른 시스템의 루트 권한에는 제약을 두어 더 이상의 시스템 크랙이 불가능하도록 하여 시스템 보안을 향상시킨다. 커널 2.6에서 지원한다.
SELinux의 이해
어떤 주체(사용자, 프로그램, 프로세스)가 어느 객체(파일, 디바이스, 저장장치, 프린터, 메모리, CPU 등)에 접근하는 것을 통제하는 방법으로는 임의적 접근 통제(DAC, Discretionary Access Control)와 강제적 접근 통제(MAC, Mandatory Access Control)이 있다. 표준 리눅스 보안은 임의적 접근 통제 모델을 따르고 있는데 객체에 대한 접근 권한은 UID와 GID를 기반으로 하여 사용자의 파일허가 권한과 소유 권한을 통해서 이뤄지므로 setuidsetgid를 갖는 파일이나 루트 사용자로 객체에 접근하면 시스템에서 행해지는 어떠한 일(크래킹)을 막아내기 어려우며 시스템 전체에 걸쳐 보안 정책을 시행하도록 할 방법이 없는 문제점을 안고 있다. 강제적 접근 통제(MAC)은 어떤 주체가 어떤 객체에 접근하려 할 때 양자의 보안 정책에 따라 높은 보안을 요하는 정보가 낮은 보안 수준의 주체에게 노출 되지 않도록 접근을 제한한다. SELinux는 이러한 강제적 접근 통제를 커널에 적용하여 모든 주체(사용자, 프로세스)와 객체를 제어할 수 있게 해준다. SELinux 환경에서는 운영체제의 모든 성분들이 어떤 일을 할 수 있고 할 수 없는지에 대한 보안 정책을 시행시켜, 보안 취약점이 있거나 악의적인 의도를 가진 응용 프로그램으로 크래커가 시스템을 마음대로 할 수 없도록 하여 시스템의 접근 보안을 향상시켜 줄 수 있다.
SELinux는 유형 시행(Type Enforcement (TE)) 보안 모델을 기초로 하여 역할 기반 접근 제어(Role-Based Access Control (RBAC)) 보안 모델을 사용하여 구현된다. TE 모델에서는 객체는 유형(type)이라는 보안 속성을 갖으며, 주체는 영역(domain) 이라는 보안 속성을 가지게 되어, 영역을 기반으로 하여 주체는 객체에 접근하게 된다. 역할 기반 접근 제어에서는 TE에 의해서 제공된 각각의 역할을 통해서 접근을 제어하게 된다.
SELinux의 용어 이해
SELinux에서는 identity, 영역(domain), 유형(type), 역할(role), 보안 문맥(security context), 전이(transition), 정책(policy) 등의 용어를 많이 사용하는데 이들 용어에 대한 개념을 이해하는 것이 SELinux를 이해하는데 도움이 될 것이다.
identity
/etc/passwd 파일에 있는 사용자 ID(UID)와 동일하지만 보안 속성을 갖는 문맥을 이루고 있다는 점에서 다르다. id 명령을 실행 하였을 때 context로 SELinux 환경에서는 사용자는 user_u와 같은 보안 속성을 지님을 볼 수 있다. 이와 같이 SElinux의 identity는 앞으로 살펴보게 될 역할과 유형과 함께 보안 문맥(security context)를 형성한다.
역할(role)
역할은 어떤 영역이 이용될 것인가를 결정한다. 사용자 역할이 접근할 수 있는 영역들은 정책 설정 파일에 의해서 미리 정의되어 있다. 역할은 영역에 포함되도록 신뢰되지 않았다면 거부될 것이다. 예를 들어 user_t영역을 가진 사용자가 passwd 명령을 실행할 수 있도록 하기 위해서는 관련 설정 파일에서 다음과 같이 명시해 주어야 한다.
role user_t types user_passwd_t
이것은 사용자 역할(user_r)에서 사용자가 user_passwd_t 영역에 포함되도록 하여 passwd 명령을 실행할 수 있게 해 주는 것이다.
영역(domain)
모든 프로세스는 영역내에서 동작하게 된다. 영역은 프로세스에게 어떠한 접근을 가질 것인가를 결정한다. 영역을 프로세스가 무엇을 할 수 있고 유형에 따라서 프로세스가 어떤 행동을 취할 수 있도록 할 것인가 하는 목록이다. 리눅스의 uid와 같이 영역을 생각해 본다면 루트는 프로그램을 가지며 그 프로그램은 4777의 접근 권한을 가지고 있다면 그 시스템에서는 누구나 루느 권한을 가지게 되어 보안 문제가 발생할 수 있겠지만, SELinux에서는 특권 영역으로 도메인을 옮기는 프로세스를 가지고 있거나 프로세스의 역할이 특정 영역에 들어가도록 신뢰하지 않는다면 그 프로그램을 실행할 수 없게 된다. 예를 들어, sysadm_t는 시스템 관리 영역이며, user_t는 일반적인 비특권 사용자의 영역이며, initinit_t영역에서 동작하며, namednamed_t 영역에서 작동한다.
유형(type)
객체에 주어진 보안 속성으로 그 객체에 어떤 주체가 접근할 수 있는지를 결정한다. 영역은 프로세스에 적용되고 유형은 디렉토리, 파일, 소켓 등의 객체에 적용된다는 점을 제외하고는 영역에 대한 정의와 같다. 영역과 유형의 보안 속성은 일반적으로 sysadm_t와 같이 마지막에 _t로 표시된다.
보안 문맥(security context)
파일, 디렉토리, TCP 소켓 등과 연관되어 있는 모든 속성을 가진다. 보안 문맥은 다음과 같이 identity, 역할과 영역 또는 유형으로 구성된다.
identity:role:domain 또는 identity:role:type SELinux 환경하에서 id -Z 또는 id --context 명령을 실행하므로써 현재의 보안 문맥을 볼 수 있다.
$ id -Z
user_u:system_r:unconfined_t
아이덴티티 문맥(Identity Context)
사용자 또는 프로세스 등의 보안 속성으로 보안 문맥 구조에서 첫 번째 문맥을 이루며 사용자의 문맥으로는 user_u 또는 root 등이 있다. 사용자가 su 명령으로 루트 권한을 가질 때 사용자 문맥은 user_u에서 root로 변경 된다. 예를 들어, user_u 문맥을 갖는 Fedora 사용자가 su 명령으로 루트 권한을 획득하였을 때 루트 사용자 문맥을 가지게 된다.
$ id -Z
user_u:system_r:unconfined_t
$ su -
password :
$ id -Z
root:system_r:unconfined_t
프로세스 문맥(Process Context)는 ps axZ 명령으로 확인할 수 있다.
$ ps axZ | grep init
user_u:system_r:unconfined_t 1 ? S 0:01 init [5]
프로세스를 어떤 사용자의 소유권으로 작동시켰는가에 따라서 문맥 형태도 달리 표현될 것이다. root 사용자가 직접 프로세스를 실행하였다면 root 사용자의 문맥으로 표시될 것이며 일반 사용자로 프로세스가 실행되었다면 user_u로 표시될 것이다.
객체 문맥(Object Context)
두 번째 보안 문맥을 이루는 문맥으로 파일, 디렉토리, 소켓, 디바이스 등의 객체에 대해서 object_r과 같은 문맥으로 표시된다. 디렉토리나 파일에 대해서 ls -Z 명령을 실행하면 객체 문맥 형태를 볼 수 있다.
$ ls -lZ /home
drwx------ kdj kdj system_u:object_r:user_home_dir_t kdj
drwx------ fedora fedora root:object_r:user_home_dir_t fedora
$ ls -Z /etc/passwd
-rw-r--r-- root root system_u:object_r:etc_t /etc/passwd
$
영역/유형 문맥(domain/type context)
마지막 보안 문맥 구조에서 주체와 객체에 따라서 갖는 문맥 형태는 달라진다. 프로세스들은 영역을 가지며, 파일, 디렉토리, 소켓 등과 같은 객체는 유형을 가지게 됩니다. 그러나 영역이나 유형 문맥들은 마지막에 모두 _t 접미사가 붙는다.
$ ps axZ | grep squid
root:system_r:squid_t 4323 ? Ss 0:01 squid -D
$ ls -Z /home
drwx------ kdj kdj system_u:object_r:user_home_dir_t kdj
예제 화면에서 squid 데몬은 root 아이덴티티와 system_r 역할(role)으로 squid_t 영역의 정책 하에서 동작하는 것으로 SELinux의 목표 정책(targeted policy)이 적용되며 이 정책 하에 프로세스의 접근이 제어된다. 그러나 정책에 적용되지 않는 프로세스의 경우에는 무제한 영역 unconfined_t 문맥으로 표시되어진다.
SELinux 정책(policies)
SELinux 정책은 사용자, 프로그램, 프로세스 등의 주체와 이들의 동작 대상인 파일과 디바이스를 포함한 시스템의 모든 객체에 대한 접근 허가를 정의하는 것을 말한다. 정책들은 다음 패키지를 설치하므로써 /etc/selinux/정책이름/src/policy 디렉토리에서 찾아볼 수 있다.
apt-get install selinux-policy-strict selinux-policy-strict-sources
apt-get install selinux-policy-targeted selinux-policy-targeted-sources
목표 정책(targeted policy)
SELinux가 활성화되어 있든 그렇지 않든 간에 마치 시스템이 표준 리눅스 보안 모델로 작동되도록 허용해 주는 정책으로 대부분의 프로세스는 SELinux의 정책에 제한받지 않고 표준 리눅스 보안에 따라 제어되도록 하고 일부 프로세스에 대해서만 SELinux의 정책으로 접근을 제어하는 것이다. 현재 이 정책에 영향을 받는 데몬으로는 hdcpd, httpd, mysqld, named, portmap, squid, syslogd, udev 등이 있으며 이들 데몬에 대한 정책 파일은 /etc/selinux/targeted/src/policy/domains/program 디렉토리에 찾아 볼수 있다.
엄격 정책(strict policy)
엄격한 정책을 통해서 각 프로세스에 대한 접근을 엄격하게 제어하는 것으로 이 정책으로 시스템을 운영하는 데는 상당한 제약이 많기 때문에 SELinux에 대한 전문적인 지식과 충분한 이해가 없다면 이 정책 사용을 신중하게 고려해야 한다.
기타 관련 명령어
  • setenforce 명령은 SELinux를 시작시키거나 중지시킨다.
  • restorecon 명령은 보안 문맥을 기본값으로 복원한다.
  • chcon 명령은 보안 문맥을 수정한다.
  • setsebool 명령은 SELinux의 각 정책을 시작시키거나 중지시킨다.
  • sealert 명령은 발생한 보안 문제들의 로그를 보여주고 해결 방법을 제공한다.
  • semodule 명령은 사용자가 임으로 만든 보안 정책을 설치하여 실행하거나 중지한다.
간단한 문제 해결 예제
서버를 설치하고 웹 서비스를 시작할 때 만나는 403 퍼미션 에러가 발생했다고 가정하자.
  • tail 명령으로 /var/log/message에 남은 에러 메세지를 확인한다.
    # tail /var/log/messages

    Jun 17 13:59:42 centos setroubleshoot: SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/test.html.
    For complete SELinux messages. run sealert -l 0f03538b-feb4-4ddc-a2ba-30e97bc4b6c9
  • 로그에서 시키는 대로 sealert 실행한다.
    # sealert -l 0f03538b-feb4-4ddc-a2ba-30e97bc4b6c9

    SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/test.html.

    ***** Plugin restorecon (99.5 confidence) suggests *************************
    If you want to fix the label.
    /var/www/html/test.html default label should be httpd_sys_content_t.
    Then you can run restorecon.
    Do
    # /sbin/restorecon -v /var/www/html/test.html
  • 마지막 줄의 resorecon 명령을 실행하여 문제를 해결한다.
    # /sbin/restorecon -v /var/www/html/test.html