seccomp-sandbox/README.md
2023-11-21 19:37:15 +08:00

125 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# x2t 沙箱
为了避免 x2t 解析文档时,被通过内存溢出而执行未信任代码,对 x2t 做一层沙箱,限制 syscall 调用
## Quick start
### Setup
```bash
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
```bash
cargo build
```
### Build static with container
```bash
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
/output/path/x2t-sandbox --help
```
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
### Generate syscalls with strace
```bash
strace -f --output x2t-syscalls.txt /path/to/x2t some.xml
```
### Generate syscalls with tracing mode
cargo 开启 tracing-mode 后,宏找不到环境变量和文件不会失败,可以直接生成一个。
```bash
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。
### 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
```
### Run
```
./target/debug/x2t-sandbox /path/to/x2t some.xml
```
### Optional: Nix 直接构建二进制
nix 是一个 fully reproducible 的构建和配置系统。
- 安装 nix
```bash
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 目录下
```bash
./result/bin/x2t-sandbox /path/to/x2t some.xml
```
## 项目结构
- [项目](/)
- [x2t-syscalls.txt](x2t-syscalls.txt): x2t 用到的 syscall
- [build.rs](build.rs): 解决少数构建平台无法找到 libseccomp 的问题
- [x2t-sandbox-rulegen](x2t-sandbox-rulegen/): 通过 macro 直接从 syscall 列表生成代码不用内嵌syscall名字文本了不容易被修改
- Cargo.toml/Cargo.lock: 已经被配置为默认构建静态链接的二进制
- optional: flake.nix/flake.lock: nix 搭建的、完全统一的统一开发环境,配置为默认构建静态链接的二进制
- .envrc: 如果不适用nix注释掉或者 direnv block 一下不加载就行
- .gitignore
## Common problems
### syscall 解析不出来
rust 里面nix 这个库用了宏解析头文件来生成 syscall 列表,所以如果头文件没有那就是没有。这种情况在 alpine 的 musl 容器里面常见。
如果需要静态链接的二进制建议使用 nix 来构建,否则建议在对应环境里面安装 libseccomp 并且用同样的环境来构建动态链接的二进制。
## 比较相近的项目
- [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