19.3. SELinux와 관련된 문제 해결
이전에 비활성화된 시스템에서 SELinux를 활성화하거나 비표준 구성에서 서비스를 실행하려는 경우 SELinux에서 잠재적으로 차단된 상황을 해결해야 할 수 있습니다. 대부분의 경우 SELinux 거부는 잘못된 구성의 기호입니다.
19.3.1. SELinux 거부 식별
이 절차의 필수 단계에만 따릅니다. 대부분의 경우 1단계만 수행해야 합니다.
절차
SELinux에서 시나리오를 차단하면
/var/log/audit/audit.log
파일이 거부에 대한 자세한 정보를 확인하는 첫 번째 위치입니다. 감사 로그를 쿼리하려면ausearch
툴을 사용합니다. SELinux 결정(예: 액세스 허용 또는 허용하지 않음)은 캐시되고 이 캐시는 AVC(액세스 벡터 캐시)라고 하며 메시지 유형 매개 변수에 대해AVC
및USER_AVC
값을 사용합니다.# ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts recent
일치하는 항목이 없으면 감사 데몬이 실행 중인지 확인합니다. 그렇지 않으면
auditd
를 시작한 후 거부된 시나리오를 반복하고 감사 로그를 다시 확인합니다.auditd
가 실행 중이지만ausearch
출력에 일치하는 항목이 없는 경우systemd
저널에서 제공하는 메시지를 확인합니다.# journalctl -t setroubleshoot
SELinux가 활성 상태이고 감사 데몬이 시스템에서 실행되지 않는 경우
dmesg
명령의 출력에서 특정 SELinux 메시지를 검색합니다.# dmesg | grep -i -e type=1300 -e type=1400
이전 세 번의 확인 이후에도 아무것도 찾을 수 없습니다. 이 경우
dontaudit
규칙으로 인해 AVC 거부를 음소거할 수 있습니다.dontaudit
규칙을 일시적으로 비활성화하려면 모든 거부를 허용하십시오.# semodule -DB
거부된 시나리오를 다시 실행하고 이전 단계를 사용하여 거부 메시지를 찾은 후 다음 명령을 실행하면 정책에서
dontaudit
규칙을 다시 활성화합니다.# semodule -B
4개의 이전 단계를 모두 적용하고 문제를 여전히 식별하지 않은 경우 SELinux가 실제로 시나리오를 차단하는지 고려하십시오.
허용 모드로 전환:
# setenforce 0 $ getenforce Permissive
- 시나리오를 반복합니다.
문제가 계속 발생하는 경우 SELinux와는 다른 것이 시나리오를 차단하는 것입니다.
19.3.2. SELinux 거부 메시지 분석
SELinux 가 시나리오를 차단하고 있음을 확인한 후 수정 사항을 선택하기 전에 근본 원인을 분석해야 할 수 있습니다.
사전 요구 사항
-
policycoreutils-python-utils
및setroubleshoot-server
패키지가 시스템에 설치됩니다.
절차
sealert
명령을 사용하여 기록된 거부에 대한 세부 정보를 나열합니다. 예를 들면 다음과 같습니다.$ sealert -l "*" SELinux is preventing /usr/bin/passwd from write access on the file /root/test. ***** Plugin leaks (86.2 confidence) suggests ***************************** If you want to ignore passwd trying to write access the test file, because you believe it should not need this access. Then you should report this as a bug. You can generate a local policy module to dontaudit this access. Do # ausearch -x /usr/bin/passwd --raw | audit2allow -D -M my-passwd # semodule -X 300 -i my-passwd.pp ***** Plugin catchall (14.7 confidence) suggests ************************** ... Raw Audit Messages type=AVC msg=audit(1553609555.619:127): avc: denied { write } for pid=4097 comm="passwd" path="/root/test" dev="dm-0" ino=17142697 scontext=unconfined_u:unconfined_r:passwd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0 ... Hash: passwd,passwd_t,admin_home_t,file,write
이전 단계에서 얻은 출력에 명확한 제안이 포함되지 않은 경우:
전체 경로 감사를 활성화하여 액세스한 오브젝트의 전체 경로를 확인하고 추가 Linux 감사 이벤트 필드를 표시합니다.
# auditctl -w /etc/shadow -p w -k shadow-write
setroubleshoot
캐시를 지웁니다.# rm -f /var/lib/setroubleshoot/setroubleshoot.xml
- 문제를 재현합니다.
1단계 반복.
프로세스를 완료한 후 전체 경로 감사를 비활성화합니다.
# auditctl -W /etc/shadow -p w -k shadow-write
-
sealert
가catchall
제안만 반환하거나audit2allow
도구를 사용하여 새 규칙을 추가하는 것을 제안하는 경우, 감사 로그의 SELinux 거부에 나열된 예제와 문제와 일치하십시오.
추가 리소스
-
시스템의
sealert(8)
도움말 페이지
19.3.3. 분석된 SELinux 거부 수정
대부분의 경우 sealert
툴에서 제공하는 제안은 SELinux 정책과 관련된 문제를 해결하는 방법에 대한 올바른 지침을 제공합니다. sealert
를 사용하여 SELinux 거부를 분석하는 방법에 대한 정보는 SELinux 거부 메시지 분석을 참조하십시오.
툴에서 구성 변경에 audit2allow
툴을 사용하도록 제안하는 경우 주의하십시오. SELinux 거부가 표시되는 경우 audit2allow
를 사용하여 첫 번째 옵션으로 로컬 정책 모듈을 생성해서는 안 됩니다. 레이블 지정 문제가 있는 경우 문제 해결을 시작해야 합니다. 두 번째 가장 자주 발생하는 사례는 프로세스 구성을 변경했으며 SELinux에 대해 알려주는 것을 잊어버리는 것입니다.
문제 레이블 지정
레이블 지정 문제의 일반적인 원인은 비표준 디렉터리가 서비스에 사용되는 경우입니다. 예를 들어 웹 사이트에 /var/www/html/
를 사용하는 대신 관리자가 /srv/myweb/
을 사용하려고 할 수 있습니다. Red Hat Enterprise Linux에서 /srv
디렉터리에 var_t
유형으로 레이블이 지정됩니다. /srv
에 생성된 파일과 디렉터리는 이 유형을 상속합니다. 또한 /myserver
와 같은 최상위 디렉토리에서 새로 생성된 오브젝트는 default_t
유형으로 레이블이 지정될 수 있습니다. SELinux는 Apache HTTP Server(httpd)
가 이러한 두 가지 유형 모두에 액세스하지 못하도록 합니다. 액세스를 허용하기 위해 SELinux는 httpd
에서 /srv/myweb/
의 파일에 액세스할 수 있음을 알아야 합니다.
# semanage fcontext -a -t httpd_sys_content_t "/srv/myweb(/.*)?"
이 semanage
명령은 /srv/myweb/
디렉터리의 컨텍스트와 그 아래에 있는 모든 파일 및 디렉터리를 SELinux 파일 컨텍스트 구성에 추가합니다. semanage
유틸리티는 컨텍스트를 변경하지 않습니다. root로 restorecon
유틸리티를 사용하여 변경 사항을 적용합니다.
# restorecon -R -v /srv/myweb
잘못된 문맥
matchpathcon
유틸리티는 파일 경로의 컨텍스트를 확인하고 해당 경로의 기본 레이블과 비교합니다. 다음 예제에서는 파일이 잘못 레이블된 디렉터리에서 matchpathcon
을 사용하는 방법을 보여줍니다.
$ matchpathcon -V /var/www/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
/var/www/html/page1.html has context unconfined_u:object_r:user_home_t:s0, should be system_u:object_r:httpd_sys_content_t:s0
이 예제에서 index.html
및 page1.html
파일에는 user_home_t
유형으로 레이블이 지정됩니다. 이 유형은 사용자 홈 디렉토리의 파일에 사용됩니다. mv
명령을 사용하여 홈 디렉토리의 파일을 이동하면 user_home_t
유형으로 파일에 레이블이 지정될 수 있습니다. 이 유형은 홈 디렉토리 외부에 없어야 합니다. restorecon
유틸리티를 사용하여 이러한 파일을 올바른 유형으로 복원합니다.
# restorecon -v /var/www/html/index.html
restorecon reset /var/www/html/index.html context unconfined_u:object_r:user_home_t:s0->system_u:object_r:httpd_sys_content_t:s0
디렉터리 아래의 모든 파일의 컨텍스트를 복원하려면 -R
옵션을 사용합니다.
# restorecon -R -v /var/www/html/
restorecon reset /var/www/html/page1.html context unconfined_u:object_r:samba_share_t:s0->system_u:object_r:httpd_sys_content_t:s0
restorecon reset /var/www/html/index.html context unconfined_u:object_r:samba_share_t:s0->system_u:object_r:httpd_sys_content_t:s0
비표준 방식으로 구성된 제한된 애플리케이션
서비스는 다양한 방법으로 실행할 수 있습니다. 이를 위해 서비스 실행 방법을 지정해야 합니다. 런타임 시 SELinux 정책 부분을 변경할 수 있는 SELinux 부울을 통해 이를 수행할 수 있습니다. 이렇게 하면 SELinux 정책을 다시 로드하거나 다시 컴파일하지 않고도 NFS 볼륨에 대한 서비스 액세스 허용 등의 변경 사항이 가능합니다. 또한 기본이 아닌 포트 번호에서 서비스를 실행하려면 semanage
명령을 사용하여 정책 구성을 업데이트해야 합니다.
예를 들어 Apache HTTP 서버가 MariaDB와 통신할 수 있도록 하려면 httpd_can_network_connect_db
부울을 활성화합니다.
# setsebool -P httpd_can_network_connect_db on
P 옵션은
시스템을 재부팅할 때마다 설정을 지속합니다.
특정 서비스에 대한 액세스가 거부된 경우 getsebool
및 grep
유틸리티를 사용하여 액세스를 허용하는 부울을 사용할 수 있는지 확인합니다. 예를 들어 getsebool -a | grep ftp
명령을 사용하여 FTP 관련 부울을 검색합니다.
$ getsebool -a | grep ftp
ftpd_anon_write --> off
ftpd_full_access --> off
ftpd_use_cifs --> off
ftpd_use_nfs --> off
ftpd_connect_db --> off
httpd_enable_ftp_server --> off
tftp_anon_write --> off
부울 목록을 가져오고 활성화 또는 비활성화되었는지 확인하려면 getsebool -a
명령을 사용합니다. 부울 목록의 의미를 비롯하여 부울 목록이 표시되고 활성화되어 있는지 여부를 확인하려면 selinux-policy-devel
패키지를 설치하고 semanage boolean -l
명령을 root로 사용합니다.
포트 번호
정책 구성에 따라 서비스는 특정 포트 번호에서만 실행할 수 있습니다. 정책 변경 없이 서비스가 실행되는 포트를 변경하려고 하면 서비스가 시작되지 않을 수 있습니다. 예를 들어 semanage port -l | grep http
명령을 root로 실행하여 http
관련 포트를 나열합니다.
# semanage port -l | grep http
http_cache_port_t tcp 3128, 8080, 8118
http_cache_port_t udp 3130
http_port_t tcp 80, 443, 488, 8008, 8009, 8443
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989
http_port_t
포트 유형은 Apache HTTP Server가 수신 대기할 수 있는 포트를 정의합니다. 이 경우 TCP 포트 80, 443, 488, 8008, 8009, 8443입니다. httpd가 포트 9876(Listen 9
를 구성하는 경우 다음 명령이 실패합니다.
876)
에서 수신 대기하지만
이를 반영하도록 정책이 업데이트되지 않도록 관리자가 httpd.conf
# systemctl start httpd.service Job for httpd.service failed. See 'systemctl status httpd.service' and 'journalctl -xn' for details. # systemctl status httpd.service httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled) Active: failed (Result: exit-code) since Thu 2013-08-15 09:57:05 CEST; 59s ago Process: 16874 ExecStop=/usr/sbin/httpd $OPTIONS -k graceful-stop (code=exited, status=0/SUCCESS) Process: 16870 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
다음과 유사한 SELinux 거부 메시지가 /var/log/audit/audit.log에 기록됩니다.
type=AVC msg=audit(1225948455.061:294): avc: denied { name_bind } for pid=4997 comm="httpd" src=9876 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket
httpd
가 http_port_t
포트 유형에 대해 나열되지 않은 포트에서 수신 대기하도록 하려면 semanage port 명령을 사용하여 포트에
다른 레이블을 할당합니다.
# semanage port -a -t http_port_t -p tcp 9876
a 옵션은
새 레코드를 추가하고, -t
옵션은 유형을 정의하고, -p
옵션은 프로토콜을 정의합니다. 마지막 인수는 추가할 포트 번호입니다.
모서리 사례, 진화 또는 손상된 애플리케이션 및 손상된 시스템
애플리케이션에 버그가 포함되어 SELinux가 액세스를 거부할 수 있습니다. 또한 SELinux 규칙이 진화하고 있습니다. SELinux는 특정 방식으로 애플리케이션이 실행되고 있지 않을 수 있으므로 애플리케이션이 예상대로 작동하는 경우에도 액세스를 거부할 수 있습니다. 예를 들어, PostgreSQL의 새 버전이 릴리스되면 현재 정책에서 고려하지 않는 작업을 수행하여 액세스가 허용되어야 하는 경우에도 액세스가 거부될 수 있습니다.
이러한 경우 액세스가 거부된 후 audit2allow
유틸리티를 사용하여 사용자 지정 정책 모듈을 생성하여 액세스를 허용합니다. Red Hat Bugzilla 의 SELinux 정책에서 누락된 규칙을 보고할 수 있습니다. Red Hat Enterprise Linux 8의 경우 Red Hat Enterprise Linux 8
제품에 대한 버그를 생성하고 selinux-policy
구성 요소를 선택합니다. 이러한 버그 보고서에 audit2allow -w -a
및 audit2allow -a
명령의 출력을 포함합니다.
애플리케이션에서 주요 보안 권한을 요청하는 경우 애플리케이션이 손상되었다는 신호일 수 있습니다. 침입 탐지 툴을 사용하여 이러한 의심스러운 동작을 검사합니다.
Red Hat 고객 포털의 솔루션 엔진은 기존과 동일하거나 매우 유사한 문제에 대해 가능한 솔루션을 포함하는 문서 형태로 지침을 제공할 수도 있습니다. 관련 제품 및 버전을 선택하고 selinux 또는 avc 와 같은 SELinux 관련 키워드를 차단된 서비스 또는 애플리케이션의 이름과 함께 사용합니다(예: selinux samba
).
19.3.4. 로컬 SELinux 정책 모듈 생성
활성 SELinux 정책에 특정 SELinux 정책 모듈을 추가하면 SELinux 정책의 특정 문제를 해결할 수 있습니다. 이 절차를 사용하여 Red Hat 릴리스 노트에 설명된 특정 알려진 문제를 수정하거나 특정 Red Hat 솔루션을 구현할 수 있습니다.
Red Hat에서 제공하는 규칙만 사용하십시오. Red Hat은 제품 지원 범위를 벗어나기 때문에 사용자 지정 규칙을 사용하여 SELinux 정책 모듈 생성을 지원하지 않습니다. 전문가가 아닌 경우 Red Hat 영업 담당자에게 연락하여 컨설팅 서비스를 요청하십시오.
사전 요구 사항
-
확인을 위한
setools-console
및감사
패키지입니다.
절차
텍스트 편집기로 새
.cil
파일을 엽니다. 예를 들면 다음과 같습니다.# vim <local_module>.cil
로컬 모듈을 더 잘 정리하려면 로컬 SELinux 정책 모듈의 이름에
local_
접두사를 사용합니다.알려진 문제 또는 Red Hat 솔루션에서 사용자 지정 규칙을 삽입합니다.
중요자체 규칙을 작성하지 마십시오. 특정 알려진 문제 또는 Red Hat 솔루션에서 제공되는 규칙만 사용하십시오.
예를 들어 SELinux를 구현하면 RHEL 솔루션에서 cups.sock에 대한 cups-lpd 읽기 액세스를 거부하려면 다음 규칙을 삽입합니다.
(allow cupsd_lpd_t cupsd_var_run_t (sock_file (read)))
RHBA-2021:4420 의 RHEL에 대해 예제 솔루션이 영구적으로 수정되었습니다. 따라서 이 솔루션과 관련된 이 절차의 일부는 업데이트된 RHEL 8 및 9 시스템에는 영향을 미치지 않으며 구문 예제로만 포함됩니다.
두 가지 SELinux 규칙 구문, CIL(Common Intermediate Language) 및 m4 중 하나를 사용할 수 있습니다. 예를 들어 CIL의
(allow cupsd_lpd_t cupsd_var_run_t (sock_file (read)))
은 m4의 다음과 동일합니다.module local_cupslpd-read-cupssock 1.0; require { type cupsd_var_run_t; type cupsd_lpd_t; class sock_file read; } #============= cupsd_lpd_t ============== allow cupsd_lpd_t cupsd_var_run_t:sock_file read;
- 파일을 저장하고 닫습니다.
정책 모듈을 설치합니다.
# semodule -i <local_module>.cil
semodule -i
를 사용하여 생성한 로컬 정책 모듈을 제거하려면.cil
접미사 없이 모듈 이름을 참조하십시오. 로컬 정책 모듈을 제거하려면semodule -r < local_module> 을 사용합니다
.규칙과 관련된 서비스를 다시 시작합니다.
# systemctl restart <service-name>
검증
SELinux 정책에 설치된 로컬 모듈을 나열합니다.
# semodule -lfull | grep "local_" 400 local_module cil
로컬 모듈에는 우선순위
400
이 있으므로semodule -lfull | grep -v ^100
명령을 사용하여 해당 값을 사용하여 목록에서도 필터링할 수 있습니다.SELinux 정책에서 관련 허용 규칙을 검색합니다.
# sesearch -A --source=<SOURCENAME> --target=<TARGETNAME> --class=<CLASSNAME> --perm=<P1>,<P2>
여기서 <
SOURCENAME
>은 소스 SELinux 유형이며 <TARGETNAME
>은 대상 SELinux 유형이며 <CLASSNAME
>은 보안 클래스 또는 오브젝트 클래스 이름이며 <P1
> 및 <P2
>는 규칙의 특정 권한입니다.예를 들어 SELinux가 RHEL Red Hat knowledgbase 솔루션의 cups.sock에 대한 cups-lpd 읽기 액세스를 거부하려면 다음을 수행합니다.
# sesearch -A --source=cupsd_lpd_t --target=cupsd_var_run_t --class=sock_file --perm=read allow cupsd_lpd_t cupsd_var_run_t:sock_file { append getattr open read write };
이제 마지막 줄에
읽기
작업이 포함되어야 합니다.관련 서비스가 SELinux에 의해 제한된 상태로 실행되는지 확인합니다.
관련 서비스와 관련된 프로세스를 확인합니다.
$ systemctl status <service-name>
이전 명령의 출력에 나열된 프로세스의 SELinux 컨텍스트를 확인합니다.
$ ps -efZ | grep <process-name>
서비스에서 SELinux 거부를 유발하지 않는지 확인합니다.
# ausearch -m AVC -i -ts recent <no matches>
i
옵션은 숫자 값을 사람이 읽을 수 있는 텍스트로 해석합니다.
추가 리소스
19.3.5. 감사 로그의 SELinux 거부
Linux 감사 시스템은 기본적으로 /var/log/audit/audit.log
파일에 로그 항목을 저장합니다.
SELinux 관련 레코드만 나열하려면 메시지 유형 매개 변수를 최소한 AVC 및 AVC
_USER
로 설정된 ausearch
명령을 사용합니다. 예를 들면 다음과 같습니다.
# ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR
감사 로그 파일의 SELinux 거부 항목은 다음과 같이 표시됩니다.
type=AVC msg=audit(1395177286.929:1638): avc: denied { read } for pid=6591 comm="httpd" name="webpages" dev="0:37" ino=2112 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:nfs_t:s0 tclass=dir
이 항목의 가장 중요한 부분은 다음과 같습니다.
-
AVC : 거부됨
- SELinux에서 수행하고 액세스 벡터 캐시 (AVC)에 기록 된 동작 -
{ read }
- 거부된 작업 -
PID=6591
- 거부된 작업을 수행하려는 주체의 프로세스 식별자 -
Comm="httpd"
- 분석된 프로세스를 호출하는 데 사용된 명령의 이름 -
httpd_t
- 프로세스의 SELinux 유형 -
nfs_t
- 프로세스 작업의 영향을 받는 오브젝트의 SELinux 유형 -
tclass=dir
- 대상 객체 클래스
이전 로그 항목은 다음으로 변환할 수 있습니다.
SELinux는 PID 6591과 httpd_t
유형이 nfs_t
유형의 httpd 프로세스를
거부했습니다.
다음 SELinux 거부 메시지는 Apache HTTP 서버가 Samba 제품군 유형으로 레이블이 지정된 디렉토리에 액세스하려고 하면 발생합니다.
type=AVC msg=audit(1226874073.147:96): avc: denied { getattr } for pid=2465 comm="httpd" path="/var/www/html/file1" dev=dm-0 ino=284133 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=file
-
{ getattr }
-getattr
항목은 소스 프로세스가 타겟 파일의 상태 정보를 읽으려고 했다고 나타냅니다. 이 작업은 파일을 읽기 전에 수행됩니다. SELinux는 프로세스가 파일에 액세스하고 적절한 레이블이 없으므로 이 작업을 거부합니다. 일반적으로 표시되는 권한에는getattr
,read
,write
가 포함됩니다. -
path="/var/www/html/file1"
- 프로세스가 액세스하려고 한 개체(대상)의 경로입니다. -
scontext="unconfined_u:system_r:httpd_t:s0"
- 거부된 작업을 시도한 프로세스의 SELinux 컨텍스트(소스). 이 경우httpd_t
유형으로 실행 중인 Apache HTTP 서버의 SELinux 컨텍스트입니다. -
tcontext="unconfined_u:object_r:samba_share_t:s0"
- 프로세스가 액세스하려고 시도한 오브젝트의 SELinux 컨텍스트입니다. 이 경우file1
의 SELinux 컨텍스트입니다.
이 SELinux 거부는 다음으로 변환될 수 있습니다.
SELinux는 PID 2465로 httpd
프로세스를 거부하여 별도로 구성하지 않는 한 httpd_t 도메인에서
실행 중인 프로세스에 액세스할 수 없는 samba_share_t
유형을 사용하여 /var/www/html/file1
파일에 액세스합니다.
추가 리소스
-
시스템의
auditd(8)
및ausearch(8)
도움말 페이지
19.3.6. 추가 리소스
- CLI의 기본 SELinux 문제 해결 (Red Hat Knowledgebase)
- SELinux가 무엇을 말하려고 합니까? SELinux 오류의 4가지 주요 원인 (Fedora people)