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

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

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

제4장: 전반적인 정책 구조

이전 장 에서 정책 파일에서 OpenWRT 정책을 사용하는 방법에 대해 이야기했습니다. 하지만 실제로는 하나의 큰 정책 파일이 아니라, 비교적 일관된 방식으로 여러 개의 개별 파일로 분리되어 있습니다. ` src 디렉토리를 살펴보면 ` cil 로 끝나는 파일들과 ` cil 파일과 이름이 같은 디렉토리들이 많이 있습니다. 이는 정책 전반에 걸쳐 일관된 패턴을 보여주는 중요한 부분입니다. 각 디렉토리에는 특정 주체 또는 객체의 하위 클래스가 포함되어 있으며, ` cil 파일은 해당 객체들의 기본 클래스가 됩니다. 때로는 디렉토리 구조(예: ` /var 는 ` varfile.cil 에, ` /var/run 은 ` varfile/runtimevarfile.cil 에 있음)와 관련이 있지만, 일반적으로는 기능과 관련이 있습니다.

fs

` fs 클래스는 일반적으로 마운트된 파일 시스템과 관련된 것들입니다. 반드시 마운트해야 하는 것은 아니지만, 대부분 ` / ` 디렉터리에서 찾아볼 수 있습니다.

이러한 파일 시스템은 기본 접근 권한을 부여하는 데 사용됩니다. ` /tmp 디렉토리를 검색해야 하는 경우 ` fs/seclabelfs/tmpseclabelfs.cil 파일을 참조하십시오. ` /tmp 에 파일을 생성하려면 ` tmp 블록이 ` .fs.obj_file_macro_template 를 상속받는데, 이 템플릿에는 ` addname_fs_dirs 라는 매크로가 포함되어 있습니다. 따라서 다음과 같이 추가할 수 있습니다.

(call .tmp.addname_fs_dirs (subj))

에이전트의 차단을 해제하여 /tmp 에 파일을 생성할 수 있도록 허용합니다.

` fs 에는 두 가지 주요 하위 클래스가 있습니다. 일반적인 보안 레이블이 있는 파일 시스템용 ` seclabelfs 와 보안 레이블이 적용되지 않은 파일(DOS, ISO9660, proc, SELinux 등)용 ` noseclabelfs .

xxx파일

` src 디렉터리에는 이 패턴과 일치하는 파일이 많이 있습니다. 또한 이러한 파일 중 상당수가 ` fs 디렉터리에 있는 파일과 일치한다는 것을 알 수 있습니다. 이는 의도적인 설계이며, 이러한 클래스는 특정 디렉터리에 있는 파일들을 위해 만들어졌습니다.

파일

` file 클래스는 파일 형식을 다룹니다. 이러한 형식은 위치보다는 기능에 더 중점을 둡니다. 예를 들어 실행 파일은 ` file/execfile.cil 에서 처리됩니다. 파일을 생성하거나 에이전트에서 사용하는 파일이 있는 경우, 해당 파일은 이러한 형식 중 하나로 표현되어야 합니다.

사용자 지정 컨텍스트를 생성하는 경우 파일의 목적에 따라 파일 디렉터리에 있는 클래스 중 하나를 사용하여 이 작업을 수행해야 합니다.

` file.cil 파일은 또한 모든 권한에 대한 클래스 권한 및 기본 클래스 정보를 생성합니다.

예시 파일 접근

` /tmp 디렉터리에 ` asdf 라는 파일을 생성한다고 가정해 보겠습니다. 에이전트가 접근 및 보호 권한을 유지할 수 있도록 해당 파일에 레이블을 지정하고 싶습니다. 이 파일은 데이터 파일입니다. 먼저 데이터 파일을 처리하는 매크로를 만들어 보겠습니다. 에이전트 이름이 myagent이고, 해당 이름으로 된 블록이 있다고 가정해 보겠습니다. 에이전트 블록에 다음 코드를 추가합니다.

; Create macros and types for accessing our data files<br /> (blockinherit .file.data.obj_template)

이렇게 하면 블록에 ` datafile_file_context 가 생성됩니다. 이제 filecon 항목을 추가하세요.

(filecon<br /> "/tmp/asdf"<br /> file<br /> datafile_file_context)

해당 파일에 적절한 레이블을 지정해야 합니다. 하지만 수동으로 파일을 생성하면 ` /tmp 디렉터리의 파일들이 ` u:r:tmp.fs 로 레이블이 지정되기 때문입니다. 이 내용은 ` src/fs/seclabelfs/tmpseclabelfs.cil 파일에서 확인할 수 있습니다. 해당 파일에서 모든 블록 상속 항목을 살펴보면 전환 규칙을 찾을 수 있습니다. 전환 규칙은 `tmp` 블록에 있으므로 다음과 같이 추가합니다.

(macro obj_type_transition_datafile ((type ARG1))<br /> (call .tmp.fs_obj_type_transition<br /> (ARG1 datafile file "asdf")))

이렇게 하면 파일에 올바른 레이블을 지정하는 데 사용할 매크로가 생성됩니다. 맨 위, 에이전트 블록 외부에 다음을 추가합니다.

(in .file<br /> (call myagent.obj_type_transition_datafile (unconfined.subj_typeattr))<br /> )

이 코드는 해당 매크로를 사용하여 파일이 올바른 레이블로 생성되도록 합니다. 본질적으로, tmpseclablfs.cil의 규칙에 따라 제한되지 않은 파일에서 ` u:r:tmp.fs 로, 그리고 위의 규칙에 따라 ` u:r:myagent.datafile 로 레이블이 변경됩니다.

기본 원칙은 객체 생성 시 객체 유형이 규칙에 따라 한 컨텍스트에서 다른 컨텍스트로 전환된다는 것입니다. 객체 유형 전환의 연속을 따라가면 최종 유형을 찾을 수 있습니다.

이제 파일에 접근해야 합니다. 에이전트 블록에 다음 내용을 추가하세요.

; We create/delete /tmp/asdf<br /> (call .tmp.readwrite_fs_dirs (subj))<br /> (call manage_datafile_files (subj))

첫 번째 호출을 통해 /tmp 에 파일을 생성하고 삭제할 수 있습니다. ` manage_fs_dirs 를 사용할 수도 있지만, 이 명령은 필요 이상으로 많은 권한(이름 변경 등)을 부여합니다. 필요한 최소한의 권한만 사용하는 것이 좋습니다. 두 번째 호출은 ` blockinherit 에서 생성한 매크로를 사용하여 데이터 파일에 접근할 수 있도록 해줍니다.

하지만 아직 완전히 끝난 것은 아닙니다. 이 모든 작업을 수행하면 프로그램이 ` /tmp/asdf 를 생성할 때 ` u:r:myagent.datafile 컨텍스트가 아닌 여전히 ` u:r:tmp.fs 컨텍스트로 생성됩니다. 그러나 제한되지 않은 셸에서 생성하면 올바르게 생성됩니다. 이는 추가한 타입 전환에서 ` unconfined 가 전환을 수행하도록 허용했기 때문입니다.

현재 ` myagent.subj 에는 이 작업을 수행할 권한이 없습니다. 따라서 myagent 블록에 규칙을 하나 더 추가해야 합니다.

; Allow myagent.subj to transition our file in /tmp/asdf<br /> (call obj_type_transition_tmpfile (subj))

그러면 모든 게 잘 작동할 겁니다.

예시 새 디렉토리

이제 ` /var/lib/myagent 디렉토리를 생성한다고 가정해 보겠습니다. 검색해 보면 ` /var/lib 는 ` src/varfile/statevarfile.cil 에 있으므로 해당 파일과 상호 작용해야 합니다. 먼저 해당 파일의 클래스를 상속받습니다.

(blockinherit .varfile.state.obj_template)

그리고 우리 파일에 대한 ` filecon 항목이 필요합니다.

(filecon<br /> "/var/lib/myagent"<br /> dir<br /> statevarfile_file_context)<br /> (filecon<br /> "/var/lib/myagent/.*"<br /> any\<br /> statevarfile_file_context)

파일을 생성할 때 상태 전환을 위한 매크로가 필요합니다.

(macro obj_type_transition_statevarfile ((type ARG1))<br /> (call .varfile.statevarfile_obj_type_transition<br /> (ARG1 statevarfile dir "myagent")))

그리고 파일 블록에서 이를 호출해야 합니다.

(in .file<br /> (call myagent.obj_type_transition_statetmpfile<br /> (unconfined.subj_typeattr))<br /> )

물론, 우리는 파일에 접근할 수 있어야 합니다.

; Access to /var/lib/myagent. We grant full access.<br /> (call manage_statevarfile (subj))

이건 흔히 볼 수 있는 일반적인 패턴입니다.

` myagent.subj 가 적절한 컨텍스트로 파일을 생성할 수 있도록 객체 유형 전환을 수행할 필요는 없을 것입니다. 단, 프로그램 자체에서 ` /var/lib/myagent 를 생성하는 경우는 예외입니다. 이 경우 restorecon이 수행하는 레이블링이 적용되지 않습니다. ` /var/lib/myagent 는 restorecon에 의해 이미 적절하게 레이블링되어 있으므로, 그 아래에 생성되는 모든 파일은 해당 레이블을 상속받기 때문입니다.

대리인

에이전트는 일반적으로 프로그램 또는 프로그램 집합입니다. ` agent.cil 파일에는 에이전트의 기본 클래스 정보가 포함되어 있으며, 당연히 ` agent 디렉터리에는 모든 에이전트가 있습니다.

주제

` subj.cil 파일에는 주체를 처리하기 위한 매크로와 템플릿이 포함되어 있습니다. 또한 주체에 대한 권한 처리에 필요한 모든 클래스 권한 등을 생성합니다. 이러한 내용들은 모두 매우 직관적이며, 다른 SELinux 관련 문서에서 자세히 설명되어 있습니다.

파일 컨텍스트.하위 디렉토리

메인 디렉토리(src 디렉토리가 아닌)에 이 파일이 있습니다. 이 파일은 디렉토리 이름을 대체하는 데 사용되는 파일입니다. 예를 들어 다음과 같은 내용이 있습니다.

/bin /usr/bin

즉, ` filecon 관점에서 /bin 에 있는 모든 것을 /usr/bin 에 있는 것처럼 취급하라는 뜻입니다. 이렇게 하면 기본적으로 동일한 기능을 하는 항목들에 대해 수많은 ` filecon 항목을 생성할 필요가 없어집니다.

` xxx_typeattr 과 "all"이 포함된 매크로는 무슨 의미인가요?

블록 안에 비슷하지만 약간씩 다른 내용이 있는 것을 알 수 있을 겁니다. 예를 들어, ` src/varfile.cil 에는 다음과 같은 내용이 있습니다.

(macro readwrite_varfile ((type ARG1))<br /> (allow ARG1 varfile (allfiles (readwrite))))

그리고 이는 .file.obj_all_macro_template을 상속하므로 다음과 같은 내용도 포함됩니다.

(macro readwrite_all ((type ARG1))<br /> (allow ARG1 obj_typeattr (allfiles (readwrite))))

유일한 차이점은 obj_typeattr과 varfile입니다. 다음 두 가지의 차이점은 무엇일까요?

(call .varfile.readwrite_varfile (subj))

그리고

(call .varfile.readwrite_all (subj))

obj_typeattr 은 타입 속성인데, 이름이 그다지 좋지는 않습니다. 실제로는 타입 그룹 또는 타입 집합에 더 가깝습니다. 하나 이상의 타입을 포함할 수 있으며, 이를 사용하는 것은 모든 타입을 그 위치에 모아두는 것과 같습니다. 이 정책에서는 이를 타입 클래스처럼 사용합니다. 따라서 ` .varfile.obj_typeclass 는 ` /var /var 그 안에 있는 모든 것, 즉 ` .varfile.varfile 에서 파생된 모든 것(예: ` /var/run 및 ` /var/lib )을 포함하며, 여기에는 ` .varfile.varfile , ` .varfile.runtimevarfile , ` .varfile.statevarfile 등이 포함됩니다.

` varfile 또는 ` .varfile.varfile 과 같은 참조는 특정 파일 형식만을 가리킵니다. 따라서 이러한 접근 권한을 사용하면 ` /var 디렉터리에 있는 파일이나 해당 디렉터리 내의 특정 컨텍스트를 가진 파일을 직접 열 수 있지만, 컨텍스트가 다른 /var/run 디렉터리에 있는 파일은 열 수 없습니다.

그렇다면 어떤 것을 사용해야 할까요?

최선의 정책은 가능한 한 가장 제한적인 정책을 사용하는 것입니다. ` /var/run 과 ` /var/lib 에는 접근해야 하지만 ` /var/log 에는 접근할 필요가 없다면 ` .varfile.obj_typeattr 을 사용하지 마세요. 이는 최선의 보안 관행이 아닙니다. 특히 다음과 같은 행위는 절대 하지 마세요.

(call .file.manage_all (subj))

또는 그와 비슷한 어떤 것도요. 그렇게 하면 모든 것에 대한 완전한 접근 권한을 갖게 되어, 더 쉽긴 하겠지만 오히려 역효과를 초래할 겁니다.

경우에 따라 ` subj_typeattr 이라는 속성도 있지만, 실제로 많이 사용되는 경우는 드뭅니다. 기본 원리는 동일하지만 프로세스에 적용되는 것입니다.

결론

이 개요는 여러분이 이 문제를 해결하는 데 도움이 될 몇 가지 도구를 제공하겠지만, 어려움을 겪게 될 것입니다.

CIL 파일을 꼼꼼히 살펴보고, 블록을 검색하고, 그 안에 무엇이 있는지 확인하는 데 시간을 좀 투자해야 할 겁니다. 제가 몬타비스타 고객의 SELinux 관련 사례를 다룬 블로그 글이 여러분이 제가 겪었던 초기 어려움을 극복하는 데 도움이 되기를 바랍니다.

#selinux IRC 채널과 SELinux 메일링 리스트에서 많은 도움을 받을 수 있습니다. 사람들이 기꺼이 설명을 도와줄 것입니다. 임베디드 보안 문제에 대한 질문이나 기술 지원이 필요하면 MontaVista에 문의할 수도 있습니다.

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