SELinux 기초 — 강제 접근 제어(MAC) 입문

SELinux의 MAC 개념, Enforcing/Permissive/Disabled 모드, 컨텍스트 라벨, chcon/restorecon/semanage 사용법과 AVC 거부 트러블슈팅을 설명합니다.

· 5 min read · PALDYN Team

지난 글에서 X11 포워딩으로 원격 GUI 앱을 실행하는 방법을 살펴봤습니다. 보안 챕터로 넘어가 **SELinux(Security-Enhanced Linux)**를 다룹니다. RHEL/CentOS/Fedora 계열에서 기본 활성화되어 있는 SELinux는 많은 관리자가 처음 만나면 당황해서 비활성화부터 합니다. 하지만 원리를 이해하면 강력한 방어 계층이 됩니다.

DAC와 MAC의 차이

기존 Linux 파일 권한은 **DAC(Discretionary Access Control, 임의 접근 제어)**입니다. 파일 소유자가 chmod로 권한을 마음대로 바꿀 수 있습니다. root는 모든 파일에 접근할 수 있습니다.

SELinux는 **MAC(Mandatory Access Control, 강제 접근 제어)**입니다. 정책이 커널 수준에서 강제되며, root도 정책에 정의된 범위를 넘을 수 없습니다. Apache가 침해당해도 httpd_t 컨텍스트의 범위 밖에는 접근할 수 없습니다.

세 가지 모드

# 현재 모드 확인
getenforce
# Enforcing / Permissive / Disabled

# 일시적 변경 (재부팅 시 /etc/selinux/config 값으로 돌아옴)
setenforce 0   # Permissive (정책 위반 허용, 로그만 기록)
setenforce 1   # Enforcing  (정책 위반 차단 + 로그)

영구 변경은 /etc/selinux/config에서 SELINUX=enforcing을 수정한 뒤 재부팅합니다. Disabled에서 Enforcing으로 직접 전환하면 재레이블링이 필요합니다.

SELinux 아키텍처와 정책 적용 흐름

컨텍스트 라벨

SELinux는 모든 파일, 프로세스, 포트에 컨텍스트(context) 라벨을 붙입니다. 형식은 user:role:type:level입니다.

# 파일 컨텍스트 확인
ls -Z /var/www/html/index.html
# system_u:object_r:httpd_sys_content_t:s0

# 프로세스 컨텍스트 확인
ps -eZ | grep httpd
# system_u:system_r:httpd_t:s0    ...  httpd

# 포트 컨텍스트 확인
semanage port -l | grep http
# http_port_t  tcp  80, 443, ...

가장 중요한 부분은 type 필드입니다. httpd 프로세스(httpd_t)는 httpd_sys_content_t 라벨이 붙은 파일에만 읽기 접근이 허용됩니다.

컨텍스트 수정

파일을 다른 위치에서 복사하거나 직접 생성하면 컨텍스트가 틀릴 수 있습니다.

# 임시 변경 (재레이블링 시 초기화됨)
chcon -t httpd_sys_content_t /srv/mysite/index.html

# 재귀적 적용
chcon -Rt httpd_sys_content_t /srv/mysite/

# 권장: restorecon으로 정책 기본값 복원
restorecon -Rv /var/www/html/

# 새 경로를 정책에 영구 등록 (semanage)
semanage fcontext -a -t httpd_sys_content_t "/srv/mysite(/.*)?"
restorecon -Rv /srv/mysite/

semanage fcontext + restorecon 조합이 올바른 방법입니다. chcon만 쓰면 restorecon 실행 시 원래대로 돌아갑니다.

Boolean — 정책 스위치

SELinux 정책에는 시스템 관리자가 켜고 끌 수 있는 Boolean 스위치가 있습니다.

# 모든 Boolean 목록
getsebool -a | grep httpd

# Apache가 네트워크 연결을 시작할 수 있는지
getsebool httpd_can_network_connect
# httpd_can_network_connect --> off

# 활성화 (-P: 영구 저장)
setsebool -P httpd_can_network_connect on

Apache에서 백엔드 API나 DB에 연결할 때 흔히 필요한 Boolean입니다.

트러블슈팅

SELinux 트러블슈팅 플로우

AVC(Access Vector Cache) 거부 로그는 /var/log/audit/audit.log에 기록됩니다.

# 최근 AVC 거부 확인
ausearch -m avc -ts recent

# sealert: 거부 원인과 해결 방법 제안
sealert -a /var/log/audit/audit.log

# audit2allow: 허용 정책 모듈 자동 생성
audit2allow -w -a
audit2allow -a -M mymodule
semodule -i mymodule.pp

흔한 실수: SELinux가 문제라고 의심되면 setenforce 0으로 전환해 확인하는 것까지는 좋습니다. 그런데 그 상태로 두고 잊어버리는 게 문제입니다. 원인을 파악한 뒤 컨텍스트 수정이나 Boolean 조정으로 해결하고 다시 Enforcing으로 복원하세요.


지난 글: X11 포워딩 — SSH로 원격 서버의 GUI 앱 실행하기

다음 글: AppArmor 기초 — 프로파일 기반 강제 접근 제어


읽어주셔서 감사합니다. 😊