2024-02-02 17:02:36 +08:00
2024-01-19 07:52:10 +00:00
2024-01-19 02:47:51 +00:00
2024-01-18 21:26:13 +08:00
2023-11-20 21:37:52 +08:00
2023-11-01 16:20:18 +08:00
2023-11-21 17:39:53 +08:00
2023-11-01 16:20:18 +08:00
2024-01-19 07:52:10 +00:00
2024-01-19 07:52:10 +00:00
2023-11-01 16:20:18 +08:00
2024-01-18 21:24:44 +08:00
2023-11-21 19:37:15 +08:00
2024-02-02 17:02:36 +08:00

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: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 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

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。

Generate syscalls within container

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
    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

Common problems

syscall 解析不出来

rust 里面nix 这个库用了宏解析头文件来生成 syscall 列表,所以如果头文件没有那就是没有。这种情况在 alpine 的 musl 容器里面常见。

如果需要静态链接的二进制建议使用 nix 来构建,否则建议在对应环境里面安装 libseccomp 并且用同样的环境来构建动态链接的二进制。

比较相近的项目

Description
No description provided
Readme 191 KiB
Languages
Rust 67.6%
Nix 14.4%
Shell 12.8%
Dockerfile 5.2%