在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:Rocker开源软件地址:https://gitee.com/kt10/rocker开源软件介绍:
1. ROCKERROCKER 是一个 通过将 App 程序文件及其它合适的文件压缩成 沙箱功能的安全性保证, 来自于
1.1. 亮点与特性
1.2. 用户指南1.2.1. 代码结构(简略)整个项目分成 Client 端与 Server 端两部分, 类似于一个传统的 CS 架构, Client 端以库的形式给调用方使用. ..├── core/ # [Rust 代码] 服务端核心逻辑实现├── rocker_server/ # [Rust 代码] CS server 端实现├── librocker_client/ # [C 代码] CS client 库实现├── librocker_client_wrapper/ # [Rust 代码] 通过 ffi 封装的 librocker_client 库, 用于测试├── tests/ # [Rust 代码] 测试用例├── README.md # 项目主文档└── tools/ 1.2.2. 环境配置与编译1.2.2.1. 环境需求对应的官方说明文档, 链接如下: 1.2.2.2. 编译理论上本项目可在任何 crosstool-ng 和 rust 支持的架构体系上编译并运行, 非 x86(_x64) 平台上默认静态链接 musl 或 uclibc 库, 以简化对运行环境的依赖. 如下以 # 编译安装, 安装路径是项目根目录内的 install_dirmake TARGET=armv7-linux-musleabihf release# 功能测试make TARGET=armv7-linux-musleabihf test# 性能测试make TARGET=armv7-linux-musleabihf bench 1.2.3. 客户端库调用示例如下: // 由调用方定义的, 将在 ROCKER 中执行的回调函数及其参数void *your_args = NULL;int start_your_APP(void *args){};// 初始化一个空白的 RockerRequest 结构体RockerRequest req = ROCKER_request_new();// 为 RockerRequest 结构体赋值req.app_id = 1000;req.uid = 1000;req.gid = 1000;req.app_pkg_path = "/tmp/your_APP.squashfs";req.app_exec_dir = "/var/your_APP/execdir";req.app_data_dir = "/var/your_APP/datadir";req.app_overlay_dirs = { "/usr", "/var", "/etc", "/home", "/root" };// 尝试在 ROCKER 中运行 APPRockerResult res = ROCKER_enter_rocker(&req, start_my_APP, my_args);if (ROCKER_ERR_success != res.err_no) { // 处理错误}// APP 运行结束, 清理环境kill(res.guard_pid, SIGKILL);// 更稳健的清理方法RockerResult res2 = ROCKER_get_guardname(res.guard_pid);if (ROCKER_ERR_success == res2.err_no && \ 0 == strcmp(res.guard_name, res2.guard.name)) { kill(res.guard_pid, SIGKILL);} 详情参见 librocker_client. 1.3. 架构说明以下将以'时序图'的形式论述具体的逻辑架构. 1.3.2. 时序图
NOTE: RockerClient 通常与 AppMaster 属于同一进程, 文档中出于可读性的考虑, 对二者做了逻辑层面的拆分. 1.3.2.1. 概览
AppMaster 调用 RockerClient 的 API, 向 RockerMaster 请求创建新的 rocker, 并在其中运行指定的 App. 新 Rocker 的具体配置信息由 AppMaster 在其请求信息中指定.
RockerMaster 收到请求, 创建一个新的 rocker 虚拟沙箱环境, 其中的 1 号进程就是 RockerGuard, RockerGuard 扮演的角色类似于常规 Linux 系统中的 init 或 systemd 进程, 若该进程退出, 即意味着其所在的虚拟沙箱环境的完全销毁(所有的进程及磁盘挂载都会被 Kernel 自动清理).
RockerMaster 创建完对应的 RockerGuard 实例, 后续的与 AppMaster 的交互, 将由 RockerGuard 直接执行, RockerMaster 不再参与.
RockerGurad 根据 AppMaster 的要求, 创建对应的 rocker 环境, 此过程需要 CAP_SYS_ADMIN 能力或 root 权限, 具体的细节将在接下来的 1.3.1.1 节中描述.
RockerGuard 将创建好的 rocker 入口, 发送给 RockerClient.
RockerClient 进入新创建的 rocker 环境, 在其中将 App 启动起来, 具体的细节将在 1.3.1.3 节中描述.
App 启动完成之后, RockerClient 将 Guard 及 App 的 PID 等相关信息返回 AppMaster, 以供 AppMaster 的后续管理. 至此, RockerClient 完成其在单次 App 启动中使命, 不再参与后续环节.
AppMaster 停止 App 的方式有两种, 一种是按照常规的逻辑自行管理, 另一种是通过 kill RockerGuard 的方式自动完成. 两种方式各有利弊,
RockerGuard 自动退出的条件是其所在的 rocker 虚拟沙箱中的其它进程已经全部退出, 若 AppMaster 遗漏了某个进程, 将会导致此 rocker 的资源永远不被释放.
RockerGuard 退出后, RockerMaster 收到 SIGCHLD 信号, 可选的执行一些对应的内部逻辑.
内核探知到某个 rocker(pid namespace) 中的 1 号进程退出.
内核自动清理其中的所有资源(包括递归产生的衍生资源). 1.3.2.2. 子图 {#1}
RockerMaster 以带 CLONE_MNT 与 CLONE_PID 标志的 clone 接口创建 RockerGuard 实例, 参见 man clone(2).
RockerGuard 调用 ioctl 调口获取可用的 loop 设备, 参见 man loop(4).
将打包成 squashfs 格式的 App 程序包, 绑定到新获取的 loop 设备上, RockerGuard 将该 loop 设备挂载到 AppMaster 要求的执行路径. 创建 App.sqfs 及绑定挂载的过程, 类似于如下的命令行逻辑: #将 App 程序文件制作成 squashfs 包, 需先安装 squashfs-tools 工具mksquashfs ./AppDir ./App.sqfs#将 squashfs 包绑定到 loop 设备losetup /dev/loop8 ./App.sqfs#挂载到指定目录mount ./App.sqfs /mnt/AppExecDir
RockerGuard 创建 overlay 读写隔离层, 具体细节将在 1.3.1.2 节说明.
重新挂载 /proc, 以使新 pid_namespace 内的 pid 信息正常显示.
前述工作完成以后, RockerGuard 进程调用 unshare 接口进入新的专用 user_namespace, 之后 rocker 内的任何操作都是在这个权限受限的 user_namespace 中进行, 参见 man unshare(2).
RockerGuard 准备工作完成, 通知 RockerMaster.
RockerMaster 为 RockerGuard 设置 uid_map(需要 CAP_SETUID) 及 gid_map(需要 CAP_SETGID). 设置 gid_map 之前, 须向 /proc/[RockerGuard PID]/setgroups 文件中写入 "deny" 值, 参见 man user_namespaces(7). 1.3.2.3. 子图 {#1} {#1}
遍历根下的所有顶层目录, 排除动态目录, 如 /proc, /sys, /dev, /run 等.
根下所有可见的顶层目录, 均在独立的 mnt_namespace 中原地叠加 overlay 隔离层, 以使每个 App 均拥有独立的可读写虚拟文件系统, 参见 内核文档 overlayfs. 以 ID 为 1000 的 App 挂载 /usr 为例, 假设其 upperdir 与 workdir 分别为 /private/1000/upperdir 与 /private/1000/workdir, overlay 挂载过程类似于如下的命令行逻辑: mount -t overlay overlay /usr \ -o lowerdir=/usr,upperdir=/private/1000/upperdir,workdir=/private/1000/workdir 1.3.2.4. 子图 {#2}
RockerGuard 准备好新的 rocker 环境后, 通知 RockerClient 端.
RockerClient 创建一个子进程, 子进程调用系统的 setns 接口进入新的 rocker 环境.
在 (1) 中创建的子进程中再创建一个子进程, 在其中启动前台 App 进程. 这一步新建的子进程, 实质是 (1) 中子进程的兄弟进程, 通过带 CLONE_PARENT 标志的 clone 实现, 其父进程与 (1) 中子进程的父进程一致, 如此以来 AppMaster 可以收到 App 进程终止时发送的 SIGCHLD 信号, 参见 man clone(2).
RockerClient 将 RockerGuard 及 App 的 PID 等信息返回给 AppMaster. 1.4. 开发路线添加更多的实用功能, 如下所示的 1.5. BUG
1.6. 待办事宜
|
请发表评论