Translated message

A translation of this page exists in English.

사용자 정의 SELinux 정책 작성을 위한 빠른 시작

업데이트됨 -

Table of Contents

시스템에서 SELinux에 의해 제한되는 새 애플리케이션을 실행하려면 배포 SELinux 정책에 의해 시행되는 규칙을 보완하는 사용자 정의 정책 파일을 준비하십시오.

정책 템플릿 생성

policycoreutils-devel 패키지에서 제공하는 sepolicy 생성 도구는 초기 단계를 수행하는 데 도움이 됩니다. 이 도구는 기본 정책 모듈, Makefile 및 설정 스크립트를 생성합니다. 스크립트는 정책 모듈을 구축 및 설치하고 .fc 파일에 정의된 경로의 레이블을 다시 지정합니다. 일반 사용자로 명령을 사용할 수 있습니다. 예를 들면 다음과 같습니다.

$ sepolicy generate --init <path_to_my_app_binary>

자세한 내용은 SELinux 사용 문서의 RHEL에서 사용자 지정 애플리케이션에 대한 SELinux 정책 생성 및 시행 섹션을 참조하세요.

그래픽 인터페이스와 마법사를 선호하는 경우 policycoreutils-gui 패키지에서 제공하는 selinux-polgengui 도구를 사용할 수 있습니다.

생성된 정책 템플릿에는 다음 정책 파일이 포함되어 있습니다.

  • <mypolicy>.te - 정책 규칙은 물론 애플리케이션에서 사용되는 새로운 유형과 도메인을 정의합니다.
  • <mypolicy>.fc - 파일 컨텍스트 정의, 즉 애플리케이션과 관련된 파일에 레이블을 지정하기 위한 지침이 포함되어 있습니다.
  • <mypolicy>.if - 이 정책과 상호 작용하기 위해 다른 정책 모듈에서 사용하는 정책 매크로인 인터페이스를 포함합니다.

애플리케이션 동작에 따라 액세스 허용

시스템에 초기 정책을 설치한 후 애플리케이션에 필요한 액세스를 기반으로 정책을 개선할 수 있습니다.

액세스된 모든 경로를 로그에 포함하려면 전체 감사를 활성화합니다.

# audictl -d never,task
# auditctl -w /etc/ -p w

또는 /etc/audit/rules.d/audit.rules 파일을 열고 "-a task,never"가 있는 경우 제거하고 "-w /etc/ -p w"를 추가한 다음 감사 데몬을 다시 시작합니다.

SELinux 정책의 모든 위반을 기록하려면 SELinux를 허용 모드로 전환하세요.

# setenforce 0

setenforce 0 명령은 다음에 다시 시작할 때까지 SELinux를 전체 시스템에서 허용 모드로 설정합니다. 새 도메인만 허용 모드로 전환하고 SELinux 정책의 나머지 부분은 시행 모드로 유지할 수 있습니다.

# semanage permissive -a <myapp_t>

sepolicy generate 명령은 허용되는 <myapp_t> 규칙을 정책 모듈에 추가합니다. 따라서 규칙을 유지한 경우 이 단계를 건너뛸 수 있습니다.

전체 감사 및 허용 모드를 활성화한 후 새 SELinux 도메인에서 애플리케이션을 실행합니다. 애플리케이션에 필요한 모든 액세스 권한을 보려면 최대한 많은 사용 사례를 테스트하세요. 시스템은 현재 정책에서 허용되지 않는 모든 액세스 요청을 AVC (SELinux 액세스 거부 로그) 형식으로 기록합니다.

AVC 처리

SELinux가 작업을 거부하면 시스템은 AVC(액세스 벡터 캐시) 메시지를 /var/log/audit/audit.log/var/log/messages 파일에 추가하거나 Journal 데몬이 거부를 기록합니다.
다음과 같이 ausearch 명령을 사용하여 최근 AVC를 표시할 수 있습니다.

# ausearch -m AVC,USER_AVC -ts recent

-ts 최근 매개변수는 검색 시간을 10분으로 제한하지만 대신 타임스탬프를 사용할 수 있습니다.

audit2allow 도구는 AVC를 처리하고 정책에 대한 해당 허용 규칙을 생성할 수 있습니다.

사용자 지정 규칙이 다른 정책 패키지에 정의된 리소스와 상호 작용할 때마다 가능하면 간단한 허용 규칙 대신 인터페이스를 사용하십시오. audit2allow -R 명령은 대신 사용 사례를 다루는 인터페이스를 찾으려고 시도합니다. 결과 정책이 너무 느슨하지 않은지 확인하려면 이 명령의 각 결과를 확인해야 합니다.

정책 매크로

패턴 또는 더 복잡한 경우 인터페이스라고도 하는 정책 매크로는 특정 사용 사례를 허용하기 위해 함께 작동하는 여러 규칙을 생성합니다.

예:

  • interfaces:
    • mysql_read_config(<domain>) - 지정된 도메인(이 예에서는 httpd_t)에 MySQL 구성 파일에 대한 읽기 액세스 권한을 부여합니다.
    • init_daemon_domain(<domain>, <file_type>) - 도메인에 대한 첫 번째 인수로 제공된 유형을 승격하는 반면 init 데몬에 의해 실행 가능한 진입점으로 사용됩니다.
  • 패턴:
    • rw_files_pattern(<domain>, <dir_type>, <file_type>) - 제공 레이블이 지정된 파일에 대한 읽기 및 쓰기 액세스 라벨이 붙은 디렉토리에 위치
    • domtrans_pattern(<source>, <entrypoint>, <target>) - 자동 도메인 전환을 설정합니다. 프로세스가 도메인에서 실행될 때 라벨이 붙은 바이너리를 실행합니다. , 결과 프로세스는 도메인에서 실행됩니다.

Fedora, RHEL 및 CentOS에서 사용 가능한 인터페이스는 selinux-policy Github 저장소의 모듈 섹션에 정의되어 있습니다. 각 정책 모듈에는 다른 모듈이 모듈에 정의된 리소스에 액세스할 수 있는 수단으로 인터페이스 세트가 포함되어 있습니다.

각 매크로에는 지정해야 하는 고정된 개수의 인수가 있습니다. 해당 인수가 확실하지 않은 경우 매크로 본문에서 $ 문자 뒤에 색인이 오는 형태의 인수 참조가 있는지 확인하세요(예: $1 ). 또는 selinux-policy-doc 패키지에서 제공하는 /usr/share/doc/selinux-policy/html/interfaces.html 파일에서 인터페이스 색인을 확인하세요.

선택적 정책

기여 모듈 중 하나에 정의된 인터페이스를 사용할 때마다 이를 option_policy 블록에 묶어야 합니다.

예를 들어 Apache 모듈은 kerberos 모듈 에 정의된 kerberos_read_keytab 인터페이스를 사용합니다.

optional_policy(`
kerberos_read_keytab(httpd_t)
')

option_policy 블록은 선택적 모듈 없이 정책 모듈을 사용할 수 있도록 보장합니다. 이 경우 Kerberos 모듈이 제거된 시스템에서 Apache 모듈을 사용할 수 있습니다. option_policy 블록을 생략하면 액세스 권한을 부여한 리소스가 있는 모듈이 누락된 경우 새 정책 모듈을 설치하면 오류가 발생합니다.

매크로 확장

selinux-policy-devel 패키지에서 제공하는 매크로 확장 도구는 이름이 설명이 필요하지 않은 경우 각 매크로에 포함된 내용을 표시합니다. 매크로가 생성하는 모든 허용 규칙을 보려면 모든 인수를 포함하는 전체 매크로 이름과 함께 매크로 확장기를 사용하세요. 예:

# macro-expander "mysql_read_config(httpd_t)" 
allow httpd_t mysqld_etc_t:dir { getattr search open read lock ioctl };
allow httpd_t mysqld_etc_t:file { open { getattr read ioctl lock } };
allow httpd_t mysqld_etc_t:lnk_file { getattr read };

매크로 확장기 목록은 기본적으로 규칙만 허용합니다. type_transition 규칙이나 속성 할당과 같은 매크로의 전체 내용을 보려면 매크로 확장기 -M <>을 사용하고 모듈 헤더와 모든 필수 블록을 무시하세요.

$ macro-expander -M "domtrans_pattern(<source>, <entrypoint>, <target>)"
module expander 1.0.0;
require {
role system_r;
...
}
allow <source> <entrypoint>:file { getattr open map read execute ioctl execute_no_trans };
allow <source> <target>:process transition;
type_transition <source> <entrypoint>:process <target>;
allow <target> <source>:fd use;
allow <target> <source>:fifo_file { getattr read write append ioctl lock };
allow <target> <source>:process sigchld;

권한 집합

다른 정책 매크로와 달리 권한 집합은 인수를 사용하지 않으며 일반적으로 함께 사용되는 권한 집합에 대한 약어 역할만 합니다.

예:

  • rw_file_perms - { getattr 읽기 쓰기 추가 ioctl 잠금 열기 }
  • create_dir_perms - { getattr 생성 }
  • append_fifo_file_perms - { getattr 열기 추가 잠금 ioctl }

모든 권한 집합은 obj_perm_sets.spt 파일에 정의되어 있습니다. 매크로 확장기는 기본적으로 허용 규칙만 표시하므로 독립 실행형 권한 집합을 확장하려면 다음과 같이 명령을 조정해야 합니다.

$ macro-expander -M "manage_blk_file_perms" | tail -n 1
{ create open getattr setattr read write append rename link unlink ioctl lock }

이 경우 -M 옵션이 포함된 매크로 확장기는 쿼리가 포함된 완전한 모듈을 생성하므로 모듈 헤더와 require 블록을 무시할 수 있습니다.

또는 "더미" 허용 규칙을 제공합니다. 예를 들면 다음과 같습니다.

$ macro-expander "allow _ _:_ manage_blk_file_perms"
allow _ _:_ { create open getattr setattr read write append rename link unlink ioctl lock }

누락된 인터페이스

인터페이스가 존재하지 않는 유효한 액세스 요구 사항을 허용하려면 gen_require 문을 사용하여 문제를 해결하십시오.

다음 예에서 dhcpd 정책 모듈에는 audit2allow -R 명령의 출력에 나열된 AVC를 기반으로 추가 액세스가 필요합니다.

$ audit2allow -R
type=AVC msg=audit(1674838508.590:840): avc: denied { write } for pid=2383 comm="dhcpd" name="bluetooth.conf" dev="vda2" ino=2 scontext=system_u:system_r:dhcpd_t:s0 tcontext=system_u:object_r:bluetooth_conf_t:s0 tclass=file permissive=1

require {
type bluetooth_conf_t;
type dhcpd_t;
class file write;
}

#============= dhcpd_t ==============
allow dhcpd_t bluetooth_conf_t:file write;

bluetooth_conf_t 파일에 쓰기 위한 인터페이스는 없지만 selinux-policy Github 저장소의 bluetooth.if 파일을 빠르게 검색하면 bluetooth_read_config 가 표시되며 이 사용 사례에 맞게 수정할 수 있습니다.

interface(`bluetooth_read_config',`
gen_require(`
type bluetooth_conf_t;
')

allow $1 bluetooth_conf_t:file read_file_perms;
')

read_file_perms를 write_file_perms 1 로 바꾸고 인터페이스 인수( $1 -> dhcpd_t )를 채워 누락된 액세스를 수정합니다.

또한 추가된 정책을 option_policy 블록으로 묶어야 합니다. 마치 블루투스 모듈에 정의된 실제 인터페이스를 사용하는 것처럼 말입니다.

optional_policy(`
gen_require(`
type bluetooth_conf_t;
')

allow dhcpd_t bluetooth_conf_t:file write_file_perms;
')

프로세스 컨텍스트(도메인)

실행 중인 프로세스에 할당된 유형을 종종 도메인 이라고 합니다. 기본적으로 새 프로세스는 상위 프로세스의 컨텍스트를 상속합니다. 예를 들어, unconfined_t 도메인에서 실행 중인 Bash 셸에서 사용자가 cat 명령을 입력하면 unconfined_t 로도 실행되는 새 프로세스가 생성됩니다.

domtrans_pattern (도메인 전환 패턴)의 일부인 type_transition 규칙을 사용하여 이 동작을 변경할 수 있습니다.

domtrans_pattern(<source>, <entrypoint>, <target>)

이 패턴은 type_transition 규칙을 사용하여 <target> 도메인으로의 자동 전환을 정의하고 전환을 허용하는 규칙 세트를 추가합니다. 일반적으로 init_t (init 데몬 도메인)와 새로 생성된 도메인 간의 전환을 용이하게 하기 위해 init_daemon_domain(<target>, <entrypoint>) 인터페이스의 일부로 사용됩니다.

파일 컨텍스트

새 파일은 해당 파일을 만든 디렉터리에 할당된 유형을 상속합니다. 애플리케이션 코드를 변경하지 않고 사용자 정의 유형을 할당하려면 filetrans_pattern 매크로를 사용하세요.

filetrans_pattern(<process_domain>, <directory>, <target_type>, <class(es)>, [<name>])

다음과 같습니다.

  • <class(es)> - 규칙이 적용되는 객체 클래스(파일, 디렉터리, 소켓 등)
  • [ ] - 주어진 이름 의 객체로 규칙을 제한합니다(선택 사항).

예를 들면 다음과 같습니다.

filetrans_pattern(httpd_t, var_t, httpd_cache_t, file, "apache_cache")

httpd_t 로 실행되는 프로세스가 var_t 라는 디렉터리에 apache_cache 라는 파일을 생성하면 시스템은 결과 파일에 httpd_cache_t 레이블을 설정합니다.

보다 전문화된 매크로 내에서 filetrans_pattern을 사용할 수 있습니다. 여기서 <directory> 인수는 특정 위치에 따라 미리 채워집니다. 예를 들면 다음과 같습니다.

files_var_filetrans(httpd_t, httpd_cache_t, { file dir })

자세한 내용은 RHEL 7 SELinux 사용자 및 관리자 가이드의 파일 이름 전환 섹션을 참조하세요.

기본 파일 컨텍스트 정의

모든 정책 모듈에는 해당 리소스의 기본 SELinux 컨텍스트를 결정하는 파일 컨텍스트 정의 파일 <module>.fc 가 포함되어 있습니다. 이 컨텍스트는 matchpathcon 또는 Restorecon 과 같은 유틸리티에 레이블을 지정하는 데 사용됩니다.

각 정의의 형식은 다음과 같습니다.

pathname_regexp [file_type] security_context

다음과 같습니다.

  • pathname_regexp - 정규식 형식일 수 있는 경로 이름을 정의합니다.
  • file_type - 객체 클래스를 나타내며 비어 있거나(모든 객체 클래스를 의미) 다음 중 하나입니다.
    • -b - 블록 장치
    • -c - 문자 장치
    • -d - 디렉토리
    • -p - 명명된 파이프(FIFO)
    • -l - 심볼릭 링크
    • -s - 소켓 파일
    • -- - 일반 파일
  • security_context - 경로에 할당된 기본 보안 컨텍스트

자세한 내용은 RHEL 7 SELinux 사용자 및 관리자 가이드의 SELinux 컨텍스트 - 파일 레이블 지정 섹션을 참조하세요.

CIL 오류 문제 해결

컴파일된 정책 모듈을 시스템에 로드하면 컴파일러는 모듈 코드를 CIL (Common Intermediate Language)로 변환합니다. 즉, 모듈을 로드하는 동안 발생하는 대부분의 오류는 시스템 정책에 이미 존재하는 유형 정의가 포함된 단순 정책의 다음 예에 표시된 대로 정책의 CIL 버전에 대해 보고됩니다.

$ sepolicy generate --init /usr/bin/cat

$ echo "type abrt_t;" >> cat.te

$ sudo make -f /usr/share/selinux/devel/Makefile cat.pp
Compiling targeted cat module
Creating targeted cat.pp policy package
rm tmp/cat.mod.fc tmp/cat.mod

$ sudo semodule -i cat.pp
Re-declaration of type abrt_t
Previous declaration of type at /var/lib/selinux/targeted/tmp/modules/400/cat/cil:6
Bad type declaration at /var/lib/selinux/targeted/tmp/modules/400/cat/cil:6
Failed to build AST
semodule: Failed!

일부 CIL 관련 오류 메시지가 명확하지 않기 때문에 모듈 소스 코드의 CIL 번역에서 해당 줄을 확인해야 할 수도 있습니다. 이 특별한 경우 오류는 6행과 관련이 있습니다. pp 도구를 사용하여 정책 바이너리를 CIL로 변환하고 문제가 있는 줄을 표시합니다.

$ cat cat.pp | /usr/libexec/selinux/hll/pp > cat.cil
$ head -6 cat.cil | tail -1
(type abrt_t)

CIL 및 해당 키워드가 소스 정책 언어와 어떻게 다른지에 대한 자세한 내용은 SELinux 프로젝트 위키의 CIL 정책 언어 섹션을 참조하세요.

정책 예시

다음 예시 단계를 수행하여 bootupd 패키지에 대한 새 SELinux 정책을 생성하고 테스트합니다. 패키지에는 현재 제한되지 않은 서비스가 포함되어 있습니다.

bootupd 패키지로 설치된 모든 파일을 표시합니다:

$ rpm -ql bootupd
/usr/bin/bootupctl
/usr/lib/.build-id
/usr/lib/.build-id/e8
/usr/lib/.build-id/e8/3c00b4a3c33f2858d6730e9ba95d8286ab6dde
/usr/lib/.build-id/e8/3c00b4a3c33f2858d6730e9ba95d8286ab6dde.1
/usr/lib/systemd/system/bootupd.service
/usr/lib/systemd/system/bootupd.socket
/usr/libexec/bootupd
/usr/share/doc/bootupd
/usr/share/doc/bootupd/README.md
/usr/share/licenses/bootupd
/usr/share/licenses/bootupd/LICENSE

나열된 파일 중에서 두 개의 유닛 파일과 두 개의 바이너리 인 bootupdbootupctl (원격 명령줄 인터페이스)을 볼 수 있습니다. 새 SELinux 정책 준비를 위한 나머지 파일은 무시할 수 있습니다.

bootupd.socket 파일은 서비스가 /var/run/bootupd.sock 소켓을 사용함을 나타냅니다. bootupd 서비스의 단위 파일은 init 시스템을 사용하므로 sepolicy generate 명령과 함께 --init 매개변수를 사용하십시오. bootupd.service 파일의 내용을 보면 /usr/libexec/bootupd가 서비스 바이너리라는 것을 알 수 있습니다. 나머지 파일(유닛 및 소켓 파일)을 --writepath 매개변수의 값으로 사용하여 sepolicy generate 명령이 해당 파일을 정책에 포함하도록 합니다.

$ sepolicy generate --init /usr/libexec/bootupd -w /usr/lib/systemd/system/bootupd.service /usr/lib/systemd/system/bootupd.socket /var/run/bootupd.sock
Created the following files:
/home/user/bootupd/bootupd.te # Type Enforcement file
/home/user/bootupd/bootupd.if # Interface file
/home/user/bootupd/bootupd.fc # File Contexts file
/home/user/bootupd/bootupd_selinux.spec # Spec file
/home/user/bootupd/bootupd.sh # Setup Script

bootupd.te 유형 적용 파일에는 네 가지 새로운 유형이 포함되어 있습니다.
* bootupd_t - bootupd 프로세스용 도메인
* bootupd_exec_t - bootupd 바이너리의 파일 유형
* bootupd_var_run_t - /var/run/bootupd.sock 소켓 유형
* bootupd_unit_file_t - 두 유닛 파일의 파일 유형

init_daemon_domain(bootupd_t, bootupd_exec_t) 매크로는 init 데몬이 bootupd 바이너리를 실행할 때 결과 프로세스가 bootupd_t 도메인에서 실행되도록 보장합니다.

생성된 모듈의 나머지 부분은 bootupd_var_run_t 에 대한 액세스 권한을 부여하는 매크로 그룹을 제외하고 대부분 init 데몬 정책 템플릿입니다.
* manage_dirs_pattern(bootupd_t, bootupd_var_run_t, bootupd_var_run_t) - bootupd_var_run_t 라는 레이블이 붙은 디렉토리를 관리합니다.
* manage_files_pattern(bootupd_t, bootupd_var_run_t, bootupd_var_run_t) - bootupd_var_run_t 라는 라벨이 붙은 파일 관리
* manage_lnk_files_pattern(bootupd_t, bootupd_var_run_t, bootupd_var_run_t) - bootupd_var_run_t 라는 라벨이 붙은 링크 파일을 관리합니다.
* files_pid_filetrans(bootupd_t, bootupd_var_run_t, { dir file lnk_file }) - bootupd_t가 var_run_t 라는 디렉터리에 파일을 생성하면 결과 파일은 bootupd_var_run_t 라는 레이블이 지정됩니다.

/var/run/bootupd.sock 경로가 존재하지 않으므로 sepolicy generate는 디렉터리, 파일 및 링크 파일에 대한 액세스 매크로를 생성합니다. /var/run/bootupd.sock 은 소켓 파일이므로 세 가지 관리_* 패턴을 모두 제거할 수 있습니다. selinux-policy Github 저장소의 file_patterns.spt 파일에는 rw_sock_files_pattern 과 같이 대신 사용할 수 있는 여러 소켓 패턴이 포함되어 있습니다.

systemctl start bootupd.socket 을 사용한 결과로 소켓 파일이 bootupd 가 아닌 systemd 에 의해 생성되므로 files_pid_filetrans 매크로도 중복됩니다. 애플리케이션 바이너리가 소켓 파일을 생성하는 경우 files_pid_filetrans` 줄을 제거하는 대신 { dir file lnk_file }을 { sock_file } 바꿔야 합니다.

bootupd.fc 파일 컨텍스트 구성 파일에는 sepolicy generate 명령에 제공된 모든 경로도 포함되어 있습니다.

/usr/lib/systemd/system/bootupd.service         --      gen_context(system_u:object_r:bootupd_unit_file_t,s0)
/usr/lib/systemd/system/bootupd.socket -- gen_context(system_u:object_r:bootupd_unit_file_t,s0)
/usr/libexec/bootupd -- gen_context(system_u:object_r:bootupd_exec_t,s0)
/var/run/bootupd.sock -- gen_context(system_u:object_r:bootupd_var_run_t,s0)

다시 말하지만, sepolicy generate는 소켓 파일을 올바르게 인식하지 못했습니다. 따라서 객체 클래스를 -- (일반 파일)에서 -s (소켓 파일)로 변경해야 합니다.

/var/run/bootupd.sock           -s      gen_context(system_u:object_r:bootupd_var_run_t,s0)

객체 클래스의 전체 목록은 기본 파일 컨텍스트 정의 섹션을 참조하세요.

이 단계가 끝나면 새 정책이 패키지와 일치합니다. 컴파일하고 설치합니다.

$ make -f /usr/share/selinux/devel/Makefile bootupd.pp
Compiling targeted bootupd module
Creating targeted bootupd.pp policy package
rm tmp/bootupd.mod.fc tmp/bootupd.mod

$ sudo semodule -i bootupd.pp

새 파일 컨텍스트 정의의 영향을 받는 각 경로에서 Restorecon 명령을 사용하여 시스템에 설정을 적용합니다.

$ sudo restorecon -v /usr/libexec/bootupd /usr/lib/systemd/system/bootupd.socket /usr/lib/systemd/system/bootupd.service
Relabeled /usr/libexec/bootupd from system_u:object_r:bin_t:s0 to system_u:object_r:bootupd_exec_t:s0
Relabeled /usr/lib/systemd/system/bootupd.socket from system_u:object_r:systemd_unit_file_t:s0 to system_u:object_r:bootupd_unit_file_t:s0
Relabeled /usr/lib/systemd/system/bootupd.service from system_u:object_r:systemd_unit_file_t:s0 to system_u:object_r:bootupd_unit_file_t:s0

전체 감사를 활성화한 후 서비스를 실행합니다.

$ sudo systemctl start bootupd.socket

$ sudo systemctl start bootupd

파일 컨텍스트와 서비스 프로세스의 도메인을 확인하세요. AVC에 대한 로그를 검색합니다.

$ ls -lZ /var/run/bootupd.sock
srw-------. 1 root root system_u:object_r:bootupd_var_run_t:s0 0 Mar 14 10:45 /var/run/bootupd.sock

$ ps -axZ | grep bootup[d]
system_u:system_r:bootupd_t:s0 2508 ? Ss 0:00 /usr/libexec/bootupd daemon -v

$ sudo ausearch -m AVC | tee avc.log
----
time->Tue Mar 14 10:24:55 2023
type=PROCTITLE msg=audit(1678803895.889:613): proctitle=2F7573722F6C6962657865632F626F6F74757064006461656D6F6E002D76
type=SYSCALL msg=audit(1678803895.889:613): arch=c000003e syscall=41 success=yes exit=4 a0=1 a1=80002 a2=0 a3=8080808080808080 items=0 ppid=1 pid=1995 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="bootupd" exe="/usr/libexec/bootupd" subj=system_u:system_r:bootupd_t:s0 key=(null)
type=AVC msg=audit(1678803895.889:613): avc: denied { create } for pid=1995 comm="bootupd" scontext=system_u:system_r:bootupd_t:s0 tcontext=system_u:system_r:bootupd_t:s0 tclass=unix_dgram_socket permissive=1
----
time->Tue Mar 14 10:24:55 2023
type=PROCTITLE msg=audit(1678803895.889:614): proctitle=2F7573722F6C6962657865632F626F6F74757064006461656D6F6E002D76
type=SYSCALL msg=audit(1678803895.889:614): arch=c000003e syscall=44 success=yes exit=8 a0=4 a1=557718261310 a2=8 a3=4000 items=0 ppid=1 pid=1995 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="bootupd" exe="/usr/libexec/bootupd" subj=system_u:system_r:bootupd_t:s0 key=(null)
type=AVC msg=audit(1678803895.889:614): avc: denied { sendto } for pid=1995 comm="bootupd" path="/run/systemd/notify" scontext=system_u:system_r:bootupd_t:s0 tcontext=system_u:system_r:kernel_t:s0 tclass=unix_dgram_socket permissive=1
----
time->Tue Mar 14 10:24:55 2023
type=PROCTITLE msg=audit(1674838508.590:840): proctitle=2F7573722F6C6962657865632F626F6F74757064006461656D6F6E002D76
type=PATH msg=audit(1674838508.590:840): item=0 name="/boot/efi" inode=413 dev=fc:02 mode=040755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:boot_t:s0 nametype=NORMAL cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0
type=CWD msg=audit(1674838508.590:840): cwd="/usr"
type=SYSCALL msg=audit(1674838508.590:840): arch=c000003e syscall=137 success=yes exit=0 a0=7fff3dc6b6a0 a1=7fff3dc6c7c0 a2=9 a3=fff items=1 ppid=1 pid=2383 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="bootupd" exe="/usr/libexec/bootupd" subj=system_u:system_r:bootupd_t:s0 key=(null)
type=AVC msg=audit(1674838508.590:840): avc: denied { getattr } for pid=2383 comm="bootupd" name="/" dev="vda2" ino=2 scontext=system_u:system_r:bootupd_t:s0 tcontext=system_u:object_r:fs_t:s0 tclass=filesystem permissive=1

서비스가 새 도메인에서 실행 중이고 소켓 파일에 올바른 레이블이 있더라도 SELinux는 여전히 정책에서 허용되지 않는 세 가지 액세스 벡터를 보고했습니다. AVC 메시지에 대한 자세한 설명은 RHEL 9 SELinux 사용 문서의 감사 로그 섹션에서 SELinux 거부를 참조하세요.

새로운 정책에 누락된 허용 규칙을 제안 하려면 audit2allow 도구를 사용할 수 있습니다.

$ audit2allow -i avc.log

#============= bootupd_t ==============
allow bootupd_t fs_t:filesystem getattr;
allow bootupd_t kernel_t:unix_dgram_socket sendto;
allow bootupd_t self:unix_dgram_socket create;

다른 정책 모듈( fs_tkernel_t )에 정의된 유형을 포함하는 정책 모듈을 컴파일할 수 없으므로 필요한 규칙이 포함된 인터페이스 또는 매크로에 대해 -R 옵션과 함께 audit2allow를 사용해야 합니다.

$ audit2allow -R -i avc.log

require {
type bootupd_t;
class unix_dgram_socket create;
}

#============= bootupd_t ==============
allow bootupd_t self:unix_dgram_socket create;
fs_getattr_xattr_fs(bootupd_t)
kernel_dgram_send(bootupd_t)

제안된 인터페이스가 매크로 확장기를 사용하여 필요한 사용 사례를 정확히 포함하는지 확인한 후 이를 정책 모듈에 추가합니다. 또한 option_policy 블록의 기여 모듈 에서 시작되는 모든 인터페이스를 묶어야 합니다. 먼저 허용 모드에서 새 정책을 배포하고 다양한 시스템 구성에서 가능한 한 많은 사용 시나리오를 테스트합니다.

추가 리소스


  1. selinux-policy Github 저장소의 obj_perm_sets.spt 에서 찾을 수 있습니다 ↩︎

Comments