示例

概览

我们准备了一些示例来演示如何在不同场景中使用 Sandbox2 以及如何编写政策。

您可以在 //sandboxed_api/sandbox2/examples 中找到这些代码,详情请参阅下文。

CRC4

CRC4 示例是刻意为 CRC4 校验和计算错误,它演示了如何沙盒化其他程序以及如何与其通信。

  • crc4bin.cc:我们要沙盒的程序(即 Sandboxee)
  • crc4sandbox.cc:将运行 crc4sandbox.cc 的沙盒程序(即执行器)。

运作方式:

  1. 执行器使用 ::sandbox2::GetDataDependencyFilePath() 从其文件路径启动 Sandboxee。
  2. Executor 使用 SendBytes() 通过通信通道 Comms 向 Sandboxee 发送输入。
  3. Sandboxee 会计算 CRC4,并通过通信通道 Comms 将其回复发回给执行器,执行器会使用 RecvUint32() 接收该消息。

如果程序发出除通信(read()write())以外的任何系统调用,则会由于违反政策而终止。

静态

此静态示例演示了如何对静态链接的二进制文件(如您没有其源代码的第三方二进制文件)进行沙盒化处理,这意味着它不知道将对其进行沙盒化处理。

  • static_bin.cc:Sandboxee 是一个静态 C 二进制文件,可将 ASCII 文本从标准输入转换为大写。
  • static_sandbox.cc:执行器及其政策和限制,以及对 Sandboxee 输入使用文件描述符。

运作方式:

  1. 执行器会使用 GetDataDependencyFilepath 从其文件路径启动 Sandboxee,就像 CRC4 一样。
  2. 它会设置限制,在 /proc/version 上打开文件描述符,并使用 MapFd 将其标记为在 Sandboxee 中映射。
  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,用于保留当前环境变量
  • --sandbox2tool_redirect_fd1,用于接收 Sandboxee STDOUT_FILENO (1) 并在本地输出
  • --sandbox2tool_cpu_timeout:用于设置 CPU 超时(以秒为单位)
  • --sandbox2tool_walltime_timeout,用于设置实际用时超时(以秒为单位)
  • --sandbox2tool_file_size_creation_limit,用于设置所创建文件的大小上限
  • --sandbox2tool_cwd,用于设置沙盒的当前工作目录

custom_fork

custom_fork 示例演示了如何创建沙盒来初始化二进制文件,然后等待来自父级执行程序的 fork() 请求。

与其他类型的沙盒相比,此模式有望提升性能,因为在本例中,创建新的 Sandboxees 实例不需要执行新的二进制文件,只需创建现有二进制文件的分支即可

  • custom_fork_bin.cc:自定义分支服务器,通过 Client::WaitAndFork 接收对 fork() 的请求,以生成新的 Sandboxees。
  • custom_fork_sandbox.cc:执行器,用于启动自定义分支服务器。然后,它会通过新的执行器向其发送请求,以(通过 fork())生成新的 Sandboxee。

网络

网络命名空间(默认启用)可防止沙盒化进程连接到外部世界。此示例演示了如何处理此问题。

连接在执行器内初始化,并通过 ::sandbox2::Comms::SendFD() 传递生成的套接字。Sandboxee 使用 ::sandbox2::Comms::RecvFD() 接收套接字,然后可照常使用此套接字交换数据。

network_proxy

此示例演示了处理网络命名空间的另一种方法。在内部,它的运作方式与上例完全相同,但作为更方便的 API 公开。

Sandboxee 可以通过以下 2 种不同的方式建立网络连接:

  • 自动 - 安装自动处理程序,然后发出常规连接调用。
  • manual - 获取 NetworkProxyClient 并直接使用 NetworkProxyClient::Connect

以下示例展示了这两种方法。如果设置了 connect_with_handler 标志,则会使用自动模式;否则,会使用手动模式。