x2t 沙箱
为了避免 x2t 解析文档时,被通过内存溢出而执行未信任代码,对 x2t 做一层沙箱,限制 syscall 调用
Quick start
Setup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Debian / EL9 / Arch 只有动态链接的 libseccomp
# apt install -y libseccomp-dev pkg-config
# dnf install -y libseccomp-devel pkgconf
# Alpine 有动态和静态的两个版本
# apk add --no-cache libseccomp-dev libseccomp-static
# 也可以直接使用 nix 构建的静态二进制
Build
cargo build
Build static with container
docker build -t x2t-sandbox-builder:1 -f Docker.static-builder .
docker run -it --rm \
-v $PWD:/src --workdir /src \
-e RUSTFLAGS='-C target-feature=+crt-static' \
x2t-sandbox-builder:1 \
--features tracing-mode \
--target x86_64-unknown-linux-musl \
--release \
./target/x86_64-unknown-linux-musl/release/x2t-sandbox --help
Generate syscalls with strace
strace -f --output x2t-syscalls.txt /path/to/x2t some.xml
Generate syscalls with tracing mode
cargo 开启 tracing-mode 后,宏找不到环境变量和文件不会失败,可以直接生成一个。
cargo build --features tracing-mode
RUST_LOG=trace ./target/debug/x2t-sandbox -- -l x2t-syscalls.txt /path/to/x2t some.xml
cat x2t-syscalls.txt | sort | uniq | sponge x2t-syscalls.txt
cargo build
更新 syscall 列表后重新构建二进制会生成新的 sandbox。
Run
./target/debug/x2t-sandbox /path/to/x2t some.xml
Optional: Nix 直接构建二进制
nix 是一个 fully reproducible 的构建和配置系统。
- 安装 nix
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
- 构建
# nix flake 构建需要文件在 git 目录树中 git add x2t-syscalls.txt # 构建,并软链接 result -> /nix/产物/路径 nix build .#x2t-sandbox-static # 也可以构建,不软链接,打印目录 nix build .#x2t-sandbox-static --no-link --print-out-paths # git commit # git push
- 二进制在 result 目录下
./result/bin/x2t-sandbox /path/to/x2t some.xml
项目结构
- 项目
- x2t-syscalls.txt: x2t 用到的 syscall
- build.rs: 解决少数构建平台无法找到 libseccomp 的问题
- x2t-sandbox-rulegen: 通过 macro 直接从 syscall 列表生成代码,不用内嵌syscall名字文本了,不容易被修改
- Cargo.toml/Cargo.lock: 已经被配置为默认构建静态链接的二进制
- optional: flake.nix/flake.lock: nix 搭建的、完全统一的统一开发环境,配置为默认构建静态链接的二进制
- .envrc: 如果不适用nix,注释掉,或者 direnv block 一下不加载就行
- .gitignore
比较相近的项目
- cloudflare/sandbox: cloudflare/sandbox 在运行时配置规则,我们是在构建时配置规则
- Cloudflare | Sandboxing in Linux with zero lines of code: cloudflare 写了一篇博客讲解 seccomp 工作机制和 sandbox 使用
- google/nsjail: 隔离更全面,使用了命名空间和 cgroup 来限制访问,是一个类似于容器但是目标主要是解决安全问题的解决方案
- Figma | Server-side sandboxing: Containers and seccomp figma 的 use case
Description
Languages
Rust
67.6%
Nix
14.4%
Shell
12.8%
Dockerfile
5.2%