2023-11-01 16:17:51 +08:00
# x2t 沙箱
为了避免 x2t 解析文档时,被通过内存溢出而执行未信任代码,对 x2t 做一层沙箱,限制 syscall 调用
## Quick start
### Setup
```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
2023-11-02 10:13:50 +08:00
# 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 构建的静态二进制
2023-11-01 16:17:51 +08:00
```
### Build
2023-11-02 10:46:46 +08:00
```bash
2023-11-01 16:17:51 +08:00
cargo build
```
2023-11-02 10:46:46 +08:00
### Build static with container
```bash
2023-11-21 10:16:54 +08:00
docker build -t x2t-sandbox-builder:copy-to-data -f build/Dockerfile.static --target copy-to-data .
docker run -it --rm -v /path/to/put/output/:/data x2t-sandbox-builder:copy-to-data
2023-11-02 10:46:46 +08:00
2023-11-20 21:15:49 +08:00
/output/path/x2t-sandbox --help
```
2023-11-01 16:17:51 +08:00
2023-11-21 10:16:54 +08:00
And there is [Dockerfile ](./build/Dockerfile.ubuntu ) for you to build for ubuntu. base image can be specified by argument `--build-arg BASE=library/ubuntu:22.04` . default base image is ubuntu:20.04
2023-11-01 21:53:20 +08:00
### Generate syscalls with strace
2023-11-02 10:46:46 +08:00
```bash
2023-11-01 21:53:20 +08:00
strace -f --output x2t-syscalls.txt /path/to/x2t some.xml
```
### Generate syscalls with tracing mode
cargo 开启 tracing-mode 后,宏找不到环境变量和文件不会失败,可以直接生成一个。
2023-11-02 10:46:46 +08:00
```bash
2023-11-02 10:05:34 +08:00
cargo build --features tracing-mode
RUST_LOG=trace ./target/debug/x2t-sandbox -- -l x2t-syscalls.txt /path/to/x2t some.xml
2023-11-02 00:07:38 +08:00
cat x2t-syscalls.txt | sort | uniq | sponge x2t-syscalls.txt
cargo build
2023-11-01 21:53:20 +08:00
```
2023-11-01 21:57:53 +08:00
更新 syscall 列表后重新构建二进制会生成新的 sandbox。
2023-11-21 19:37:15 +08:00
### Generate syscalls within container
```bash
docker build -t x2t-sandbox:tracer -f ./build/Dockerfile.ubuntu-build-with-tracer --target runtime-tracer .
docker run -it --rm -v output-volume:/output -v some-other-programs:/programs x2t-sandbox -l /output/syscalls.txt /path/to/command /and/its/arguments
```
2023-11-02 10:05:34 +08:00
### Run
```
./target/debug/x2t-sandbox /path/to/x2t some.xml
```
2023-11-02 10:13:50 +08:00
### Optional: Nix 直接构建二进制
nix 是一个 fully reproducible 的构建和配置系统。
- 安装 nix
2023-11-02 10:46:46 +08:00
```bash
2023-11-02 10:13:50 +08:00
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
```
- 构建
```bash
# 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 目录下
2023-11-02 10:46:46 +08:00
```bash
2023-11-02 10:13:50 +08:00
./result/bin/x2t-sandbox /path/to/x2t some.xml
```
2023-11-01 16:17:51 +08:00
## 项目结构
- [项目 ](/ )
2023-11-01 21:58:39 +08:00
- [x2t-syscalls.txt ](x2t-syscalls.txt ): x2t 用到的 syscall
- [build.rs ](build.rs ): 解决少数构建平台无法找到 libseccomp 的问题
- [x2t-sandbox-rulegen ](x2t-sandbox-rulegen/ ): 通过 macro 直接从 syscall 列表生成代码, 不用内嵌syscall名字文本了, 不容易被修改
2023-11-02 10:46:46 +08:00
- Cargo.toml/Cargo.lock: 已经被配置为默认构建静态链接的二进制
2023-11-01 16:17:51 +08:00
- optional: flake.nix/flake.lock: nix 搭建的、完全统一的统一开发环境,配置为默认构建静态链接的二进制
- .envrc: 如果不适用nix, 注释掉, 或者 direnv block 一下不加载就行
- .gitignore
2023-11-01 16:28:21 +08:00
2023-11-02 10:54:44 +08:00
## Common problems
### syscall 解析不出来
rust 里面, nix 这个库用了宏解析头文件来生成 syscall 列表,所以如果头文件没有那就是没有。这种情况在 alpine 的 musl 容器里面常见。
如果需要静态链接的二进制建议使用 nix 来构建,否则建议在对应环境里面安装 libseccomp 并且用同样的环境来构建动态链接的二进制。
2023-11-02 00:21:52 +08:00
## 比较相近的项目
- [cloudflare/sandbox ](https://github.com/cloudflare/sandbox ): cloudflare/sandbox 在运行时配置规则,我们是在构建时配置规则
- [Cloudflare | Sandboxing in Linux with zero lines of code ](https://blog.cloudflare.com/sandboxing-in-linux-with-zero-lines-of-code/ ): cloudflare 写了一篇博客讲解 seccomp 工作机制和 sandbox 使用
- [google/nsjail ](https://github.com/google/nsjail ): 隔离更全面,使用了命名空间和 cgroup 来限制访问,是一个类似于容器但是目标主要是解决安全问题的解决方案
- [Figma | Server-side sandboxing: Containers and seccomp ](https://www.figma.com/blog/server-side-sandboxing-containers-and-seccomp ) figma 的 use case