개요

다양한 시나리오에서 Sandbox2를 사용하는 방법과 정책을 작성하는 방법을 보여주는 몇 가지 예시를 준비했습니다.

//sandboxed_api/sandbox2/examples에서 확인할 수 있습니다. 자세한 설명은 아래를 참고하세요.

CRC4

CRC4 예시는 의도적으로 버그가 있는 CRC4 체크섬 계산으로, 다른 프로그램을 샌드박스 처리하는 방법과 통신하는 방법을 보여줍니다.

  • crc4bin.cc: 샌드박스에 포함할 프로그램 (즉, 샌드박스 대상)
  • crc4sandbox.cc: 이를 실행할 샌드박스 프로그램 (즉, 실행기)입니다.

기본 원리:

  1. 실행기는 ::sandbox2::GetDataDependencyFilePath()를 사용하여 파일 경로에서 Sandboxee를 시작합니다.
  2. 실행기는 SendBytes()를 사용하여 통신 채널 Comms를 통해 샌드박스에 입력을 전송합니다.
  3. 샌드박스 처리된 프로세스는 CRC4를 계산하고 통신 채널 Comms를 통해 실행기에 응답을 다시 전송하며, 실행기는 RecvUint32()로 응답을 수신합니다.

프로그램이 통신 (read()write()) 이외의 syscall을 실행하면 정책 위반으로 인해 종료됩니다.

정적

정적 예에서는 소스가 없어 샌드박스에 적용될지 모르는 서드 파티 바이너리와 같은 정적으로 연결된 바이너리를 샌드박스 처리하는 방법을 보여줍니다.

  • static_bin.cc: Sandboxee는 표준 입력의 ASCII 텍스트를 대문자로 변환하는 정적 C 바이너리입니다.
  • static_sandbox.cc: 정책과 제한이 있고 샌드박스 입력에 파일 설명자를 사용하는 실행기입니다.

기본 원리:

  1. 실행기는 CRC4와 마찬가지로 GetDataDependencyFilepath를 사용하여 파일 경로에서 Sandboxee를 시작합니다.
  2. 제한을 설정하고 /proc/version에서 파일 설명자를 열고 샌드박스에서 MapFd로 매핑되도록 표시합니다.
  3. 이 정책을 사용하면 정책 위반으로 인해 종료되는 대신 일부 시스템 호출 (open)이 오류 (ENOENT)를 반환할 수 있습니다. 이는 어떤 시스템 호출이 이루어지는지 수정할 수 없는 서드 파티 프로그램을 샌드박싱할 때 유용합니다. 대신 이러한 호출이 정상적으로 실패하도록 할 수 있습니다.

도구

이 도구 예시는 자체 정책을 개발하고 Sandbox2 API를 실험하는 도구이자 기능 데모입니다.

  • sandbox2tool.cc: 다음을 보여주는 실행기
    • 다른 바이너리를 샌드박스 처리하는 방법
    • 파일 시스템 검사를 설정하는 방법
    • 실행기가 Sandboxee를 비동기식으로 실행하여 출력을 점진적으로 읽을 수 있는 방법

직접 사용해 보세요.

Bazel

bazel run //sandboxed_api/sandbox2/examples/tool:sandbox2tool -- \
--sandbox2tool_resolve_and_add_libraries \
--sandbox2tool_additional_bind_mounts /etc \
/bin/cat /etc/hostname

CMake + Ninja

cd build-dir
ninja sandbox2_sandbox2tool && \
./sandbox2_sandbox2tool \
--sandbox2tool_resolve_and_add_libraries \
--sandbox2tool_additional_bind_mounts /etc \
/bin/cat /etc/hostname

Google3 (Blaze)

blaze run //third_party/sandboxed_api/sandbox2/examples/tool:sandbox2tool -- \
 --sandbox2tool_resolve_and_add_libraries \
 --sandbox2tool_additional_bind_mounts /etc \
 /bin/cat /etc/hostname

플래그:

  • --sandbox2tool_resolve_and_add_libraries를 사용하여 Sandboxee에 필요한 라이브러리를 확인하고 마운트합니다.
  • --sandbox2tool_additional_bind_mounts <PATHS>를 사용하여 Sandboxee에 추가 디렉터리를 제공합니다.
  • --sandbox2tool_keep_env - 현재 환경 변수를 유지합니다.
  • 샌드박스 처리된 STDOUT_FILENO (1)를 수신하고 로컬로 출력하는 --sandbox2tool_redirect_fd1
  • --sandbox2tool_cpu_timeout: CPU 시간 제한을 초 단위로 설정
  • --sandbox2tool_walltime_timeout: 벽시계 시간 제한을 초 단위로 설정
  • --sandbox2tool_file_size_creation_limit: 생성된 파일의 최대 크기를 설정합니다.
  • 샌드박스의 현재 작업 디렉터리를 설정하는 --sandbox2tool_cwd

custom_fork

custom_fork 예시에서는 바이너리를 초기화한 다음 상위 실행기에서 오는 fork() 요청을 기다리는 샌드박스를 만드는 방법을 보여줍니다.

이 모드는 다른 유형의 샌드박스와 관련하여 성능을 향상시킬 수 있습니다. 여기서는 Sandboxee의 새 인스턴스를 만드는 데 새 바이너리를 실행할 필요가 없고 기존 바이너리를 포크하기만 하면 되기 때문입니다.

  • custom_fork_bin.cc: 새 Sandboxee를 생성하기 위해 Client::WaitAndFork을 통해 fork() 요청을 수신하는 맞춤 포크 서버입니다.
  • custom_fork_sandbox.cc: 맞춤 포크 서버를 시작하는 실행기입니다. 그런 다음 새 Sandboxee를 생성(fork()를 통해)하도록 새 실행기를 통해 요청을 전송합니다.

네트워크

기본적으로 사용 설정되는 네트워크 네임스페이스는 샌드박스 처리된 프로세스가 외부 세계에 연결되지 못하도록 합니다. 이 예시에서는 이 문제를 처리하는 방법을 보여줍니다.

연결이 실행기 내에서 초기화되고 결과 소켓이 ::sandbox2::Comms::SendFD()를 통해 전달됩니다. 샌드박스에서는 ::sandbox2::Comms::RecvFD()를 사용하여 소켓을 수신하고 이 소켓을 사용하여 평소와 같이 데이터를 교환할 수 있습니다.

  • network_bin.cc: 샌드박스 처리할 프로그램 (즉, 샌드박스 대상)입니다.
  • network_sandbox.cc: 실행할 샌드박스 프로그램 (즉, 실행기)

network_proxy

이 예시에서는 네트워크 네임스페이스를 처리하는 다른 방법을 보여줍니다. 내부적으로는 위의 예와 정확히 동일한 방식으로 작동하지만 더 편리한 API로 노출됩니다.

샌드박스에서는 다음과 같은 두 가지 방법으로 네트워크 연결을 설정할 수 있습니다.

  • automatic - 자동 핸들러를 설치한 다음 정기 연결 호출을 실행합니다.
  • manual: NetworkProxyClient를 획득하고 NetworkProxyClient::Connect를 직접 사용합니다.

이 예시에서는 두 가지 방법을 모두 보여줍니다. connect_with_handler 플래그가 설정되면 자동 모드가 사용되고, 그렇지 않으면 수동 모드가 사용됩니다.