SELinux(Security-Enhanced Linux)
2025-10-26, G25DR
1. 서론
SELinux(Security-Enhanced Linux)는 리눅스 커널에 통합된 강력한 강제적 접근 제어(Mandatory Access Control, MAC) 보안 아키텍처이다.1 이는 단순한 부가 기능이 아니라, 시스템의 모든 주체(Subject, 예: 프로세스)와 객체(Object, 예: 파일, 디렉터리, 네트워크 포트) 간의 모든 상호작용을 사전에 정의된 보안 정책에 따라 엄격하게 통제하는 포괄적인 보안 프레임워크로 정의된다.3 현대 리눅스 시스템에서 SELinux는 운영체제의 최후 방어선 역할을 수행하며, 알려지지 않은 취약점이나 잘못된 설정으로 인한 피해를 최소화하는 핵심적인 역할을 담당한다.
SELinux의 개발 배경은 미국 국가안보국(National Security Agency, NSA)으로 거슬러 올라간다.5 NSA는 정부 및 군사 기관에서 요구하는 고도의 보안 수준을 충족시키기 위해 이 기술을 개발하였다. 초기 개발 이후 2000년에 오픈소스 커뮤니티에 코드를 공개하였고, 광범위한 검토와 기여를 거쳐 2003년 리눅스 커널 2.6 버전에 공식적으로 통합되었다.3 NSA가 개발 주체라는 점 때문에 초기에 백도어(backdoor)에 대한 의혹이 제기되기도 했으나, 바이너리가 아닌 전체 소스 코드가 공개되었기 때문에 전 세계 개발자들의 검증을 통해 이러한 우려는 해소되었다.5
SELinux의 등장은 기존 유닉스 및 리눅스 시스템이 채택해 온 임의적 접근 제어(Discretionary Access Control, DAC) 모델의 본질적인 한계에서 비롯되었다.2 전통적인 DAC 모델은 파일이나 디렉터리의 소유자(Owner), 그룹(Group), 그리고 그 외 사용자(Other)에게 부여된 읽기(r), 쓰기(w), 실행(x) 권한에 기반한다. 이 모델의 가장 큰 취약점은 시스템의 모든 권한을 가진 ‘루트(root)’ 슈퍼유저의 존재이다. 루트 계정은 단일 실패 지점(Single Point of Failure)으로 작용하여, 만약 공격자가 데몬 프로세스의 취약점이나 잘못된 설정 등을 통해 루트 권한을 탈취하게 되면 시스템 전체가 완전히 장악되는 치명적인 결과를 초래한다.5 SELinux는 바로 이 문제를 해결하기 위해 루트조차도 보안 정책의 통제를 받도록 설계된, 근본적으로 다른 보안 패러다임을 제시한다.
2. SELinux의 구조와 핵심 원리
2.1 강제적 접근 제어(MAC)의 구현체: 패러다임의 전환
SELinux의 핵심은 강제적 접근 제어(MAC)를 구현한 것이다. 이는 기존의 임의적 접근 제어(DAC)와는 근본적으로 다른 철학에 기반하며, 시스템 보안의 패러다임을 전환시켰다.
2.1.1 임의적 접근 제어(DAC)와의 심층 비교 분석
전통적인 리눅스 시스템의 보안 모델인 DAC는 접근 제어에 대한 결정 권한이 객체의 소유자에게 위임된 ’임의적’인 방식이다. 예를 들어, 사용자는 chmod 명령어를 사용하여 자신이 소유한 파일의 접근 권한을 다른 사용자에게 자유롭게 부여하거나 제한할 수 있다.6 이러한 방식은 유연하고 직관적이지만, 보안 관점에서는 심각한 약점을 내포한다. 특정 프로세스가 악성코드에 감염되거나 취약점을 통해 권한을 탈취당했을 경우, 공격자는 해당 프로세스가 실행된 사용자의 권한을 그대로 획득하여 그 사용자가 접근할 수 있는 모든 파일과 리소스에 접근할 수 있게 된다.9
반면, MAC은 시스템 관리자가 중앙에서 정의한 ‘강제적인’ 보안 정책에 따라 모든 접근 시도를 통제하는 모델이다.2 SELinux 환경에서는 파일의 소유자라 할지라도, 중앙 보안 정책이 허용하지 않는 접근은 원천적으로 불가능하다. 예를 들어, 한 사용자가 자신의 홈 디렉터리에 있는 파일을 chmod 777로 설정하여 모든 사용자에게 모든 권한을 부여했더라도, SELinux 정책이 웹 서버 프로세스(httpd)가 사용자 홈 디렉터리에 접근하는 것을 금지하고 있다면 웹 서버는 해당 파일에 접근할 수 없다. 이처럼 SELinux는 기존의 DAC 규칙이 적용된 이후에 추가적인 보안 검사를 수행하는 강력한 보안 계층으로 작동한다. 즉, DAC 규칙에서 접근이 거부되면 SELinux 검사는 수행되지 않으며, DAC에서 허용되더라도 SELinux 정책이 최종적으로 접근을 거부할 수 있다.7
2.1.2 루트 권한의 재해석: 슈퍼유저 권한의 분리와 제한
SELinux가 가져온 가장 혁신적인 변화 중 하나는 전통적인 ‘슈퍼유저’ 개념을 재해석한 것이다. DAC 환경에서 루트 사용자는 신과 같은 존재로, 시스템의 모든 파일과 프로세스에 대한 무제한적인 접근 권한을 가졌다. 이것이 바로 전통적 리눅스 보안의 아킬레스건이었다.5
SELinux는 루트 사용자조차도 보안 정책의 제약을 받도록 설계되었다. 이는 시스템 전체에 최소 권한 원칙(Principle of Least Privilege)을 일관되게 적용한 결과다.4 예를 들어, Apache 웹 서버(httpd) 데몬은 80번이나 443번과 같은 1024번 이하의 잘 알려진 포트(well-known port)에 바인딩(binding)하기 위해 전통적으로 루트 권한으로 시작해야만 했다.5 하지만 SELinux 환경에서는 httpd 프로세스가 설령 루트 권한으로 실행되더라도, httpd_t라는 특정 도메인(domain) 내에서만 활동하도록 엄격히 제한된다. 이 도메인에 할당된 정책은 웹 콘텐츠 파일 읽기, 특정 포트 바인딩 등 웹 서버 운영에 필수적인 최소한의 작업만을 허용한다. 따라서 공격자가 httpd 프로세스의 제어권을 탈취하더라도, 시스템의 핵심 설정 파일인 /etc/shadow나 데이터베이스 파일에는 접근할 수 없게 된다.13 이처럼 SELinux는 루트 권한을 가졌더라도 그 권한을 사용할 수 있는 범위를 극도로 제한함으로써, 권한 상승 공격(privilege escalation attack)으로 인한 피해를 극적으로 감소시킨다.14
2.2 SELinux 아키텍처
SELinux는 리눅스 커널 내부에 정교하게 통합되어 작동하며, 주요 구성 요소는 다음과 같다.
2.2.1 리눅스 보안 모듈(LSM) 프레임워크
SELinux는 리눅스 커널 소스 코드를 직접 수정하는 방식이 아니라, 커널 2.6 버전부터 도입된 리눅스 보안 모듈(Linux Security Module, LSM) 프레임워크를 통해 구현된다.2 LSM은 커널의 주요 지점, 예를 들어 파일 열기, 프로세스 생성, 소켓 연결과 같은 시스템 콜(system call)이 호출될 때마다 보안 모듈이 결정을 내릴 수 있도록 하는 ’훅(hook)’을 제공한다. SELinux는 이 LSM 훅에 등록되어, 모든 중요한 커널 수준의 접근 요청을 가로채서 자신의 보안 정책에 따라 허용 여부를 결정한다. 이 구조 덕분에 SELinux는 커널의 핵심 기능과 분리되어 독립적으로 개발 및 유지보수가 가능하다.
2.2.2 보안 정책 데이터베이스와 보안 서버
시스템의 모든 접근 제어 규칙은 컴파일된 형태의 바이너리 파일로 존재하며, 일반적으로 /etc/selinux/targeted/policy/ 디렉터리 내에 저장된다. 시스템이 부팅될 때 이 정책 파일이 커널 메모리로 로드된다. 커널 내부에 존재하는 ’보안 서버(Security Server)’는 LSM 훅으로부터 전달받은 접근 요청을 로드된 정책 데이터베이스와 비교하여 최종적으로 접근을 허용할지, 거부할지를 결정하는 역할을 수행한다.2
2.2.3 성능 최적화를 위한 접근 벡터 캐시(AVC)
모든 접근 요청이 발생할 때마다 매번 복잡한 정책 데이터베이스 전체를 조회하는 것은 상당한 성능 부하를 유발할 수 있다. 이러한 오버헤드를 최소화하기 위해 SELinux는 접근 벡터 캐시(Access Vector Cache, AVC)라는 메커니즘을 사용한다.2 AVC는 보안 서버가 한 번 내린 접근 결정(예: ‘httpd_t 프로세스는 httpd_sys_content_t 파일을 읽을 수 있다’)을 메모리에 캐싱한다. 이후 동일한 유형의 접근 요청이 발생하면, 정책 데이터베이스를 다시 조회하는 대신 AVC에 캐시된 결과를 즉시 반환하여 처리 속도를 크게 향상시킨다.16 이 덕분에 SELinux는 강력한 보안을 제공하면서도 시스템 성능에 미치는 영향을 최소화할 수 있다.
2.3 보안 컨텍스트(Security Context): 모든 객체의 보안 식별자
SELinux의 정책 결정은 ’보안 컨텍스트(Security Context)’라는 핵심 개념을 기반으로 이루어진다. 이는 SELinux가 시스템의 모든 프로세스(주체)와 파일, 디렉터리, 포트 등 모든 리소스(객체)에 부여하는 고유한 보안 레이블이다.2 이 컨텍스트 정보는 접근 권한을 확인하는 데 사용되는 핵심 식별자 역할을 한다.
보안 컨텍스트는 사용자:역할:타입:레벨이라는 네 가지 필드로 구성된 문자열 형태를 가진다.15
2.3.1 구성 요소 심층 분석
-
사용자(User): 이는
/etc/passwd에 정의된 리눅스 시스템 사용자(UID)와는 완전히 별개의 개념인 SELinux 사용자다.16 정책 내에서 특정 역할(Role)과 레벨(Level)에 대한 권한을 정의하는 데 사용된다. 예를 들어, 일반 사용자는unconfined_u컨텍스트에, 시스템 서비스는system_u컨텍스트에 매핑될 수 있다.18 -
역할(Role): 역할 기반 접근 제어(Role-Based Access Control, RBAC)를 구현하기 위한 요소다.15 역할은 특정 SELinux 사용자가 수행할 수 있는 작업의 집합을 정의하며, 접근 가능한 타입(도메인)의 범위를 결정한다.16 예를 들어, 시스템 프로세스는
system_r역할을, 파일과 같은 객체는object_r역할을 부여받는 것이 일반적이다.18 -
타입(Type): 보안 컨텍스트의 네 가지 구성 요소 중 가장 중요하고 핵심적인 요소다.12 프로세스에 적용될 때는 특별히 **도메인(Domain)**이라고 부른다. SELinux 정책의 거의 모든 규칙은 타입 강제(Type Enforcement, TE) 규칙으로, ’어떤 타입(도메인)을 가진 주체가 어떤 타입을 가진 객체에 대해 어떤 작업을 수행할 수 있는가’를 정의한다.15 예를 들어,
httpd_t라는 도메인에서 실행되는 웹 서버 프로세스는httpd_sys_content_t라는 타입을 가진 파일에 대해서만 접근이 허용되고,mysqld_db_t타입을 가진 데이터베이스 파일에는 접근이 거부된다.10 -
레벨(Level): 이는 선택적 필드로, 주로 다중 레벨 보안(Multi-Level Security, MLS) 및 다중 카테고리 보안(Multi-Category Security, MCS)을 구현하기 위해 사용된다.16 군사나 정부 기관에서 정보의 민감도(예: Top Secret, Secret, Unclassified)를 구분하고, ’상위 등급은 하위 등급을 읽을 수 있지만, 하위 등급은 상위 등급에 쓸 수 없다’와 같은 엄격한 정보 흐름을 제어하는 데 활용된다.
이처럼 SELinux는 단순히 ‘누가(who)’ 접근하는지에 초점을 맞추는 DAC와 달리, ‘무엇이(what)’ ‘무엇을(what)’ 가지고 ‘어떻게(how)’ 상호작용하는지를 타입(Type)을 통해 정의한다. 이는 시스템의 각 구성 요소가 수행해야 할 ’정상적인 역할과 의도’를 보안 정책으로 명문화하는 것과 같다. 따라서 SELinux 정책 위반(denial)이 발생했다는 것은 단순한 권한 오류가 아니라, 시스템의 ’설계된 의도’에서 벗어나는 비정상적인 행위가 발생했다는 강력한 신호로 해석될 수 있다. 이는 보안 침해뿐만 아니라 시스템의 잘못된 설정이나 애플리케이션의 버그를 탐지하는 데에도 매우 유용하게 활용될 수 있다.4
또한, 보안 컨텍스트, 특히 ’타입’의 사용은 커널 수준에서 일종의 ‘객체 지향’ 개념을 도입한 것으로 볼 수 있다. 전통적인 보안 모델이 파일 경로와 같은 구체적인 식별자에 의존하는 것과 달리 24, SELinux는 모든 객체에 ’타입’이라는 추상화된 클래스(class)를 부여한다. 예를 들어, httpd_sys_content_t는 ’웹 콘텐츠 파일’이라는 하나의 클래스를 의미한다.12 정책은 /var/www/html과 같은 구체적인 파일 경로가 아닌, 이 추상화된 ’타입’을 기준으로 작성된다. 따라서 웹 콘텐츠가 어떤 경로에 위치하든 httpd_sys_content_t 타입으로 레이블링되어 있다면 동일한 정책의 적용을 받는다. 이러한 추상화는 보안 정책을 시스템의 물리적 구조 변화에 강인하고, 이식성 있으며, 일관성 있게 만들어준다. 이는 복잡한 현대 시스템의 보안을 효과적으로 관리하기 위한 핵심적인 설계 철학이다.2
2.3.2 보안 컨텍스트 확인 방법
시스템 관리자는 다양한 명령어를 통해 각 리소스의 보안 컨텍스트를 확인할 수 있다.
- 파일 및 디렉터리:
ls -Z명령어를 사용한다.13
Bash
$ ls -Z /var/www/html
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html
- 프로세스:
ps -eZ또는ps auxZ명령어를 사용한다.16
Bash
$ ps -eZ | grep httpd
system_u:system_r:httpd_t:s0 1234? 00:00:01 httpd
- 네트워크 포트:
netstat -Z또는 최신 시스템에서는ss -Z명령어를 사용한다.27
Bash
$ ss -Ztlp | grep httpd
LISTEN 0 128 *:http *:* users:(("httpd",pid=1234,fd=4))
Table 1: DAC vs. MAC 비교
| 구분 | 임의적 접근 제어 (DAC) | 강제적 접근 제어 (MAC) - SELinux |
|---|---|---|
| 제어 주체 | 객체(파일, 디렉터리)의 소유자 | 시스템 관리자가 정의한 중앙 보안 정책 |
| 제어 단위 | 사용자 ID (UID), 그룹 ID (GID) | 보안 컨텍스트 (특히 ‘타입’) |
| 정책 결정자 | 소유자가 임의로 결정 가능 | 중앙 정책에 의해 강제됨 (소유자도 변경 불가) |
| 기본 철학 | “허용 우선 (Default-Allow)” - 명시적으로 금지되지 않으면 허용 | “거부 우선 (Default-Deny)” - 명시적으로 허용되지 않으면 거부 |
| 대표 명령어 | chmod, chown | chcon, semanage, restorecon |
| 보안 강도 | 낮음 | 높음 |
| 주요 취약점 | 루트 권한 탈취, 사용자 실수, 악성코드 감염 시 해당 사용자 권한으로 시스템 접근 가능 | 복잡한 정책 관리, 잘못된 정책 설정 시 서비스 장애 발생 가능 |
3. SELinux의 작동 방식과 정책 관리
SELinux를 효과적으로 운영하기 위해서는 작동 모드에 대한 이해와 정책 관리 방법에 대한 숙지가 필수적이다.
3.1 작동 모드: Enforcing, Permissive, Disabled
SELinux는 시스템의 요구사항과 운영 단계에 따라 세 가지 주요 작동 모드 중 하나로 설정될 수 있다. 이 모드들은 단순히 보안을 켜고 끄는 스위치가 아니라, 정책의 전체 생명주기를 관리하기 위한 핵심적인 도구다.
3.1.1 각 모드의 특징 및 장단점
-
Enforcing (강제 모드): 이 모드에서 SELinux는 활성화된 보안 정책을 시스템에 실제로 강제 적용한다.1 정책에 위배되는 모든 접근 시도는 차단되며, 해당 위반 사실은 감사 로그(
/var/log/audit/audit.log)에 기록된다.28 이는 실제 운영 중인 프로덕션(production) 환경에서 권장되는 기본 모드로, 시스템에 대한 최고 수준의 보호를 제공한다.30 -
Permissive (허용 모드): 이 모드에서 SELinux는 정책을 강제하지 않는다. 즉, 정책에 위배되는 행위가 발생하더라도 차단하지 않고 허용한다.1 하지만 마치 Enforcing 모드인 것처럼 모든 정책 위반 사항을 감사 로그에 상세히 기록한다.28 이 특징 덕분에 Permissive 모드는 새로운 정책을 개발하거나, 기존 정책을 디버깅하고, 시스템 문제를 해결하는 단계에서 매우 유용하다. 실제 서비스를 중단시키지 않으면서 애플리케이션이 어떤 권한을 필요로 하는지 파악하고 잠재적인 정책 충돌을 분석할 수 있다.30
-
Disabled (비활성화 모드): 이 모드에서는 SELinux가 커널 수준에서 완전히 비활성화된다.1 SELinux 관련 커널 모듈이 로드되지 않으며, 파일 시스템에 보안 컨텍스트 레이블을 지정하는 작업도 수행되지 않는다. 보안상의 모든 이점을 포기하는 것이므로 극히 예외적인 경우를 제외하고는 절대 권장되지 않는다.34 Disabled 모드에서 다시 Enforcing이나 Permissive 모드로 전환하려면 시스템 재부팅이 필수적이며, 부팅 과정에서 전체 파일 시스템에 대해 리레이블링(relabeling) 작업을 수행해야 하므로 시스템 규모에 따라 상당한 시간이 소요될 수 있다.35
많은 관리자들이 SELinux를 ‘켜거나(Enforcing)’ ‘끄는(Disabled)’ 이분법적 개념으로 접근하지만, Permissive 모드의 존재는 SELinux가 단순한 차단 메커니즘을 넘어 정교한 관리 도구임을 시사한다. 이상적인 SELinux 운영 워크플로우는 Permissive (개발/분석) -> Enforcing (배포/운영)의 순환적인 생명주기를 따른다. 새로운 애플리케이션을 배포할 때, 먼저 Permissive 모드에서 실행하여 필요한 모든 접근 권한을 로그로 수집하고, 이를 바탕으로 안전한 정책을 수립한 후 Enforcing 모드로 전환하는 것이 정석적인 접근 방식이다.32
3.1.2 환경별 운영 전략
-
개발/테스트 환경: 새로운 애플리케이션을 개발하거나 시스템 설정을 변경할 때는
Permissive모드를 활용하는 것이 좋다. 이를 통해 애플리케이션의 정상 작동에 필요한 권한을 시스템 중단 없이 파악하고, 감사 로그를 분석하여 맞춤형 정책을 개발할 수 있다.32 -
스테이징 환경: 프로덕션 환경으로 배포하기 전,
Enforcing모드로 전환하여 실제 운영 환경과 동일한 조건에서 최종 테스트를 수행해야 한다. 이 단계에서 예상치 못한 정책 위반이 발생하는지 면밀히 모니터링하고 정책을 최종적으로 다듬는다. -
프로덕션 환경: 모든 운영 서버는 반드시
Enforcing모드로 운영하여 시스템을 잠재적인 위협으로부터 보호해야 한다.32
3.1.3 모드 변경 방법
-
실시간 변경 (일시적):
setenforce명령어를 사용하면 시스템을 재부팅하지 않고 즉시 모드를 변경할 수 있다.setenforce 1은 Enforcing 모드로,setenforce 0은 Permissive 모드로 전환한다. 이 변경 사항은 시스템이 재부팅되면 초기화된다.2 현재 모드는getenforce명령어로 확인할 수 있다.8 -
영구 변경 (재부팅 필요): 시스템 재부팅 후에도 모드를 유지하려면
/etc/selinux/config설정 파일을 직접 수정해야 한다. 파일 내의SELINUX지시어 값을enforcing,permissive, 또는disabled로 변경한 후 시스템을 재부팅하면 해당 설정이 영구적으로 적용된다.28
3.2 SELinux 정책의 이해
SELinux의 모든 동작은 사전에 정의된 ’정책(Policy)’에 의해 결정된다. 이 정책은 시스템의 보안을 정의하는 규칙의 집합이다.
3.2.1 “Default-Deny” 원칙
SELinux 정책의 가장 근본적인 철학은 “명시적으로 허용된 것이 아니면 모든 것은 거부된다(Default-Deny)“는 것이다.4 이는 시스템의 공격 표면(attack surface)을 근본적으로 최소화하는 매우 강력한 보안 원칙이다. 전통적인 DAC 환경에서는 실수로 과도한 권한을 부여하기 쉽지만, SELinux에서는 필요한 접근 권한을 하나씩 명시적으로 허용해야만 시스템이 작동한다.14
3.2.2 타겟(Targeted) 정책
Red Hat Enterprise Linux(RHEL)나 CentOS와 같은 주요 배포판에서 기본으로 제공하는 정책은 ’타겟(Targeted) 정책’이다.13 이 정책은 이름 그대로 시스템의 모든 프로세스를 동일하게 통제하는 대신, 외부에 노출되어 공격받기 쉬운 특정 네트워크 서비스(예: httpd, mysqld, sshd, named 등)를 주된 통제 대상으로 삼는다. 이러한 ‘제한된(confined)’ 프로세스들은 매우 엄격한 규칙의 적용을 받는 반면, 일반 사용자가 셸에서 실행하는 대부분의 프로세스는 unconfined_t라는 ‘제한되지 않은(unconfined)’ 도메인에서 실행된다.8 이 도메인은 최소한의 SELinux 제약만을 적용받아, 사용자가 기존 리눅스 환경과 거의 차이 없이 시스템을 사용할 수 있도록 편의성을 제공한다. 이처럼 타겟 정책은 시스템의 보안성과 사용성 사이의 현실적인 균형을 맞추기 위해 설계되었다.
3.2.3 부울(Boolean)을 통한 동적 정책 제어
SELinux 부울(Boolean)은 정책의 특정 규칙들을 동적으로 켜고 끌 수 있는 일종의 스위치다.10 복잡한 정책 소스 코드를 직접 수정하고 다시 컴파일하지 않고도, 관리자가 간단한 명령어로 시스템의 보안 동작을 변경할 수 있게 해준다.28
-
부울 목록 확인:
getsebool -a명령어로 시스템에 정의된 모든 부울과 현재 상태(on/off)를 확인할 수 있다.8 -
부울 상태 변경:
setsebool명령어로 부울의 상태를 변경한다.-P옵션을 추가하면 변경 사항이 시스템 재부팅 후에도 유지된다.8 -
사용 예시: 기본적으로 웹 서버(
httpd)는 보안상의 이유로 원격 데이터베이스에 네트워크로 연결할 수 없도록 설정되어 있다. 만약 웹 애플리케이션이 외부 DB 서버에 접속해야 한다면, 관리자는 다음 명령어를 실행하여 해당 기능을 활성화할 수 있다.
Bash
# setsebool -P httpd_can_network_connect_db on
이처럼 부울은 일반적인 시나리오에 맞춰 미리 정의된 정책 옵션을 제공하여 정책 관리를 훨씬 용이하게 만든다.10
3.3 파일 시스템 레이블링 관리
파일이나 디렉터리를 생성하거나 이동할 때, 혹은 서비스의 기본 경로를 변경할 때 올바른 보안 컨텍스트를 유지하는 것은 SELinux 운영의 핵심 과제다.
3.3.1 chcon (Change Context)
chcon 명령어는 파일이나 디렉터리의 보안 컨텍스트를 임시로 변경하는 데 사용된다.8 이 변경은 즉시 적용되지만, 파일 시스템 정책에 영구적으로 기록되는 것이 아니므로 시스템이 재부팅되거나 restorecon 명령어가 실행되면 정책에 정의된 기본값으로 되돌아간다.40 빠른 테스트나 문제 해결을 위한 임시 조치에 유용하다.
Bash
# chcon -t httpd_sys_content_t /srv/www/index.html
3.3.2 semanage fcontext & restorecon
보안 컨텍스트를 영구적으로 관리하기 위해서는 semanage fcontext와 restorecon 두 명령어를 조합하여 사용해야 한다. 이 방식은 SELinux가 ’상태(State)’가 아닌 ‘정책(Policy)’ 기반 시스템임을 보여주는 핵심적인 증거다. chcon이 파일의 현재 ’상태’를 바꾸는 행위라면, restorecon은 중앙에 정의된 ’정책’을 기준으로 파일의 현재 ’상태’를 강제로 교정하는 역할을 한다. 이는 시스템의 모든 객체 레이블이 중앙 정책이라는 ’진리의 원천(Source of Truth)’에 의해 통제됨을 의미하며, 관리자의 실수나 잘못된 파일 작업으로 인해 발생할 수 있는 레이블 불일치 문제를 언제든지 정책 기준으로 바로잡을 수 있는 강력한 무결성 보장 메커니즘을 제공한다.36
semanage fcontext로 정책 정의:semanage fcontext명령어는 특정 파일 경로 패턴에 대한 기본 보안 컨텍스트를 SELinux 정책 데이터베이스에 영구적으로 추가하거나 수정한다.4
-a옵션은 새로운 규칙을 추가하고,-t옵션은 적용할 타입을 지정한다. 경로는 정규 표현식을 지원한다.
restorecon으로 정책 적용:restorecon명령어는 지정된 경로의 파일 및 디렉터리를 스캔하여, 현재 보안 컨텍스트가semanage fcontext로 정의된 정책과 일치하지 않을 경우 이를 정책 기본값으로 복원한다.4
-
-R옵션은 지정된 디렉터리와 그 하위 모든 파일/디렉터리에 재귀적으로 적용된다. -
-v옵션은 변경되는 컨텍스트를 화면에 출력하여 작업 내용을 확인할 수 있게 한다.
통합 사용 시나리오:
웹 서버의 기본 문서 루트 디렉터리를 /var/www/html에서 /web-data로 변경했다고 가정하자. 이 경우, 새로 생성된 /web-data 디렉터리와 그 안의 파일들은 기본적으로 default_t 또는 var_t와 같은 컨텍스트를 가지게 되어 httpd_t 도메인이 접근할 수 없다. 이를 해결하기 위한 올바른 절차는 다음과 같다.
- 먼저,
/web-data디렉터리와 그 하위 모든 내용((/.*)?)의 기본 타입을httpd_sys_content_t로 지정하는 정책을 추가한다.
Bash
# semanage fcontext -a -t httpd_sys_content_t "/web-data(/.*)?"
- 다음으로,
restorecon명령어를 실행하여 방금 정의한 정책을 실제 파일 시스템에 적용한다.
Bash
# restorecon -R -v /web-data
이 두 단계를 거치면 /web-data 디렉터리의 컨텍스트가 영구적으로 변경되어 웹 서버가 정상적으로 파일을 서비스할 수 있게 된다.
Table 2: SELinux 작동 모드별 특징 및 권장 사용 사례
| 구분 | Enforcing (강제) | Permissive (허용) | Disabled (비활성) |
|---|---|---|---|
| 정책 강제 여부 | 예 (접근 차단) | 아니요 (접근 허용) | 아니요 (SELinux 미작동) |
| 로그 기록 여부 | 예 (정책 위반 시) | 예 (정책 위반 시) | 아니요 |
| 주요 목적 | 실제 시스템 보호 | 정책 개발, 디버깅, 문제 분석 | SELinux 완전 비활성화 |
| 권장 환경 | 프로덕션, 스테이징 | 개발, 테스트 | 비권장 |
| 장점 | 최고 수준의 보안 제공 | 서비스 중단 없이 문제 분석 가능 | 설정의 복잡성 없음 |
| 단점 | 잘못된 정책 적용 시 서비스 장애 | 실제 공격을 방어하지 못함 | 모든 보안 이점 상실, 재활성화 어려움 |
4. 사이버 위협 대응 및 보안 강화
SELinux는 전통적인 보안 메커니즘이 놓칠 수 있는 다양한 현대적 사이버 위협에 대응하는 데 핵심적인 역할을 수행한다. 그 가치는 단순히 알려진 공격을 막는 것을 넘어, 알려지지 않은 공격의 피해를 최소화하고 시스템의 전반적인 복원력을 높이는 데 있다.
4.1 권한 상승 공격 방어 메커니즘
권한 상승 공격은 공격자가 초기에 획득한 낮은 수준의 권한을 이용하여 시스템의 더 높은 권한, 궁극적으로는 루트 권한을 획득하려는 시도를 말한다. SELinux는 여러 계층에서 이러한 시도를 효과적으로 차단한다.
4.1.1 SetUID 프로세스 샌드박싱
ping, passwd, sudo와 같이 일반 사용자가 일시적으로 루트 권한으로 실행해야 하는 SetUID 프로그램들은 전통적으로 권한 상승 공격의 주요 통로로 악용되어 왔다. SELinux는 이러한 잠재적으로 위험한 프로세스들을 각각 고유한 도메인으로 격리하여 실행하는 샌드박싱(sandboxing) 기술을 적용한다.5 예를 들어, 사용자가 passwd 명령어를 실행하면, 해당 프로세스는 passwd_t라는 매우 제한된 도메인 내에서만 작동한다. 이 도메인은 오직 /etc/shadow와 같은 암호 관련 파일에 접근하는 것만 허용하고, 그 외의 다른 시스템 파일이나 네트워크 접근은 철저히 금지한다. 따라서 설령 passwd 프로그램 자체에 취약점이 존재하여 공격자가 제어권을 탈취하더라도, 공격자는 passwd_t 도메인에 갇히게 되어 추가적인 악성 행위를 수행할 수 없게 된다.15
4.1.2 버퍼 오버플로우 공격 완화
버퍼 오버플로우는 공격자가 프로그램이 할당한 메모리 버퍼보다 더 많은 데이터를 입력하여 인접한 메모리 영역을 덮어쓰고, 궁극적으로는 악성 코드(셸 코드)를 주입하여 실행시키는 고전적이면서도 강력한 공격 기법이다. SELinux는 ‘실행 불가 메모리(Non-Executable Memory)’ 정책을 통해 이러한 공격을 완화할 수 있다. SELinux 정책은 특정 도메인에서 실행되는 프로세스가 메모리의 스택(stack)이나 힙(heap) 영역에 있는 데이터를 코드로써 실행하는 것을 금지할 수 있다. 이로 인해 공격자가 버퍼 오버플로우 취약점을 통해 셸 코드를 메모리에 성공적으로 주입하더라도, 운영체제 커널이 SELinux 정책에 따라 해당 메모리 영역에서의 코드 실행을 차단하므로 공격은 실패로 돌아간다.14
4.1.3 사례 연구: Dirty Cow (CVE-2016-5195)
Dirty Cow는 2016년에 발견된 심각한 리눅스 커널 권한 상승 취약점이다.43 이 취약점은 커널의 메모리 관리 서브시스템에서 Copy-on-Write(COW) 메커니즘을 처리하는 과정에 존재하는 경쟁 상태(Race Condition)를 악용한다.45 이를 통해 일반 사용자 권한을 가진 공격자가 읽기 전용(read-only)으로 매핑된 메모리 영역에 쓰기 작업을 수행할 수 있었고, 결과적으로 SetUID 파일과 같은 시스템의 중요 파일을 수정하여 루트 권한을 획득할 수 있었다.
이 사례는 SELinux의 역할과 한계를 명확하게 보여준다. Dirty Cow는 LSM 훅이 작동하는 수준보다 더 깊은 커널의 근본적인 로직 결함을 이용하는 공격이므로, SELinux가 이 공격 자체를 원천적으로 ’방지’하는 것은 거의 불가능하다.44 SELinux 정책은 커널이 설계된 대로 정상적으로 작동한다는 신뢰를 기반으로 설계되기 때문이다.
하지만 SELinux는 공격이 성공한 ’이후’의 활동을 제한하고 피해를 완화하는 데 여전히 중요한 역할을 할 수 있다. 공격자가 Dirty Cow를 이용해 특정 파일(예: /usr/bin/sudo)을 덮어쓰려고 시도할 때, 이 공격 코드를 실행하는 프로세스는 특정 SELinux 도메인(예: 일반 사용자 셸의 unconfined_t) 내에서 작동한다. 만약 SELinux 정책이 unconfined_t 도메인이 sudo_exec_t 타입의 파일에 대해 쓰기(write) 권한을 갖지 못하도록 정의하고 있다면, 커널이 최종적으로 쓰기 작업을 수행하기 전에 SELinux가 이를 차단할 수 있다. 즉, 공격의 성공 여부가 공격을 시도하는 프로세스의 SELinux 컨텍스트와 타겟 파일의 컨텍스트에 따라 달라질 수 있다. 이는 완벽한 방어는 아니지만, 다중 계층으로 구성된 심층 방어(Defense-in-Depth) 전략에서 SELinux가 얼마나 중요한 역할을 하는지를 보여주는 사례다.39 이처럼 SELinux의 한계를 인지하는 것은 그것을 비활성화할 이유가 아니라, 오히려 커널 패치와 같은 다른 보안 조치와 함께 더욱 견고하게 운영해야 할 이유가 된다.
4.2 제로데이 공격 피해 최소화 전략
제로데이 공격은 소프트웨어 개발사가 인지하지 못하고 보안 패치가 존재하지 않는 알려지지 않은 취약점을 이용하는 공격이다.49 정의상, 이러한 공격의 초기 침투 자체를 시그니처 기반의 전통적인 보안 솔루션으로 막는 것은 거의 불가능하다. SELinux의 진정한 가치는 바로 이러한 ‘침해가 발생한 이후(post-exploitation)’ 단계에서 발휘된다.
4.2.1 Post-Exploitation 활동 제한
SELinux는 ‘침해 가정(Assume Breach)’ 보안 모델에 완벽하게 부합하는 기술이다. 시스템은 언젠가 뚫릴 수 있다는 가정 하에, 침해가 발생하더라도 그 피해를 최소화하는 데 초점을 맞춘다. 공격자가 제로데이 취약점을 통해 시스템에 성공적으로 침투하더라도, 공격자가 획득하는 권한은 침투에 사용된 프로세스의 SELinux 도메인으로 엄격하게 제한된다.5 공격자는 이 좁은 ‘디지털 감옥’ 안에 갇히게 되어 추가적인 악성 행위를 수행하기가 극도로 어려워진다.
4.2.2 시나리오 분석: 웹 애플리케이션 제로데이 공격
알려지지 않은 웹 애플리케이션의 원격 코드 실행(RCE) 취약점을 이용한 제로데이 공격 시나리오를 통해 SELinux의 방어 원리를 단계별로 분석할 수 있다.5
-
초기 침투: 공격자는 제로데이 취약점을 악용하여 웹 서버 데몬(
httpd)의 제어권을 성공적으로 탈취한다. 이제 공격자는 웹 서버 프로세스의 권한으로 서버에서 임의의 코드를 실행할 수 있게 된다. -
SELinux의 개입: 공격자가 제어하는
httpd프로세스는 SELinux에 의해httpd_t라는 도메인 내에서 실행되고 있다.13 공격자의 모든 후속 활동은 이httpd_t도메인에 허용된 정책 규칙의 제약을 받는다. -
피해 확산(Lateral Movement) 차단: 공격자는 초기 거점을 발판으로 더 많은 권한을 획득하고 내부망으로 이동하려 시도할 것이다. 이때 SELinux가 다단계로 방어벽 역할을 수행한다.
-
데이터베이스 접근 시도: 공격자가 웹 서버 설정 파일에서 데이터베이스 연결 정보를 찾아내 직접 데이터베이스 파일(
/var/lib/mysql/)에 접근하려 시도한다. 하지만httpd_t도메인은mysqld_db_t타입으로 레이블링된 파일에 접근할 수 없도록 정책에 명시되어 있으므로 이 시도는 SELinux에 의해 차단된다.10 또한,httpd_can_network_connect_db부울이off상태라면 데이터베이스 서버로의 네트워크 연결 시도 자체도 차단된다. -
내부망 스캔 및 공격: 공격자가
nmap과 같은 네트워크 스캔 도구를 서버에 업로드하여 내부망의 다른 서버들을 공격하려 한다. 그러나httpd_t도메인은 웹 서비스에 필요한 80, 443 포트 외에 다른 임의의 포트로 나가는 연결(outbound connection)을 생성하는 것이 정책적으로 금지되어 있어 이 시도 역시 실패한다.5 -
시스템 파일 변조 및 백도어 설치: 공격자가 시스템에 영구적인 접근 권한을 확보하기 위해
/etc/crontab을 수정하거나 SSH 설정 파일을 변경하여 백도어를 설치하려 한다. 하지만httpd_t도메인은etc_t,sshd_etc_t와 같은 중요한 시스템 설정 파일 타입에 대해 쓰기 권한이 없으므로 SELinux에 의해 차단된다.
- 결론: 이 시나리오에서 공격자는 웹 서버라는 매우 제한된 샌드박스 안에 완벽하게 고립된다. 시스템의 다른 부분으로 피해를 확산시키지 못하고, 결국 시스템 관리자가 침해 사실을 탐지하고 대응할 수 있는 귀중한 시간을 벌어주게 된다. 이처럼 SELinux는 제로데이 공격의 ’폭발 반경(Blast Radius)’을 최소화하여 치명적인 시스템 장악을 막는 결정적인 역할을 수행한다.5 이는 예방(Prevention)을 넘어 복원력(Resilience)과 피해 통제(Damage Control)를 위한 현대 보안 철학의 핵심적인 구현체라 할 수 있다.
4.3 시스템 무결성 보호 및 잘못된 설정 완화
SELinux는 외부 공격뿐만 아니라 내부적인 실수나 잘못된 설정으로 인한 보안 사고를 방지하는 강력한 안전망 역할도 수행한다.
-
중요 파일 보호:
/etc/passwd,/etc/shadow와 같은 사용자 계정 정보 파일, 커널 모듈, 부트 로더 설정 등 시스템 운영에 필수적인 파일들은 극도로 제한된 특정 도메인(예:useradd,passwd명령어 실행 시 일시적으로 전환되는 도메인)에서만 접근 및 수정이 가능하도록 엄격하게 보호된다.4 -
관리자 실수 방지: 시스템 관리자가 실수로 웹 서버의 문서 루트 디렉터리를 모든 사용자의 개인 파일이 저장된
/home디렉터리로 설정했다고 가정해보자. DAC 환경에서는 웹 서버가 모든 사용자의 파일을 읽을 수 있게 되어 심각한 개인정보 유출 사고로 이어질 수 있다. 하지만 SELinux 환경에서는httpd_t도메인이user_home_t타입으로 레이블링된 디렉터리 및 파일에 접근하는 것이 기본적으로 금지되어 있으므로, 설정 실수에도 불구하고 정보 유출이 방지된다.2 이처럼 SELinux는 의도치 않은 구성 오류가 치명적인 보안 사고로 이어지는 것을 막아준다.4
5. 고급 주제 및 생태계
SELinux를 깊이 있게 활용하기 위해서는 로그 분석, 다양한 플랫폼에서의 구현 방식 차이, 그리고 기술의 장단점에 대한 비판적 이해가 필요하다.
5.1 SELinux 로그 분석 및 문제 해결
SELinux로 인해 특정 작업이 차단되었을 때, 그 원인을 파악하고 해결하는 능력은 시스템 관리자에게 필수적이다. 모든 해답은 감사 로그(audit log)에 있다.
-
로그 파일 위치 및 구조: SELinux의 모든 정책 위반(거부) 이벤트는
auditd데몬에 의해/var/log/audit/audit.log파일에 기록된다.16 각 로그 항목은type=AVC(Access Vector Cache)로 시작하며, 문제 해결에 필요한 풍부한 정보를 담고 있다. -
denied { action }: 거부된 구체적인 행위 (예:read,write,connect). -
pid=... comm="...": 행위를 시도한 주체 프로세스의 ID와 이름. -
scontext=...: 주체 프로세스의 보안 컨텍스트 (Source Context). -
tcontext=...: 접근 대상 객체의 보안 컨텍스트 (Target Context). -
tclass=...: 대상 객체의 클래스 (예:file,dir,tcp_socket). -
path=“…” name=“…”: 대상 객체의 경로 및 이름.
이 정보들을 조합하면 ’어떤 프로세스(scontext)가 어떤 파일(tcontext)에 대해 어떤 작업(action)을 하려다 거부되었는지’를 정확히 파악할 수 있다.27
audit2why: 이 유틸리티는 복잡한 AVC 거부 로그를 입력받아, 사람이 이해하기 쉬운 자연어 형태로 왜 접근이 거부되었는지를 설명해준다.53 문제의 원인을 진단하는 첫 단계로 매우 유용하다.
Bash
# grep "avc: denied" /var/log/audit/audit.log | tail -1 | audit2why
audit2allow: 이 강력한 도구는 거부 로그를 자동으로 분석하여, 해당 접근을 허용하는 데 필요한 SELinux 정책 규칙(allow구문)을 생성해준다.22 이를 통해 관리자는 복잡한 정책 언어를 잘 모르더라도 사용자 정의 정책 모듈을 쉽게 만들 수 있다.
Bash
# grep "httpd" /var/log/audit/audit.log | audit2allow -M my_httpd_local
# semodule -i my_httpd_local.pp
주의사항: audit2allow는 매우 편리한 도구지만, 그 제안을 맹목적으로 따라서는 안 된다. 이 도구는 단순히 발생한 거부를 허용하는 규칙을 생성할 뿐, 그 허용이 보안적으로 올바른지 판단하지는 않는다. 때로는 파일의 컨텍스트를 수정(restorecon)하거나, 특정 부울 값을 변경(setsebool)하는 것이 더 근본적이고 안전한 해결책일 수 있다. audit2allow는 다른 방법으로 해결할 수 없을 때 최후의 수단으로 사용하는 것이 바람직하다.42
5.2 플랫폼별 SELinux 구현 비교 분석
SELinux는 동일한 커널 기술을 기반으로 하지만, 적용되는 플랫폼의 위협 모델과 보안 목표에 따라 그 구현 방식과 정책 구조가 크게 달라진다. 이는 SELinux가 특정 기술이 아니라, 다양한 환경에 맞춰 조정 가능한 ’보안 철학’임을 보여준다.
5.2.1 서버 환경 (RHEL/CentOS/Fedora)
-
보안 목표: 서버 환경의 주된 위협 모델은 외부에 노출된 서비스(웹, DB, DNS 등)를 통한 원격 공격과, 시스템에 로그인한 다수의 사용자 간의 권한 남용 및 자원 격리다.13 따라서 정책의 목표는 중요한 시스템 데몬들을 강력하게 보호하고, 사용자별/역할별로 접근 권한을 세밀하게 제어하는 데 있다.
-
정책 구조 및 관리:
targeted정책을 기본으로 사용하며, SELinux 컨텍스트의 모든 요소(사용자, 역할, 타입, 레벨)를 적극적으로 활용하여 정교한 역할 기반 접근 제어(RBAC)를 구현한다.13 시스템 관리자가semanage,setsebool등의 도구를 사용하여 시스템의 특수한 요구사항에 맞게 정책을 적극적으로 수정하고 확장하는 것을 전제로 설계되었다.
5.2.2 모바일 환경 (Android - SEAndroid)
-
보안 목표: 안드로이드 환경의 주된 위협 모델은 사용자가 설치하는 신뢰할 수 없는 수많은 애플리케이션이다. 따라서 최우선 목표는 각 애플리케이션을 다른 앱 및 시스템으로부터 완벽하게 격리하는 강력한 애플리케이션 샌드박싱(sandboxing)을 구현하는 것이다.56
-
정책 구조 및 관리: 안드로이드는 서버 환경과는 매우 다른 접근 방식을 취한다. 각자의 위협 모델에 맞춰 SELinux의 일부 기능을 의도적으로 단순화하거나 사용하지 않는다.58
-
사용자(User): 모든 주체와 객체에 대해
u라는 단일 사용자만 사용한다. -
역할(Role): 주체는
r, 객체는object_r이라는 두 가지 기본 역할만 사용하여 사실상 RBAC 기능을 활용하지 않는다. -
부울(Boolean): 사용하지 않는다. 정책은 디바이스의 상태와 무관하게 빌드 시점에 고정된다.
-
관리: 최종 사용자가 정책을 수정하는 것을 상정하지 않는다. 모든 정책은 운영체제(OS) 빌드 시점에 구글과 디바이스 제조사에 의해 결정되고 서명되어 탑재된다. 모든 애플리케이션은 설치 시
untrusted_app_t와 같은 고유한 SELinux 도메인을 할당받아, 이 도메인에 허용된 극히 제한적인 권한 내에서만 작동한다.57
이러한 차이점은 동일한 SELinux 커널 기술이 어떻게 서로 다른 보안 목표(서버 보호 vs. 앱 샌드박싱)를 달성하기 위해 다르게 적용될 수 있는지를 명확히 보여준다.
5.3 SELinux의 장점, 단점 및 비판적 고찰
5.3.1 장점
-
강력한 보안: MAC 기반의 세분화된 접근 제어를 통해 전통적인 DAC 모델의 한계를 극복하고 심층 방어를 구현한다.2
-
피해 최소화: 권한 상승 공격, 제로데이 공격 등 최신 위협에 대해 침해 후 활동을 제한하여 피해 범위를 최소화한다.5
-
사전 정의된 고품질 정책: RHEL, Fedora, Android 등 주요 배포판은 수년간 검증된 고품질의 기본 정책을 제공하여, 관리자가 처음부터 모든 것을 만들 필요 없이 즉시 높은 수준의 보안을 적용할 수 있게 한다.4
5.3.2 단점 및 과제
-
복잡성과 높은 학습 곡선: SELinux의 개념, 정책 언어, 관리 도구는 처음 접하는 관리자에게 매우 복잡하고 어렵게 느껴질 수 있다.9
-
운영 오버헤드: 새로운 애플리케이션을 설치하거나 시스템 설정을 변경할 때마다 SELinux 정책을 고려하고 문제를 해결해야 하므로 상당한 시간과 노력이 필요하다. 이로 인해 많은 관리자들이 어려움을 느끼고 결국 SELinux를 비활성화하는 손쉬운 길을 택하기도 한다.14
-
불친절한 오류 메시지: SELinux 정책 위반으로 인해 서비스가 실패할 경우, 감사 로그를 분석하지 않으면 명확한 원인을 파악하기 어려워 문제 해결을 더디게 만들 수 있다.14
이러한 ’복잡성’은 SELinux의 명백한 단점이지만, 다르게 해석될 수도 있다. 현대의 서버 시스템(마이크로서비스, 컨테이너, 복잡한 네트워크 통신) 자체가 본질적으로 매우 복잡하다. SELinux 정책의 복잡성은 바로 이 시스템의 복잡한 상호작용을 정확하게 모델링하고 통제하려는 시도에서 비롯된 필연적인 결과다. 시스템의 본질적인 복잡성을 무시하고 보안을 단순화하려는 시도는 필연적으로 보안 공백을 만들게 된다. 따라서 SELinux의 학습 곡선은 ’불필요한 복잡성’이 아니라, 시스템의 실제 동작 방식을 깊이 이해하고 보안적으로 제어하기 위해 지불해야 하는 ’필수적인 비용’으로 재해석될 수 있다. SELinux를 마스터하는 과정은 곧 시스템 아키텍처의 전문가가 되는 과정과 같다.
Table 3: 주요 SELinux 관리 명령어 요약
| 명령어 | 주요 기능 | 사용 예시 | 비고 |
|---|---|---|---|
sestatus | SELinux의 전반적인 상태(모드, 정책 타입 등) 확인 | sestatus | 상태 진단 |
getenforce | 현재 작동 모드(Enforcing/Permissive) 확인 | getenforce | 실시간 모드 확인 |
setenforce | 작동 모드를 실시간으로 변경 | setenforce 0 (Permissive) | 임시 변경 (재부팅 시 초기화) |
chcon | 파일/디렉터리의 보안 컨텍스트 변경 | chcon -t httpd_sys_content_t file.html | 임시 변경 |
restorecon | 파일/디렉터리 컨텍스트를 정책 기본값으로 복원 | restorecon -R -v /var/www/html | 영구 정책 적용 |
semanage | SELinux 정책(컨텍스트, 포트, 부울 등) 관리 | semanage fcontext -a -t... | 영구 정책 수정 |
getsebool | SELinux 부울 값 확인 | getsebool -a | 정책 옵션 확인 |
setsebool | SELinux 부울 값 변경 | setsebool -P httpd_can_network_connect on | 정책 옵션 제어 |
audit2why | 거부 로그의 원인을 자연어로 설명 | ... | audit2why | 1차 원인 분석 |
audit2allow | 거부 로그를 기반으로 허용 정책 규칙 생성 | ... | audit2allow -M local_module | 정책 모듈 생성 |
Table 4: RHEL vs. Android SELinux 정책 비교
| 구분 | RHEL (서버 환경) | Android (모바일 환경) |
|---|---|---|
| 주된 보안 목표 | 서버 데몬 보호, 사용자/역할 기반 접근 제어 | 애플리케이션 샌드박싱 및 데이터 격리 |
| 기본 정책 | Targeted Policy (특정 서비스 중심) | 모든 프로세스를 제한하는 포괄적 정책 |
| SELinux 사용자 | 다수 사용 (system_u, unconfined_u 등) | 단일 사용자 (u) |
| SELinux 역할 | RBAC를 위해 다수 역할 사용 (system_r, object_r 등) | 주체(r), 객체(object_r) 역할만 사용 |
| 부울 사용 여부 | 예 (동적 정책 제어) | 아니요 (정적 정책) |
| 정책 관리 주체 | 시스템 관리자 | OS 개발사 및 디바이스 제조사 |
6. 결론
SELinux는 단순한 보안 기능을 넘어, 리눅스 시스템의 보안 철학을 근본적으로 바꾼 강력한 아키텍처이다. 임의적 접근 제어(DAC)가 가진 본질적인 한계, 특히 슈퍼유저(root)라는 단일 실패 지점의 위험성을 극복하기 위해 설계된 강제적 접근 제어(MAC)의 가장 성공적인 구현체다.
현대의 사이버 위협 환경은 알려지지 않은 제로데이 공격과 고도화된 권한 상승 시도가 만연해 있다. 이러한 환경에서 ’침해는 발생할 수 있다’는 것을 전제하는 ‘침해 가정(Assume Breach)’ 패러다임은 이제 표준이 되었다. SELinux는 바로 이 패러다임에 가장 부합하는 기술이다. 초기 침투를 완벽하게 막는 것이 불가능하더라도, 침해 이후 공격자의 활동을 엄격하게 제한하고 피해 확산을 차단함으로써 시스템의 핵심 기능을 보존하고 복구할 시간을 확보해준다. 즉, SELinux는 시스템의 ’사이버 복원력(Cyber Resilience)’을 보장하는 핵심적인 심층 방어 계층이다.
물론 SELinux의 복잡성과 가파른 학습 곡선은 많은 시스템 관리자에게 큰 장벽으로 작용하는 것이 사실이다. 이로 인해 많은 시스템에서 SELinux가 비활성화된 채 운영되는 안타까운 현실이 존재한다. 하지만 SELinux를 비활성화하는 것은 자동차의 에어백과 안전벨트를 모두 제거하고 운전하는 것과 같다. 당장의 불편함을 해소하기 위해 시스템의 가장 중요한 안전장치를 포기하는 행위다. 올바른 접근 방식은 복잡성을 이유로 SELinux를 회피하는 것이 아니라, Permissive 모드와 audit2allow, audit2why와 같은 강력한 분석 도구를 적극적으로 활용하여 점진적으로 시스템의 동작을 이해하고, 그에 맞는 정책을 수립해 나가는 것이다.
컨테이너, 클라우드 네이티브, 사물 인터넷(IoT) 환경이 확산됨에 따라, 수많은 개별 구성 요소를 세밀하게 통제하고 격리해야 할 필요성은 더욱 커지고 있다. 이러한 미래의 컴퓨팅 환경에서 각 객체에 고유한 보안 컨텍스트를 부여하고 정책에 따라 상호작용을 제어하는 SELinux의 역할은 지금보다 훨씬 더 중요해질 것이다. Ansible과 같은 자동화 도구와의 결합을 통해 정책 생성 및 관리의 복잡성을 완화하고, 더 넓은 범위의 시스템에 일관된 보안을 적용하는 방향으로 발전할 것으로 전망된다.2 결국 SELinux를 마스터하는 것은 단순히 하나의 보안 도구를 배우는 것을 넘어, 현대 리눅스 시스템의 아키텍처를 깊이 이해하고 가장 안전하게 운영하는 전문가로 거듭나는 길이다.