概览
我们准备了一些示例来演示如何在不同场景中使用 Sandbox2 以及如何编写政策。
您可以在 //sandboxed_api/sandbox2/examples 中找到这些代码,详情请参阅下文。
CRC4
CRC4 示例是刻意为 CRC4 校验和计算错误,它演示了如何沙盒化其他程序以及如何与其通信。
- crc4bin.cc:我们要沙盒的程序(即 Sandboxee)
- crc4sandbox.cc:将运行 crc4sandbox.cc 的沙盒程序(即执行器)。
运作方式:
- 执行器使用
::sandbox2::GetDataDependencyFilePath()
从其文件路径启动 Sandboxee。 - Executor 使用
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()
请求。
与其他类型的沙盒相比,此模式有望提升性能,因为在本例中,创建新的 Sandboxees 实例不需要执行新的二进制文件,只需创建现有二进制文件的分支即可
- custom_fork_bin.cc:自定义分支服务器,通过
Client::WaitAndFork
接收对fork()
的请求,以生成新的 Sandboxees。 - custom_fork_sandbox.cc:执行器,用于启动自定义分支服务器。然后,它会通过新的执行器向其发送请求,以(通过
fork()
)生成新的 Sandboxee。
网络
网络命名空间(默认启用)可防止沙盒化进程连接到外部世界。此示例演示了如何处理此问题。
连接在执行器内初始化,并通过 ::sandbox2::Comms::SendFD()
传递生成的套接字。Sandboxee 使用 ::sandbox2::Comms::RecvFD()
接收套接字,然后可照常使用此套接字交换数据。
- network_bin.cc:我们要沙盒化的程序(即 Sandboxee)。
- network_sandbox.cc:将运行此沙盒的沙盒程序(即执行程序)。
network_proxy
此示例演示了处理网络命名空间的另一种方法。在内部,它的运作方式与上例完全相同,但作为更方便的 API 公开。
Sandboxee 可以通过以下 2 种不同的方式建立网络连接:
- 自动 - 安装自动处理程序,然后发出常规连接调用。
- manual - 获取
NetworkProxyClient
并直接使用NetworkProxyClient::Connect
。
以下示例展示了这两种方法。如果设置了 connect_with_handler
标志,则会使用自动模式;否则,会使用手动模式。
- network_bin.cc:我们要沙盒化的程序(即 Sandboxee)。
- network_sandbox.cc:运行此脚本的沙盒程序(执行程序)。