SELinux 개념

SELinux 개념에 익숙해지려면 이 페이지를 검토하세요.

강제 액세스 제어

SELinux(보안이 강화된 Linux)는 Linux 운영체제의 강제 액세스 제어(MAC) 시스템입니다. SELinux는 MAC 시스템으로서, Linux의 친숙한 임의 액세스 제어(DAC) 시스템과 다릅니다. DAC 시스템에서는 소유권 개념이 존재하므로 특정 리소스의 소유자가 리소스와 관련된 액세스 권한을 제어합니다. 이러한 액세스 제어는 일반적으로 대략적이며 의도하지 않은 권한 에스컬레이션이 적용될 수 있습니다. 그러나 MAC 시스템은 모든 액세스 시도에 관한 결정을 위해 중앙 기관에 문의합니다.

SELinux는 다양한 커널 객체 및 이 객체에서 실행되는 민감한 작업을 인식하는 Linux 보안 모듈(LSM) 프레임워크의 일부로 구현되었습니다. 이러한 각 작업이 실행되는 시점에 LSM 후크 함수가 호출되어 불투명한 보안 객체에 저장된 작업 정보를 기반으로 작업을 허용해야 하는지 여부를 결정합니다. SELinux는 이러한 후크의 구현을 제공하고 자체 정책과 결합하는 이러한 보안 객체의 관리를 제공하여 액세스 결정을 판단합니다.

다른 Android 보안 조치와 함께 Android의 액세스 제어 정책은 보안 침해된 기기 및 계정의 잠재적 피해를 크게 제한합니다. Android의 임의 및 강제 액세스 제어와 같은 도구를 사용하면 소프트웨어가 최소 권한 수준에서만 실행되도록 구성할 수 있습니다. 이렇게 하면 공격의 영향이 완화되고 데이터를 잘못 덮어쓰거나 심지어는 잘못 전송하는 프로세스 오류 가능성이 줄어듭니다.

Android 4.3 이상에서 SELinux는 기존의 임의 액세스 제어(DAC) 환경을 씌워주는 강제 액세스 제어(MAC) 우산을 제공합니다. 예를 들어 소프트웨어가 원시 블록 기기에 데이터를 쓰려면 일반적으로 루트 사용자 계정으로 실행되어야 합니다. 기존의 DAC 기반 Linux 환경에서는 루트 사용자가 보안 침해된다면 이 사용자는 모든 원시 블록 기기에 쓸 수 있습니다. 그러나 SELinux를 사용하여 이러한 기기에 라벨을 지정할 수 있으므로 루트 권한이 할당된 프로세스는 연결된 정책에 지정된 기기에만 쓸 수 있습니다. 이런 방식으로 프로세스는 특정 원시 블록 기기 이외의 데이터 및 시스템 설정을 덮어쓸 수 없습니다.

위협의 예와 SELinux로 위협을 해결하는 방법에 관한 자세한 내용은 사용 사례를 참고하세요.

적용 수준

SELinux를 다음과 같이 서로 다른 모드로 구현할 수 있습니다.

  • 허용 - SELinux 보안 정책이 적용되지 않고 기록만 됩니다.
  • 적용 - 보안 정책이 적용되고 기록됩니다. 실패는 EPERM 오류로 표시됩니다.

이러한 선택은 양자택일이며 정책에서 조치를 취할지 아니면 잠재적 실패를 수집만 하도록 할지를 결정합니다. 허용 모드는 구현 과정에서 특히 유용합니다.

유형, 속성, 규칙

Android는 정책에 SELinux의 유형 적용(TE) 구성요소를 사용합니다. 즉, 파일, 프로세스 또는 소켓과 같은 모든 객체에는 객체와 연결된 유형이 있습니다. 예를 들어, 기본적으로 앱의 유형은 untrusted_app입니다. 프로세스의 유형은 도메인이라고도 합니다. 하나 이상의 속성을 사용하여 유형에 주석을 달 수 있습니다. 속성은 동시에 여러 유형을 참조하는 데 유용합니다.

객체는 클래스(예: 파일, 디렉터리, 심볼릭 링크, 소켓)에 매핑되며, 각 클래스의 다양한 액세스 종류는 권한으로 표현됩니다. 예를 들어, file 클래스에는 open 권한이 있습니다. 유형과 속성은 Android SELinux 정책의 일환으로 정기 업데이트되지만, 권한과 클래스는 정적으로 정의되며 새 Linux 버전의 일부로 업데이트되는 경우는 거의 없습니다.

정책 규칙의 형식은 allow source target:class permissions;이며 각 구성요소는 다음과 같습니다.

  • 소스 - 규칙 주체의 유형(또는 속성)입니다. 누가 액세스를 요청하나요?
  • 타겟 - 객체의 유형(또는 속성)입니다. 누가 액세스 요청을 받았나요?
  • 클래스 - 액세스되는 객체의 종류(예: 파일, 소켓)입니다.
  • 권한 - 실행되는 작업 또는 작업 집합(예: 읽기, 쓰기)입니다.

규칙의 예는 다음과 같습니다.

allow untrusted_app app_data_file:file { read write };

위의 예는 앱이 app_data_file이라는 라벨이 지정된 파일을 읽고 쓸 수 있음을 나타냅니다. 다른 유형의 앱이 있습니다. 예를 들어, isolated_app은 매니페스트에 isolatedProcess=true가 포함된 앱 서비스에 사용됩니다. 두 유형에 모두 규칙을 반복하는 대신 Android는 앱을 다루는 모든 유형에 appdomain이라는 속성을 사용합니다.

# Associate the attribute appdomain with the type untrusted_app.
typeattribute untrusted_app, appdomain;

# Associate the attribute appdomain with the type isolated_app.
typeattribute isolated_app, appdomain;

allow appdomain app_data_file:file { read write };

속성 이름을 지정하는 규칙을 작성하면 이름이 속성과 연결된 도메인 또는 유형 목록으로 자동 확장됩니다. 주목할 만한 속성은 다음과 같습니다.

  • domain - 모든 프로세스 유형과 연결된 속성입니다.
  • file_type - 모든 파일 형식과 연결된 속성입니다.

매크로

특히 파일 액세스의 경우 고려해야 할 권한의 종류가 많습니다. 예를 들어, read 권한으로는 파일을 열거나 파일에서 stat을 호출할 수 없습니다. 규칙 정의를 단순화하기 위해 Android는 가장 일반적인 사례를 처리하는 매크로 집합을 제공합니다. 예를 들어, open과 같은 누락된 권한을 포함하기 위해 위의 규칙을 다음과 같이 다시 작성할 수 있습니다.

allow appdomain app_data_file:file rw_file_perms;

유용한 매크로의 더 많은 예는 global_macroste_macros 파일을 참고하세요. 관련 권한 거부로 인한 실패 가능성을 줄이기 위해 가능하면 매크로를 사용해야 합니다.

유형이 정의되면 유형이 나타내는 파일 또는 프로세스와 유형을 연결해야 합니다. 이러한 연결 방법에 관한 자세한 내용은 SELinux 구현을 참고하세요. 규칙에 대한 자세한 내용은 SELinux 노트를 참고하세요.

보안 컨텍스트 및 카테고리

SELinux 정책을 디버깅하거나 파일에 라벨을 지정할 때(file_contexts를 통하거나 ls -Z를 실행할 때) 보안 컨텍스트(라벨이라고도 함)를 사용하게 될 수도 있습니다. 예를 들면, u:r:untrusted_app:s0:c15,c256,c513,c768입니다. 보안 컨텍스트의 형식은 user:role:type:sensitivity[:categories]입니다. 일반적으로 컨텍스트의 user, role, sensitivity 필드는 무시해도 됩니다(특수성 참고). type 필드는 이전 섹션에 설명되어 있습니다. categories는 SELinux의 다중 수준 보안(MLS) 지원의 일부입니다. Android S부터 카테고리는 다음과 같은 용도로 사용됩니다.

  • 다른 앱의 액세스에서 앱 데이터 격리
  • 하나의 실제 사용자에서 다른 사용자로 앱 데이터 격리

특수성

Android가 SELinux에서 제공하는 모든 기능을 사용하는 것은 아닙니다. 외부 문서를 읽을 때는 다음 사항에 유의하세요.

  • AOSP의 정책 대부분은 커널 정책 언어를 사용하여 정의됩니다. Common Intermediate Language(CIL)를 사용하는 데는 몇 가지 예외가 있습니다.
  • SELinux 사용자는 사용하지 않습니다. 유일하게 정의된 사용자는 u입니다. 필요한 경우, 실제 사용자는 보안 컨텍스트의 카테고리 필드를 사용하여 표시됩니다.
  • SELinux 역할 및 역할 기반 액세스 제어(RBAC)는 사용하지 않습니다. 두 가지 기본 역할, 즉 주체의 경우 r, 객체의 경우 object_r을 정의하여 사용합니다.
  • SELinux 민감도는 사용하지 않습니다. 기본 민감도 s0이 항상 설정됩니다.
  • SELinux 불리언은 사용하지 않습니다. 기기용으로 정책이 빌드되면 정책은 기기의 상태에 의존하지 않습니다. 이를 통해 정책의 감사 및 디버깅이 간소화됩니다.