示例

概览

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

您可以在 //sandboxed_api/sandbox2/examples 中找到它们,详细说明如下。

CRC4

CRC4 示例是有意存在 bug 的 CRC4 校验和计算,用于演示如何沙盒化另一个程序以及如何与该程序通信。

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

工作原理:

  1. 执行器使用 ::sandbox2::GetDataDependencyFilePath() 从其文件路径启动 Sandboxee。
  2. 执行程序使用 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() 请求。

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

  • custom_fork_bin.cc:自定义 fork 服务器,接收 fork()(通过 Client::WaitAndFork)请求以生成新的沙盒进程。
  • custom_fork_sandbox.cc:执行器,用于启动自定义 fork 服务器。然后,它会向该服务发送请求(通过新的执行器),以生成(通过 fork())新的沙盒进程。

网络

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

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

network_proxy

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

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

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

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