PRO DBDATA PRO DBDATA

SELinux Permission Denied 진단: AVC 로그와 파일 보안 컨텍스트 복구 가이드

읽는 시간 약 15분
SELinux Permission Denied 진단: AVC 로그와 파일 보안 컨텍스트 복구 가이드

Linux 서버에서 파일 권한을 확인했는데도 Permission denied 오류가 반복된다면 SELinux 정책을 함께 살펴봐야 합니다. 웹 콘텐츠를 읽지 못하거나 애플리케이션이 필요한 파일을 열지 못하는 문제는 서비스 중단으로 이어질 수 있습니다.

이런 장애는 CPU와 메모리 사용률이 정상이어도 발생합니다. 접근이 초기에 차단되면 실제 작업량이 줄어 자원 지표는 오히려 낮게 나타날 수 있어, 일반적인 성능 모니터링만으로 원인을 찾기 어렵습니다.

중요한 것은 권한 오류를 곧바로 SELinux 문제로 단정하지 않는 것입니다. 일반 파일 권한, 서비스 실행 계정, AVC 거부 기록, 보안 컨텍스트를 차례로 비교해야 불필요한 권한 확대를 피할 수 있습니다.

이 글에서는 RHEL 계열의 SELinux 환경과 Apache 웹 서버를 예로 들어 진단부터 라벨 복구까지 설명합니다. 아래 로그와 출력은 이해를 위한 예시이며, 실제 표시 형식과 정책은 설치된 패키지와 서버 설정에 따라 달라질 수 있습니다.

장애 증상과 초기 판단

예를 들어 웹 콘텐츠를 배포한 직후 특정 페이지에서만 HTTP 403 응답이 발생한다고 가정해 보겠습니다. 웹 서버 프로세스는 실행 중이고 디스크 공간도 충분하지만, 오류 로그에는 다음과 같은 메시지가 남습니다.

(13)Permission denied: AH00132: file permissions deny server access: /var/www/html/index.html

이 메시지만으로 SELinux가 원인이라고 확정할 수는 없습니다. 파일 읽기 권한 부족, 상위 디렉터리 탐색 권한 부족, ACL 설정도 비슷한 증상을 만들 수 있습니다.

모니터링에서는 전체 서버 상태보다 배포 전후의 URL별 오류율을 비교하는 편이 유용합니다. 정적 파일 일부만 실패하는지, 업로드처럼 쓰기가 필요한 기능만 실패하는지에 따라 점검 대상이 달라집니다.

운영자 관점에서는 먼저 실패한 작업, 대상 경로, 발생 시각을 확보하는 것이 좋습니다. CPU 사용률만 보고 자원을 증설하면 접근 통제 문제는 그대로 남습니다.

내부 동작 원리와 장애 발생 구조

일반적인 Linux 파일 권한은 사용자·그룹·기타 사용자에게 부여된 읽기, 쓰기, 실행 권한을 중심으로 접근을 판단합니다. 이를 DAC, 즉 임의적 접근 통제라고 합니다.

SELinux는 여기에 MAC, 즉 강제적 접근 통제를 추가합니다. 프로세스와 파일에 부여된 보안 컨텍스트를 사용해 해당 접근이 정책상 허용되는지 판단합니다. 일반 권한이 먼저 접근을 막았다면 SELinux 거부 로그가 발생하지 않을 수 있습니다. 이러한 관계는 Red Hat의 SELinux 기본 구조 문서에서 설명합니다.

보안 컨텍스트는 다음과 같은 구조입니다.

system_u:object_r:httpd_sys_content_t:s0

각 필드는 SELinux 사용자, 역할, 타입, 보안 수준을 뜻합니다. 일반적인 서비스 파일 접근 문제에서는 특히 타입이 중요한 판단 기준입니다. 프로세스의 타입은 도메인이라고도 부릅니다.

예를 들어 httpd_t 도메인의 웹 서버가 httpd_sys_content_t 타입의 콘텐츠를 읽는 상황과, 사용자 홈 디렉터리용 타입이 붙은 파일을 읽는 상황은 정책상 다르게 취급될 수 있습니다. 파일 소유자가 같거나 읽기 권한이 열려 있어도 결과가 같다는 보장은 없습니다.

정상 요청은 일반 권한과 SELinux 정책을 통과한 뒤 파일을 읽어 응답합니다. 반면 파일 접근이 거부되면 웹 서버는 오류를 반환하고, 해당 파일을 사용하는 상위 애플리케이션이나 상태 확인 요청까지 실패할 수 있습니다.

따라서 장애가 여러 계층에 보이더라도 최초 실패가 파일 접근인지, 네트워크 연결인지부터 구분해야 합니다.

확인 지표와 진단 명령어

현재 적용 모드와 일반 권한 확인

먼저 현재 SELinux 모드를 확인합니다.

getenforce
Enforcing

Enforcing은 정책 위반을 차단하는 상태입니다. Permissive는 위반을 기록하지만 SELinux가 해당 접근을 차단하지 않는 상태이고, Disabled는 비활성 상태입니다. Enforcing이라는 사실 자체는 오류가 아닙니다.

다음으로 대상 파일까지 이어지는 경로의 권한을 확인합니다.

namei -l /var/www/html/index.html
f: /var/www/html/index.html
dr-xr-xr-x root root /
drwxr-xr-x root root var
drwxr-xr-x root root www
drwxr-xr-x root root html
-rw-r--r-- root root index.html

예시에서는 기타 사용자도 상위 디렉터리를 탐색하고 파일을 읽을 수 있습니다. 디렉터리의 x는 경로 탐색에 필요한 권한입니다.

다만 이 출력만으로 ACL까지 검증한 것은 아닙니다. 실제 서비스 실행 계정과 ACL도 함께 확인해야 하며, 관리자 셸에서 파일을 읽었다는 사실만으로 서비스 접근이 정상이라고 판단해서는 안 됩니다.

AVC 로그에서 거부된 접근 확인

오류를 재현한 직후 최근 SELinux 관련 기록을 조회합니다.

sudo ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts recent
type=AVC msg=audit(1788616800.123:842): avc: denied { read } for pid=2148 comm="httpd" name="index.html" dev="dm-0" ino=525410 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0

예시의 주요 항목은 다음과 같습니다.

항목해석
{ read }거부된 작업은 읽기
pid=2148, comm="httpd"접근을 요청한 프로세스
scontext요청 프로세스의 컨텍스트
tcontext접근 대상의 컨텍스트
tclass=file대상은 일반 파일
permissive=0해당 거부가 permissive 처리되지 않음
:842관련 감사 기록을 연결하는 이벤트 번호

이 경우 웹 서버 도메인과 사용자 홈 파일 타입의 조합이 확인됩니다. 다만 name은 전체 경로가 아니므로 애플리케이션 로그와 같은 감사 이벤트의 다른 기록을 연결해야 합니다.

AVC가 검색되지 않는다면 조회 시간 범위, auditd 동작 여부, 로그 수집 상태를 점검합니다. 일부 거부는 dontaudit 규칙으로 기록이 생략될 수 있습니다. Red Hat의 SELinux 문제 해결 문서는 이러한 확인 순서와 로그 해석을 안내합니다.

실제 라벨과 기대 라벨 비교

파일에 현재 붙어 있는 라벨을 확인합니다.

ls -lZ /var/www/html/index.html
-rw-r--r--. 1 root root unconfined_u:object_r:user_home_t:s0 1842 Sep  5 14:00 /var/www/html/index.html

user_home_t는 현재 파일에 붙은 타입입니다. 경로에 설정된 기대 컨텍스트와 비교합니다.

matchpathcon -V /var/www/html/index.html
/var/www/html/index.html has context unconfined_u:object_r:user_home_t:s0, should be system_u:object_r:httpd_sys_content_t:s0

이 예시는 실제 라벨과 경로 기준 라벨이 다름을 보여줍니다. 앞서 확인한 실패 시각과 AVC의 대상 정보까지 일치한다면 라벨 불일치를 우선 복구할 근거가 됩니다.

반대로 기대 라벨과 일치하더라도 애플리케이션 용도에 맞는 경로 설정인지까지 보장되지는 않습니다. 비표준 경로는 별도 매핑이 필요한지 확인해야 합니다.

원인별 복구 절차와 해결 방법

긴급 영향 완화와 변경 준비

배포 직후 문제가 시작됐다면 실패한 배포를 중단하거나 검증된 이전 배포본으로 되돌리는 방안을 먼저 검토합니다. 다중 서버 환경에서는 정상 인스턴스로 요청을 우회할 수 있는지도 확인합니다.

설정 변경 전에는 대상 경로, 현재 라벨, 로컬 파일 컨텍스트 규칙, 관련 서비스 설정을 기록하고 백업합니다. 변경 범위와 되돌리는 방법을 정한 뒤 변경 관리 절차에 따라 적용해야 합니다.

전체 파일시스템을 재귀적으로 처리하기보다 오류가 확인된 파일이나 디렉터리부터 범위를 좁히는 것이 좋습니다.

표준 경로의 라벨 불일치 복구

먼저 실제 변경 없이 결과를 미리 확인합니다.

sudo restorecon -nv /var/www/html/index.html
Would relabel /var/www/html/index.html from unconfined_u:object_r:user_home_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0

-n은 변경하지 않는 점검 옵션이고, -v는 처리 내용을 표시합니다. 예상 변경이 맞으면 실제 복구를 실행합니다.

sudo restorecon -v /var/www/html/index.html
Relabeled /var/www/html/index.html from unconfined_u:object_r:user_home_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0

restorecon은 경로에 정의된 컨텍스트 규칙을 기준으로 라벨을 복구합니다. 일반적인 기본 동작에서는 타입만 바뀔 수 있으므로 SELinux 사용자 필드까지 항상 동일해진다고 가정하면 안 됩니다. 옵션별 범위는 SELinux 프로젝트의 restorecon 매뉴얼에서 확인할 수 있습니다.

파일 내용이나 일반 접근 권한을 수정하는 명령은 아닙니다. 라벨 복구 후에도 오류가 남는다면 최초 요청을 다시 실행해 다음 거부 지점을 확인합니다.

비표준 경로는 영구 매핑부터 등록

예를 들어 웹 콘텐츠 경로를 /srv/site로 변경했다면 단순한 라벨 복구만으로 해결되지 않을 수 있습니다. 해당 경로가 웹 콘텐츠라는 사실을 파일 컨텍스트 설정에 등록해야 합니다.

다음 예시는 해당 경로 전체가 읽기용 웹 콘텐츠이고, 동일한 로컬 규칙이 아직 없다는 전제입니다.

sudo semanage fcontext -a -t httpd_sys_content_t '/srv/site(/.*)?'
정상 완료 시 일반적으로 출력 없음

이 명령은 영구적인 경로 매핑을 등록합니다. 파일의 현재 라벨을 즉시 변경하지는 않습니다.

동일한 규칙이 이미 있다면 먼저 기존 설정을 확인하고 수정 여부를 결정해야 합니다. 기존 항목을 수정할 때는 -a 대신 -m을 사용합니다. 이러한 구분은 SELinux 프로젝트의 semanage-fcontext 매뉴얼에 설명되어 있습니다.

등록 후에는 하위 경로의 변경 예정 내용을 확인합니다.

sudo restorecon -Rnv /srv/site
Would relabel /srv/site from system_u:object_r:var_t:s0 to system_u:object_r:httpd_sys_content_t:s0
Would relabel /srv/site/index.html from system_u:object_r:var_t:s0 to system_u:object_r:httpd_sys_content_t:s0

-R은 하위 디렉터리와 파일을 재귀적으로 처리합니다. 범위가 적절하면 실제 적용합니다.

sudo restorecon -Rv /srv/site
Relabeled /srv/site from system_u:object_r:var_t:s0 to system_u:object_r:httpd_sys_content_t:s0
Relabeled /srv/site/index.html from system_u:object_r:var_t:s0 to system_u:object_r:httpd_sys_content_t:s0

업로드, 캐시, 실행 파일처럼 용도가 다른 항목까지 읽기용 콘텐츠 타입으로 묶으면 안 됩니다. 쓰기가 필요한 경로는 별도로 분리하고 해당 서비스 정책에 맞는 타입과 일반 권한을 검토합니다.

또한 chcon으로 현재 라벨만 바꾸는 방식은 경로의 영구 매핑을 등록하지 않습니다. 이후 재라벨링으로 되돌아갈 수 있으므로 배포 경로의 지속적인 관리에는 매핑과 적용을 구분해야 합니다.

라벨이 맞는 경우와 보안 기능을 끄기 전 점검

AVC의 대상이 파일이 아니라 소켓이거나 거부 작업이 포트 바인딩이라면 파일 라벨 복구는 맞는 해결책이 아닙니다. 서비스의 포트 설정이나 관련 SELinux boolean을 검토해야 합니다.

거부 기록을 일괄적으로 허용하는 정책을 만들기 전에는 요청 자체가 정상 업무에 필요한지 확인합니다. 잘못된 경로나 불필요한 접근을 허용하면 설정 오류를 정책에 고착시킬 수 있습니다.

전체 시스템을 permissive로 전환하는 진단은 모든 서비스의 강제 차단에 영향을 줍니다. 필요하다면 검증 환경이나 제한된 점검 시간에 수행하고 원래 모드로 복구해야 하며, 이를 영구 해결책으로 남겨서는 안 됩니다.

설정 변경 후에는 최소한 실제 업무 요청의 성공 여부와 같은 시간대의 신규 AVC 발생 여부를 함께 비교해야 합니다. 로그가 조용해졌더라도 요청 자체가 실행되지 않았다면 정상화의 증거가 되지 않습니다.

재발 방지와 마치며

배포 검증에는 파일 소유권과 일반 권한뿐 아니라 보안 컨텍스트도 포함해야 합니다. 특히 콘텐츠 경로 변경, 백업 복원, 파일 이동 후에는 대표 파일의 실제 라벨과 기대 라벨을 비교하는 절차가 유용합니다.

경보는 AVC 전체 누적 건수보다 일정 시간 동안 새로 발생한 거부 이벤트를 중심으로 설계합니다. 같은 프로세스 도메인, 대상 타입, 거부 작업을 묶고 서비스 오류율과 연결하면 반복 로그 속에서 영향이 큰 문제를 찾기 쉽습니다.

예를 들어 중요 서비스에서 새로운 거부 유형이 발생하면서 업무 요청도 실패하면 즉시 확인하도록 정할 수 있습니다. 이는 예시 기준이며, 정상 운영 기간의 패턴과 서비스 중요도에 맞춰 조정해야 합니다.

부하 테스트도 SELinux가 실제 운영과 같은 모드인 상태에서 진행합니다. 읽기뿐 아니라 업로드, 캐시 생성, 로그 회전처럼 서로 다른 접근을 검증해야 합니다. 파일 수가 많은 경로는 재귀 라벨 점검에 필요한 시간과 메타데이터 I/O도 작업 계획에 반영합니다.

SELinux Permission Denied 진단의 출발점은 보안 기능을 끄는 것이 아니라 실패한 접근을 정확히 식별하는 것입니다. 일반 권한, AVC 기록, 실제 라벨과 경로 매핑을 연결하면 필요한 접근만 복구하면서 서비스의 보안 경계도 유지할 수 있습니다.

PRODB

함께 보면 좋은 글

댓글 0

첫 댓글을 남겨보세요.

error: Content is protected !!

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.