임베디드 시스템에서 SELinux 사용 경험 - 2장

SELinux 프로젝트의 요구사항과 초기 계획을 바탕으로 구현 접근 방식을 정의했습니다.

저자: 코리 미니야드, 몬타비스타 소프트웨어

제2장: 정책 실행

이전 장 에서는 SELinux 프로젝트의 요구 사항과 초기 진행 방향에 대해 이야기했습니다. 이제 실제 구현에 대해 논의해 보겠습니다.

SELinux를 소개합니다

SELinux를 사용해 본 경험이 없으시다면, SELinux Notebook 이나 SELinux By Example 을 참고하시기 바랍니다. 이 자료들은 기존 SELinux 커널 언어를 사용하지만, 기본적인 개념은 동일합니다. 새로운 언어인 CIL( Common Intermediate Language )에 대한 참조 자료는 CIL 문서를 참고하세요. SELinux의 기본 사항을 간략하게 설명드리겠지만, 실제 구현에 필요한 모든 내용을 다루기에는 부족할 수 있습니다. 자세한 내용은 위의 링크에 있는 문서를 참조하시기 바랍니다.

SELinux는 MAC(강제 접근 제어)를 제공합니다. "강제"라는 말은 의무적이라는 의미가 아니라 중앙 집중식 접근 제어를 의미합니다. MAC 시스템에서는 일반적으로 각 사용자가 자신의 파일에 대해 개별 정책을 설정하는 것이 아니라, 하나의 중앙 집중식 접근 제어 정책이 적용됩니다. 이러한 용어는 보안 용어에서 유래되었으며, SELinux는 보안 시스템 전문가들이 설계했기 때문에 일부 용어는 소프트웨어 개념이 아닌 기존 보안 개념에 기반을 두고 있습니다.

SElinux는 기본적으로 권한이 없는 모델로 작동합니다. 기본적으로 아무것도 허용되지 않습니다. 권한을 추가해야만 특정 작업을 허용할 수 있으며, 따라서 매우 세밀하게 설정해야 합니다. 권한은 주체(Subject)와 객체(Object)에 대한 컨텍스트를 통해 제공됩니다. 주체는 객체에 접근하려는 대상입니다. 일반적으로 주체는 프로그램이며, 객체는 그 외 모든 것(파일, 소켓, 파이프, 기능 등)을 의미합니다.

컨텍스트는 최소한 사용자, 역할, 유형의 세 부분으로 구성됩니다. 다단계 보안(MLS)과 관련된 다른 부분을 추가할 수도 있지만, 이는 군사 등급 수준의 정책으로 이 정책에서는 사용되지 않습니다. 이 정책에서는 사용자와 역할이 각각 하나씩만 존재하므로 모든 컨텍스트에 대해 사용자와 역할이 각각 ` <tt>u</tt> 와 ` r 로 설정됩니다. 사실상 유형만 사용됩니다.

해당 유형은 여러 가지 방식으로 사용됩니다. 장치는 객체 컨텍스트를 갖습니다. 예를 들어, /dev/null u:r:null.nodedev 고유한 컨텍스트를 갖습니다.

# ls -Z /dev/null<br /> u:r:null.nodedev /dev/null

파일 시스템에서 파일의 컨텍스트를 레이블이라고 하며, 이러한 컨텍스트를 설정하는 과정을 레이블링이라고 합니다. 파일(및 디렉터리)의 레이블링은 정책에 지정되며 파일 시스템의 정적 파일과 동적으로 생성되는 파일 모두에 적용됩니다.

프로그램이 /dev/null 사용해야 하는 경우, 접근을 허용하는 규칙을 추가해야 합니다. 모든 규칙은 컨텍스트를 기반으로 합니다. 따라서 프로그램의 주체 컨텍스트가 특정 컨텍스트에 대해 허용되어야 합니다. 예를 들어, u:r:lxc.subj 컨텍스트에서 lxc (예: lxc-create )로 실행되는 프로그램이 /dev/null 에 쓰기를 해야 하는 경우, 규칙이 필요합니다.

(allow lxc.subj null.nodedev (chr_file (open write)))

프로그램이 다른 컨텍스트에서 실행되는 다른 프로그램을 실행해야 하는 경우, 이를 전환(transition)이라고 합니다. 주체 전환은 일반적으로 규칙을 통해 허용되어야 하며, typetransition 문에 명시되어야 합니다. 이를 위해서는 파일에 대한 read , execute 및 mmap 접근 권한, 공유 라이브러리 로드에 대한 유사한 접근 권한, 자식 프로그램으로부터 SIGCHLD 받는 권한 등 몇 가지 사항을 허용해야 합니다.

OpenWRT 정책의 기본 사항

하지만 정책을 사용할 때는 일반적으로 그렇게 낮은 수준에서 작업하지 않습니다. OpenWRT 정책 은 이러한 항목을 참조하고 유지 관리하기 쉽게 만드는 많은 매크로와 상용구 코드를 제공합니다. 예를 들어, /dev/null 에 대한 접근 권한의 경우 실제로 해야 할 작업은 src/agent/lxc.cil 의 lxc 블록에 다음 내용을 추가하는 것입니다.

(call .null.write_nodedev_chr_files (subj))

이 부분을 좀 더 자세히 살펴보겠습니다. src/dev/nodedev/nullnodev.cil 파일을 보면 /dev/null 에 대한 참조를 찾을 수 있습니다. 해당 파일에는 /dev/null 을 참조하는 filecon 및 macro 문 다음에 다음과 같은 문장이 있습니다.

(blockinherit .dev.node.obj_template)

` blockinherit dev 블록 안에 있는 ` node 블록의 obj_template 이라는 블록의 내용을 가져온다는 의미입니다. 해당 블록은 src/dev/nodedev.cil 에서 찾을 수 있습니다(`grep`을 사용하여 " block node "를 검색).

(in .dev

(block node

여기서 in 문은 "개발 블록 끝에 내용을 추가하라"는 의미입니다. 그러면 이 파일의 끝에는 다음과 같은 내용이 추가됩니다.

(block obj_template<br /> (blockabstract obj_template)

(blockinherit .dev.node.obj_base_template)<br /> (blockinherit .dev.node.obj_macro_template))))

obj_base_template 은 이 파일에 있습니다.

(block obj_base_template

(context<br /> nodedev_file_context<br /> (.u<br /> .r<br /> nodedev<br /> (systemlow<br /> systemlow)))

(blockabstract obj_base_template)

(type<br /> nodedev)

(call .dev.node.obj_type (nodedev)))

이 특정 코드는 null.nodedev type 과 u:r:null.nodedev 인 null.nodedev_file_context 컨텍스트를 생성합니다. ( systemlow 는 다단계 보안을 위한 것이지만, 우리는 사용하지 않습니다.)

호출문은 obj_type 이라는 매크로를 호출합니다. 예상되는 위치인 nodedev.cil 살펴보아도 해당 매크로는 없습니다. 따라서 해당 파일의 blockinherit 안에 있을 가능성이 높습니다. 해당 파일에는 blockinherit가 몇 개 있는데, obj_type 매크로를 검색하여 가장 가능성이 높은 것을 찾으면 file.cil 에서 유력해 보이는 것을 발견할 수 있으며, 실제로 다음과 같은 내용이 있습니다.

(blockinherit .file.obj_all_macro_template)

nodedev.cil 파일에 있습니다. file.cil 파일에는 다음과 같은 내용이 있습니다.

(macro obj_type ((type ARG1))<br /> (typeattributeset obj_typeattr ARG1))

이렇게 하면 dev.obj_typeattr 에 null.nodedev 유형이 추가됩니다.

이제 nodedev.cil 의 obj_macro_template 을 살펴보면 여러 매크로가 있습니다. 이 매크로들을 살펴보면 다음과 같은 내용을 확인할 수 있습니다.

(macro write_nodedev_chr_files ((type ARG1))<br /> (allow ARG1 nodedev write_chr_file))

따라서 여기서 원래 호출로 다시 치환하면 다음과 같습니다.

(allow lxc.subj null.nodedev write_chr_file)

이것들을 모두 전개하면 다음과 같습니다.

(allow lxc.subj null.nodedev<br /> (chr_file (append getattr ioctl lock open write)))

하지만 이 모든 것은 불필요합니다. 왜냐하면 lxc.cil 다음과 같은 기능이 있기 때문입니다.

(blockinherit .agent.base_template)

이는 결국 다음과 같은 결과를 초래할 것입니다:

(call .null.readwrite_nodedev_chr_files (subj_typeattr))

이는 에이전트 기본 템플릿이 수행하는 여러 기능 중 하나인 .subj.common 블록에서 가져온 것입니다. 따라서 일반적으로 기본적으로 제공되므로 /dev/null 에 대한 특정 액세스 권한을 추가할 필요가 없습니다.

보조 프로그램 및 도구

대상 시스템에서 로그가 표준 감사 위치( /var/log/audit/audit.log )에 저장되는 경우, ausearch라는 도구를 사용하면 로그를 좀 더 쉽게 읽을 수 있습니다. 다음과 같이 입력하면 됩니다.

ausearch -i | less

그러면 상당히 긴 줄이 포함된 출력 결과가 나옵니다. 읽기 쉽게 하려면 sed 사용하여 줄 단위로 나눌 수 있습니다.

ausearch -i | sed -e 's/ : /\n /' -e 's/ scontext=/\n scontext=/'\<br /> -e 's/ tclass=/\n tclass=/' -e 's/ name=/\n name=/'\<br /> -e 's/ path=/\n path=/' | less

그러면 좀 더 깔끔하게 정리된 출력 결과를 얻을 수 있습니다.

----<br /> type=AVC msg=audit(02/15/21 22:07:52.490:34)<br /> avc: denied { write } for pid=860 comm=sm_manager<br /> name=tmp dev="rootfs" ino=1261<br /> scontext=u:r:smm.subj tcontext=u:r:tmp.fs<br /> tclass=dir permissive=1<br /> ----

다음 블로그 게시물도 기대해주세요!

MVSecure 서비스 및 MVXpert 서비스 에 대해 자세히 알아보세요.

Please reach out to discuss your particular scenario today.

전문가와 상담하기 sales@mvista.com으로 이메일 보내기

Keep reading

Related blogs

View all posts
CGX Jun 08, 2026

캐리어급 리눅스에 대한 설명: 2026년 이후 임베디드 개발자가 기대해야 할 사항

최신 임베디드 팀이 고가용성, 결정론적, 보안성, 그리고 장기적인 유지보수가 가능한 Linux 플랫폼에서 기대해야 할 사항들을 살펴보세요.

Read article
MVXpert May 04, 2026

임베디드 리눅스용 Yocto 배포판과 리눅스 배포판 중 어느 것을 선택해야 할까요?

임베디드 리눅스 시스템을 구축하고 유지 관리할 때 Yocto와 리눅스 배포판 중 어떤 것이 더 나은 선택인지 알아보세요.

Read article
MVSecure May 02, 2025

임베디드 시스템에서 SELinux 사용 경험 - 4장

보안 강화 리눅스(SELinux)의 정책 구조에 대해 논의해 보겠습니다.

Read article
nec
nokia
ericsson
samsung
cisco
lg
stjude
guidant
fujitsu
infinera
hp
canon
siemens
motorola
tellabs
nec
nokia
ericsson
samsung
cisco
lg
stjude
guidant
fujitsu
infinera
hp
canon
siemens
motorola
tellabs