본문으로 건너뛰기

SELinux

October 2, 2026

SELinux란?​

SELinux(Security-Enhanced Linux)는 프로세스가 어떤 파일, 포트, 자원에 접근할 수 있는지를 정책으로 강제하는 Linux 커널의 보안 기능이다.

Linux의 기본 권한 체계는 chmod, chown으로 다루는 소유자/그룹/권한 기반이다. 이를 DAC(Discretionary Access Control)라고 한다.

SELinux는 여기에 더해 MAC(Mandatory Access Control)을 제공한다.

구분기준특징
DAC소유자 / 그룹 / 권한(rwx)파일 소유자가 권한을 마음대로 바꿀 수 있다
MAC시스템에 정의된 정책(Policy)root라도 정책에서 허용하지 않은 접근은 차단된다

여기서 중요한 점은 다음과 같다.

SELinux는 DAC를 대체하는 것이 아니라, DAC를 통과한 요청을 한 번 더 검사한다.

따라서 파일 권한이 777이더라도 SELinux 정책에서 허용하지 않으면 접근이 차단된다.

'권한은 다 맞는데 Permission denied가 난다'면 SELinux를 의심해볼 수 있는 이유이다.


동작 모드​


모드의 종류​

SELinux에는 3가지 모드가 있다.

모드정책 검사차단로그설명
EnforcingOOO정책을 위반한 접근을 차단한다 (기본값)
PermissiveOXO차단하지 않고 로그만 남긴다
DisabledXXXSELinux를 사용하지 않는다

Permissive는 차단은 하지 않지만 위반 내역은 로그로 남기기 때문에, 문제의 원인이 SELinux인지 확인하는 용도로 많이 사용한다.


모드 확인​

현재 적용 중인 모드만 확인

getenforce
Enforcing

SELinux 상태 조금 더 상세히 확인

sestatus
SELinux status:                 enabled
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
  • Current mode : 현재 적용 중인 모드
  • Mode from config file : 설정 파일에 정의된 모드 (재부팅 후 적용될 모드)

이 둘이 다르다면, 현재 모드는 임시로 변경된 것이고 재부팅하면 설정 파일의 값으로 돌아간다.


모드 변경​

임시 변경

setenforce 0
setenforce 1
  • 0은 Permissive, 1은 Enforcing이다.
  • 즉시 적용되지만 재부팅하면 사라진다.
  • setenforce로는 Disabled로 바꾸거나, Disabled 상태에서 다시 켤 수 없다.

영구 변경

설정 파일은 /etc/selinux/config이다.

vi /etc/selinux/config
SELINUX=enforcing
SELINUXTYPE=targeted

SELINUX= 값을 enforcing, permissive, disabled 중 하나로 변경하고 재부팅하면 적용된다.

sed로는 다음과 같이 변경할 수 있다.

sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config

전체 과정을 요약하면 다음과 같다.

setenforce = 지금 즉시 적용, 재부팅 시 초기화 / /etc/selinux/config = 재부팅 이후에 적용

따라서 재부팅 없이 바로 적용하면서 이후에도 유지하려면 둘 다 수행해야 한다.

Disabled로 변경할 때
  • Disabled 상태에서는 새로 만들어지는 파일에 SELinux Context가 붙지 않는다.
  • 이후 다시 Enforcing으로 되돌리면 전체 파일시스템의 Context를 다시 붙이는 Relabel 작업이 필요하고, 부팅 시간이 길어진다.
  • 이에, 꼭 꺼야 하는 것이 아니라면 Disabled보다 Permissive로 두는 것이 되돌리기 쉽다.
  • RHEL 9부터는 설정 파일의 SELINUX=disabled만으로는 완전히 비활성화되지 않으며, 완전히 끄려면 커널 파라미터 selinux=0을 사용하도록 안내하고 있다.

Context​


Context란?​

Context는 SELinux가 접근 허용 여부를 판단하기 위해 프로세스와 파일에 붙여두는 라벨이다.

파일의 Context는 ls -Z, 프로세스의 Context는 ps -eZ로 확인할 수 있다.

ls -Z /var/www/html
ps -eZ | grep httpd
unconfined_u:object_r:httpd_sys_content_t:s0 index.html
system_u:system_r:httpd_t:s0 1234 ? 00:00:01 httpd

Context는 :로 구분된 4개의 필드로 구성된다.

system_u : object_r : httpd_sys_content_t : s0
│ │ │ │
User Role Type Level

기본 정책인 targeted에서 실제로 중요한 것은 세번째 필드인 Type이다.

러프하게 보면 다음과 같다.

httpd_t 타입의 프로세스는 httpd_sys_content_t 타입의 파일을 읽을 수 있다.

즉, SELinux 정책은 '어떤 Type의 프로세스가 어떤 Type의 대상에 접근할 수 있는가'에 대한 규칙의 모음이라고 보면 된다.


Context가 문제가 되는 경우​

대표적인 경우가 파일을 다른 위치에서 만든 뒤 mv로 옮긴 경우이다.

cp는 대상 디렉토리의 Context를 따라가지만, mv는 원래 파일의 Context를 그대로 유지한다.

예를 들어 홈 디렉토리에서 만든 index.html을 /var/www/html로 mv하면, 파일의 Type이 user_home_t로 남아있어 httpd가 읽지 못한다.

이 경우 restorecon으로 해당 경로의 기본 Context를 다시 적용한다.

restorecon -Rv /var/www/html
  • -R : 하위 경로까지 재귀적으로 적용
  • -v : 변경된 내역 출력

기본 경로가 아닌 곳을 사용하는 경우​

/data/web처럼 기본 경로가 아닌 디렉토리를 서비스에서 사용한다면, 해당 경로에 어떤 Context를 붙일지를 정책에 등록해야 한다.

semanage fcontext -a -t httpd_sys_content_t "/data/web(/.*)?"
restorecon -Rv /data/web
  • semanage fcontext -a : 경로에 대한 Context 규칙을 정책에 추가한다.
  • restorecon : 등록된 규칙에 따라 실제 파일에 Context를 적용한다.

chcon으로 Context를 직접 바꿀 수도 있지만, 이는 정책에 등록되는 것이 아니기 때문에 restorecon이나 Relabel 시 원래대로 돌아간다.

명령어동작영구 여부
chcon파일의 Context를 직접 변경Relabel 시 원래대로 돌아감
semanage fcontext경로의 Context 규칙을 정책에 등록영구
restorecon정책에 등록된 Context를 파일에 적용-

semanage 명령어가 없다면 policycoreutils-python-utils 패키지를 설치해야 한다.

이에, Apache, Tomcat과 같은 미들웨어를 소스 컴파일 방식 설치 후 Systemd에 등록해서 실행할 경우 모든 설정이 정상인데도 실행이 되지 않는 경우가 있다.

이는 SELinux가 활성화된 환경에서 해당 실행 파일 또는 스크립트에 적절한 SELinux Context가 부여되지 않아 systemd를 통한 실행이 차단되기 때문이다.


Port와 Boolean​


Port​

SELinux는 파일뿐만 아니라 프로세스가 사용할 수 있는 포트도 제한한다.

예를 들어 httpd를 기본 포트가 아닌 8888로 띄우면, 설정이 맞더라도 SELinux에 의해 기동에 실패할 수 있다.

semanage port -l | grep http_port_t
semanage port -a -t http_port_t -p tcp 8888
  • semanage port -l : Type별로 허용된 포트 목록 확인
  • semanage port -a : 해당 Type에 포트 추가

Boolean​

Boolean은 정책의 특정 기능을 켜고 끌 수 있도록 미리 만들어둔 스위치이다.

정책 자체를 수정하지 않고도 자주 필요한 동작을 허용할 수 있다.

getsebool -a | grep httpd
setsebool -P httpd_can_network_connect on
  • getsebool -a : 전체 Boolean 목록과 현재 값 확인
  • setsebool -P : Boolean 값을 변경한다. -P를 붙여야 재부팅 후에도 유지된다.

대표적인 예시로 httpd_can_network_connect가 있다. 이 값이 off이면 httpd가 다른 서버로 네트워크 연결을 할 수 없어, Reverse Proxy로 WAS에 연결할 때 실패한다.


문제 해결​


SELinux가 원인인지 확인하는 방법​

가장 간단한 방법은 임시로 Permissive로 바꿔보는 것이다.

setenforce 0

이후 동일한 동작이 정상적으로 된다면 SELinux가 원인이다.

원인을 확인했다면 setenforce 1로 되돌리고, 아래의 로그를 확인하여 필요한 부분만 허용하는 것이 올바른 방향이다.


로그 확인​

SELinux가 차단한 내역은 /var/log/audit/audit.log에 AVC라는 타입으로 기록된다.

ausearch -m avc -ts recent
grep denied /var/log/audit/audit.log
type=AVC msg=audit(1759370000.123:456): avc:  denied  { read } for  pid=1234 comm="httpd" name="index.html" scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0
항목의미
denied { read }차단된 동작
comm차단된 프로세스
scontext접근을 시도한 주체(프로세스)의 Context
tcontext접근 대상(파일, 포트 등)의 Context
tclass대상의 종류 (file, dir, tcp_socket 등)

위 예시는 httpd_t 프로세스가 user_home_t 타입의 파일을 읽으려다 차단된 것이다.

즉, 파일의 Context가 잘못된 것이므로 restorecon으로 해결할 수 있다.

audit2why를 사용하면 차단된 이유와 해결 방법에 대한 힌트를 얻을 수 있다.

ausearch -m avc -ts recent | audit2why


정리​

증상확인해결
권한은 맞는데 파일 접근이 차단됨ls -Zrestorecon 또는 semanage fcontext
기본 포트가 아닌 포트로 기동 실패semanage port -lsemanage port -a
다른 서버로의 네트워크 연결 등 특정 동작 차단getsebool -asetsebool -P
원인을 모르겠음ausearch -m avcaudit2why로 원인 확인