概览
我们准备了一些示例,以演示如何在不同场景中使用 Sandbox2 以及如何编写政策。
您可以在 //sandboxed_api/sandbox2/examples 中找到它们,详细说明如下。
CRC4
CRC4 示例是有意存在 bug 的 CRC4 校验和计算,用于演示如何沙盒化另一个程序以及如何与该程序通信。
- crc4bin.cc:我们想要沙盒化的程序(即 Sandboxee)
- crc4sandbox.cc:将运行该程序的沙盒程序(即执行器)。
工作原理:
- 执行器使用
::sandbox2::GetDataDependencyFilePath()
从其文件路径启动 Sandboxee。 - 执行程序使用
SendBytes()
通过通信渠道Comms
将输入发送到 Sandboxee。 - Sandboxee 计算 CRC4,并通过通信渠道
Comms
将回复发送回执行程序,执行程序通过RecvUint32()
接收回复。
如果程序执行了除通信(read()
和 write()
)之外的任何系统调用,则会因违反政策而被终止。
静态
静态示例演示了如何对静态链接的二进制文件(例如您没有源代码的第三方二进制文件,这意味着它不知道自己将被沙盒化)进行沙盒化。
- static_bin.cc:Sandboxee 是一个静态 C 二进制文件,可将标准输入中的 ASCII 文本转换为大写。
- static_sandbox.cc:具有相应政策和限制的执行器,使用文件描述符作为 Sandboxee 输入。
工作原理:
- 执行器使用
GetDataDependencyFilepath
从其文件路径启动 Sandboxee,就像 CRC4 一样。 - 它会设置限制,在
/proc/version
上打开文件描述符,并标记该描述符以使用MapFd
在 Sandboxee 中进行映射。 - 该政策允许某些系统调用 (
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
以接收 SandboxeeSTDOUT_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_bin.cc:我们要沙盒化的程序(即 Sandboxee)。
- network_sandbox.cc:将运行该程序的沙盒程序(即执行器)。
network_proxy
此示例演示了处理网络命名空间的另一种方法。在内部,它的工作方式与上述示例完全相同,但以更便捷的 API 形式公开。
Sandboxee 可以通过 2 种不同的方式建立网络连接:
- 自动 - 通过安装自动处理程序,然后发出常规连接调用。
- 手动 - 通过获取
NetworkProxyClient
并直接使用NetworkProxyClient::Connect
。
此示例展示了这两种方法。如果设置了 connect_with_handler
标志,则使用自动模式;否则,使用手动模式。
- network_bin.cc:我们要沙盒化的程序(即 Sandboxee)。
- network_sandbox.cc:将运行该沙盒的程序(执行器)。