다음을 통해 공유


레거시 앱용 AppContainer

AppContainer 환경은 리소스 보안을 제공하기 위해 레거시 앱에 사용할 수 있는 제한적인 프로세스 실행 환경입니다. AppContainer 앱의 프로세스 및 해당 자식 프로세스는 경량 앱 컨테이너 내에서 실행되며, 이 컨테이너는 특별히 부여된 리소스에만 액세스할 수 있습니다. 또한 파일 시스템 및 레지스트리 가상화를 사용하여 격리됩니다. 따라서 AppContainer에서 구현된 앱은 제한된 할당된 리소스 외부에서 악의적인 작업을 허용하도록 해킹할 수 없습니다.

패키지된 앱과 패키지되지 않은 앱 모두에 대해 AppContainer는 안전하고 안전한 엔지니어링 방법을 나타냅니다.

AppContainer는 원래 LowBox라는 이름으로 지정되었습니다(Windows 8 릴리스 이전). 해당 레거시 이름은 NtCreateLowBoxToken과 같은 API 이름에서 볼 수 있습니다.

패키지에 포함된 앱

MSIX를 사용하여 패키지된 앱을 가져와 AppContainer 환경에서 실행하도록 쉽게 구성할 수 있습니다. UWP(유니버설 Windows 플랫폼) 앱은 자동으로 AppContainer 앱입니다. 그러나 MSIX로 패키지된 데스크톱 앱을 AppContainer 앱으로 구성할 수도 있습니다. MSIX를 사용하여 패키지하는 경우 AppContainer를 특히 쉽게 사용할 수 있습니다. 자세한 정보, 시나리오 및 구성 예제는 MSIX AppContainer 앱을 참조 하세요.

패키지되지 않은 앱

패키지되지 않은 앱도 앱 컨테이너에서 실행할 수 있습니다. 앱 컨테이너에서 프로세스를 만들려면 AppContainer 정의(또는 프로필)가 필요합니다. 따라서 패키지된 앱에서 AppContainer를 사용하는 것이 더 쉽습니다. 사용자에 대한 패키지를 등록할 때 배포 스택은 필요한 AppContainer 프로필(예 : CreateAppContainerProfile)을 만들기 위해 특정 Win32 API를 호출합니다. 사용자에 대한 패키지 등록을 취소하면 배포 스택에서 AppContainer 프로필(DeleteAppContainerProfile)을 제거하는 작업을 수행합니다. 앱을 패키징하지 않는 경우 Win32 API를 직접 호출하여 동일한 작업을 수행해야 합니다. 하지만 복잡할 수 있습니다.

낮은 무결성 수준을 사용한 대부분의 패키지되지 않은 앱은 이제 제한된 실행 환경을 제공하는 더 나은 방법으로 AppContainer를 사용합니다.

앱 컨테이너에서 실행되는 패키지되지 않은 프로세스가 CreateProcess를 호출하는 경우 자식 프로세스는 일반적으로 부모의 토큰을 상속합니다. 해당 토큰에는 IL(무결성 수준) 및 앱 컨테이너 정보가 포함됩니다. 값이 상승/중간/낮음/appContainer인 단일 축을 생각하지 않는 것이 가장 좋습니다. 대신 앱 컨테이너에 있거나 없는 것은 두 번째 및 직교 속성입니다. 즉, 앱 컨테이너에 있는 경우 IL(무결성 수준)이 항상 낮습니다.

AppContainer 환경 사용의 이점

AppContainer 환경의 주요 목표는 다른 앱과의 호환성을 기본 최대한 시스템 상태와 앱 상태를 분리하는 것입니다. Windows는 런타임에 파일 시스템 및 레지스트리에 적용되는 특정 변경 내용을 검색하고 리디렉션하여 이를 수행합니다(가상화라고 함). AppContainer 앱은 자체 가상 레지스트리 및 애플리케이션 데이터 폴더에 쓰고, 앱이 제거되거나 다시 설정되면 해당 데이터가 삭제됩니다. 다른 앱은 AppContainer 앱의 가상 레지스트리 또는 가상 파일 시스템에 액세스할 수 없습니다.

따라서 AppContainer 환경은 앱의 보안 샌드박싱을 제공합니다. 특정 권한 없이 하드웨어, 파일, 레지스트리, 기타 앱, 네트워크 연결 및 네트워크 리소스에 액세스하지 않도록 앱을 격리합니다. 개별 리소스는 다른 리소스를 노출하지 않고도 대상으로 지정할 수 있습니다. 또한 사용자 ID는 사용자와 앱의 연결인 고유한 ID를 사용하여 보호됩니다. 및 리소스는 최소 권한 모델을 사용하여 부여됩니다. 이는 다른 리소스에 대한 액세스 권한을 얻기 위해 사용자를 가장하는 앱으로부터 추가로 보호합니다.

앱 컨테이너에서 실행을 테스트하는 예제 코드

C# 또는 C++ 프로젝트에서 아래 코드 예제 중 적절한 하나를 사용하여 프로세스가 앱 컨테이너 내에서 실행 중인지 여부를 확인할 수 있습니다. 각 예제에 대해 코드가 실행된 후 isAppContainer이 0이 아닌 경우(또는true) 프로세스가 앱 컨테이너 내에서 실행되고 있습니다.

C#(P/Invoke)

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetCurrentProcess();

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool OpenProcessToken(
    IntPtr ProcessHandle,
    UInt32 DesiredAccess,
    out IntPtr TokenHandle);

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetTokenInformation(
    IntPtr TokenHandle,
    uint TokenInformationClass,
    out uint TokenInformation,
    uint TokenInformationLength,
    out uint ReturnLength);

UInt32 TOKEN_QUERY = 0x0008;
IntPtr tokenHandle;

if (!OpenProcessToken(
    GetCurrentProcess(),
    TOKEN_QUERY,
    out tokenHandle))
{
    // Handle the error.
}

uint isAppContainer;
uint TokenIsAppContainer = 29;
uint tokenInformationLength = sizeof(uint);

if (!GetTokenInformation(
    tokenHandle,
    TokenIsAppContainer,
    out isAppContainer,
    tokenInformationLength,
    out tokenInformationLength))
{
    // Handle the error.
}

C++(WIL)

이 예제에서는 WIL(Windows 구현 라이브러리)을 사용합니다. WIL을 설치하는 편리한 방법은 Visual Studio로 이동하여 NuGet 패키지 관리 프로젝트를>클릭하는 것입니다.>검색 상자에 Microsoft.Windows.ImplementationLibrary를 찾아보거나 입력하거나 붙여넣고 검색 결과에서 항목을 선택한 다음 설치를 클릭하여 해당 프로젝트에 대한 패키지를 설치합니다.

#include <wil\token_helpers.h>
...
bool isAppContainer = wil::get_token_is_app_container();

wil::get_token_is_app_container_nothrowwil::get_token_is_app_container_failfast 함수는 대체 오류 처리 전략을 제공합니다. 자세한 내용은 wil\token_helpers.h를 참조하세요.

C++(정식)

#include <windows.h>
...
HANDLE tokenHandle{};
DWORD isAppContainer{};
DWORD tokenInformationLength{ sizeof(DWORD) };

if (!::OpenProcessToken(
    GetCurrentProcess(),
    TOKEN_QUERY,
    &tokenHandle))
{
    // Handle the error.
}

if (!::GetTokenInformation(
    tokenHandle,
    TOKEN_INFORMATION_CLASS::TokenIsAppContainer,
    &isAppContainer,
    tokenInformationLength,
    &tokenInformationLength
))
{
    // Handle the error.
}

이 섹션의 내용

레거시 앱에 AppContainer를 사용하는 방법에 대한 자세한 내용은 다음 항목을 참조하세요.

항목 설명
AppContainer 격리 격리는 AppContainer 실행 환경의 주요 목표입니다. 불필요한 리소스 및 기타 앱에서 앱을 격리하면 악의적인 조작 기회가 최소화됩니다. 최소 권한에 따라 액세스 권한을 부여하면 앱과 사용자가 권한 이외의 리소스에 액세스할 수 없습니다. 리소스에 대한 액세스를 제어하면 프로세스, 디바이스 및 네트워크가 보호됩니다.
AppContainer 구현 AppContainer는 프로세스 토큰에 새 정보를 추가하고, SeAccessCheck()를 변경하여 구현되므로 모든 레거시 ACL(수정되지 않은 액세스 제어 목록) 개체는 기본적으로 AppContainer 프로세스의 액세스 요청을 차단하고 AppContainers에서 사용할 수 있어야 하는 ACL 개체를 다시 만듭니다.