임베디드 시스템이나 안드로이드 프레임워크를 다루다 보면 가장 먼저 마주치는 거대한 장벽 중 하나가 바로 SELinux(Security-Enhanced Linux)입니다. "분명히 root 권한으로 실행했는데 왜 접근 거부(Permission Denied)가 뜰까?"라는 의문은 개발자라면 누구나 한 번쯤 가져보았을 것입니다.
SELinux는 미국 국가안보국(NSA)이 개발한 강력한 접근 제어 메커니즘으로, 단순한 권한 관리를 넘어 시스템 전체의 안전성을 보장하는 핵심 기술입니다. 오늘은 리눅스의 기본 보안 모델인 DAC와의 차이점을 살펴보고, 안드로이드에서 SELinux가 어떻게 시스템을 보호하는지 상세히 정리해 보겠습니다.

📌 핵심 요약 3줄
- 강제적 접근 제어(MAC): 소유자가 권한을 설정하는 DAC와 달리, 중앙 정책(Policy)에 의해 모든 프로세스의 접근을 엄격히 통제합니다.
- 라벨 기반 보안: 모든 객체(파일, 프로세스 등)에 보안 컨텍스트(Label)를 부여하고, 이를 기준으로 허용 여부를 결정합니다.
- 안드로이드 보안 강화: 앱 샌드박싱과 시스템 서비스 보호를 위해 SELinux를 필수적으로 활용하며, 루트 권한의 오남용을 방지합니다.
1. SELinux의 기본 개념 및 특징
SELinux는 리눅스 커널의 보안 모듈(LSM)로서 동작하며, 사전 정의된 보안 정책에 위배되는 모든 동작을 원천 차단합니다.
| 주요 특징 | 설명 | 비고 |
| MAC (강제적 접근 제어) | 시스템 관리자가 정의한 보안 정책에 따라 모든 접근 허용 | 사용자 임의 설정 불가 |
| Labeling (라벨링) | 파일, 프로세스, 소켓 등에 보안 컨텍스트 부여 | u:r:type:s0 형식 |
| Policy (정책) | 허용할 동작과 금지할 동작을 정의한 파일 | allow 규칙 등 사용 |
SELinux의 3가지 동작 모드
- Enforcing (강제): 정책을 엄격히 적용하며 위반 시 접근을 차단하고 로그를 남깁니다. (상용 기기 기본값)
- Permissive (허용): 정책 위반 시 차단은 하지 않지만, 로그(AVC Audit)를 남깁니다. (개발 및 디버깅 시 사용)
- Disabled (비활성화): SELinux 기능을 완전히 끕니다.
2. SELinux의 3대 보안 모델
SELinux는 상황에 맞는 유연하고 강력한 제어를 위해 세 가지 핵심 모델을 조합하여 사용합니다.
2.1 유형 기반 보안 (Type Enforcement, TE)
객체와 주체를 '타입(Type)'으로 분류하여 제어하는 가장 핵심적인 모델입니다.
정책 예시: allow my_app_t data_file_t: file { read write };
(해석: my_app_t 타입 프로세스는 data_file_t 타입 파일을 읽고 쓸 수 있다.)
2.2 역할 기반 접근 제어 (RBAC)
특정 역할(Role)에 따라 실행할 수 있는 도메인과 권한을 제한합니다.
- system_r: 시스템 서비스 및 관리 작업용 역할
- user_r: 일반 사용자용 역할
2.3 다중 등급 보안 (Multi-Level Security, MLS)
데이터의 민감도(Sensitivity)에 따라 등급을 부여하여 상위 등급의 정보가 하위 등급으로 유출되지 않도록 관리합니다. 주로 군사적 목적이나 고도의 보안이 필요한 엔터프라이즈 환경에서 사용됩니다.
3. 안드로이드에서의 SELinux 적용 사례
안드로이드는 4.3 버전부터 SELinux를 도입했으며, 현재는 모든 프로세스가 엄격한 정책 하에 동작합니다.
- 샌드박스 강화: 각 앱은 고유의 SELinux 도메인을 부여받아 타 앱 데이터 접근이 원천 차단됩니다.
- 루트 권한 제한: 공격자가 루트 권한을 탈취하더라도 SELinux 정책에 정의되지 않은 커널 리소스나 시스템 설정은 변경할 수 없습니다.
- 명령어 활용:
- getenforce: 현재 동작 모드 확인
- ls -Z: 파일의 보안 컨텍스트 확인
- ps -Z: 프로세스의 보안 컨텍스트 확인
🛠️ 개발자를 위한 팁 & 흔히 하는 실수
✅ 개발 팁 (Best Practices)
- Audit2allow 도구 활용: 개발 중 avc: denied 로그가 발생하면 이를 분석하여 정책 파일(.te)로 자동 변환해 주는 audit2allow 도구를 사용해 보세요. 보안 정책 작성이 훨씬 수월해집니다.
- 최소 권한의 원칙: 정책을 작성할 때 allow 규칙에 불필요한 권한(예: execute, relabelfrom 등)을 포함하지 않도록 주의하세요.
❌ 흔히 하는 실수 (Common Mistakes)
- Permissive 모드 방치: 개발 편의를 위해 setenforce 0으로 두고 개발하다가, 배포 시 Enforcing 모드에서 기능이 동작하지 않아 당황하는 경우가 많습니다. 항상 정책을 먼저 정의하는 습관이 중요합니다.
- Labeling 누락: 새로운 파일 시스템이나 파티션을 마운트할 때 올바른 Label을 부여하지 않으면, root 권한으로도 해당 경로에 접근할 수 없습니다. file_contexts 파일 설정을 잊지 마세요.
- 불필요한 'Unconfined' 사용: 특정 프로세스를 unconfined_domain으로 설정하면 보안 취약점이 될 수 있습니다. 번거롭더라도 명확한 타입을 정의하는 것이 좋습니다.
4. 마무리
SELinux는 처음 접할 때는 복잡하고 까다롭게 느껴질 수 있지만, 시스템의 최후 보루로서 그 가치는 매우 큽니다. 특히 안드로이드 환경에서는 보안의 핵심이므로, 오늘 정리한 MAC의 개념과 유형 기반 보안(TE)의 원리를 잘 이해해 두신다면 더욱 안전하고 견고한 시스템을 개발하실 수 있을 것입니다.
'Android System & AOSP Engineering > Android Security & SELinux' 카테고리의 다른 글
| Android SELinux avc: denied 로그 분석 및 해결 완벽 가이드 (0) | 2025.04.29 |
|---|---|
| Android sepolicy 핵심 파일 가이드: file_contexts부터 mac_permissions까지 (0) | 2025.04.28 |
| Android SELinux 정책 파일 구조 분석: public vs private 차이점 정리 (0) | 2025.04.27 |
| Android sepolicy 구조 완벽 분석: file_contexts부터 빌드 과정까지 (0) | 2025.04.26 |
| Android 보안의 핵심 SELinux: 역할과 필요성 완벽 정리 (Lollipop 이후 필수) (0) | 2025.04.25 |