示例

概览

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

您可以在 //sandboxed_api/sandbox2/examples 中找到它们,请参阅下面的详细说明。

CRC4

CRC4 示例是故意计算 bug 的 CRC4 校验和,它演示了如何将其他程序以沙盒的形式进行标识以及如何与其他程序进行通信。

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

工作原理:

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

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

静态

该静态示例演示了如何将静态关联的二进制文件(例如您未获得源代码的第三方二进制文件)沙盒化,这意味着它不知道它会经过沙盒化。

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

工作原理:

  1. 执行器使用 GetDataDependencyFilepath 从文件路径启动沙盒,就像 CRC4 一样。
  2. 它会设置限制,在 /proc/version 上打开一个文件描述符,并使用 MapFd 将其标记为在沙盒中映射。
  3. 此政策允许某些系统调用 (open) 返回错误 (ENOENT),而不是因违反政策而终止。这在对第三方程序进行沙盒化时非常有用,因为在这种情况下,我们无法修改哪些系统调用,而是可以使其正常停止。

工具

该工具示例不仅是您自己的政策制定工具,并且还尝试使用 Sandbox2 API 进行实验,并演示了其功能。

  • sandbox2tool.cc:执行程序,用于演示:
    • 如何运行另一个沙盒化沙盒
    • 如何设置文件系统检查;以及
    • 执行器如何异步运行沙盒以逐步读取输出。

亲自尝试一下:

Bazel

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

CMake + 忍者

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>,用于向沙盒提供其他目录
  • --sandbox2tool_keep_env:用于保留当前环境变量
  • --sandbox2tool_redirect_fd1,用于接收沙盒 STDOUT_FILENO (1) 并在本地输出它
  • --sandbox2tool_cpu_timeout:用于设置 CPU 超时(以秒为单位)
  • --sandbox2tool_walltime_timeout,用于设置实际用时超时(以秒为单位)
  • --sandbox2tool_file_size_creation_limit,用于设置已创建文件的大小上限
  • --sandbox2tool_cwd,用于设置沙盒的当前工作目录

自定义分支

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

此模式可针对其他类型的沙盒提供更高的性能,因为在此模式下,创建新 Sandboxee 实例不需要执行新的二进制文件,只需派生现有的二进制文件

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

影音平台

网络命名空间默认处于启用状态,可阻止沙盒化进程连接到外部环境。此示例演示了如何处理此问题。

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

网络代理

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

沙盒可以通过以下两种方式建立网络连接:

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

此示例展示了这两种方法。设置 connect_with_handler 标志时使用自动模式,否则使用手动模式。