Rust安全沙箱库gaol的使用:轻量级进程隔离与资源控制框架

Rust安全沙箱库gaol的使用:轻量级进程隔离与资源控制框架

安装

在项目目录中运行以下Cargo命令:

cargo add gaol

或者在Cargo.toml中添加:

gaol = "0.2.1"

代码示例

下面是一个使用gaol进行进程隔离的基本示例:

use gaol::sandbox::{ChildSandbox, ChildSandboxMethods, Sandbox, SandboxMethods};
use gaol::profile::{Profile, Operation};

// 定义一个简单的沙箱配置
struct SimpleSandbox;

impl Sandbox for SimpleSandbox {
    fn profile(&self) -> Profile {
        // 允许文件系统操作但限制网络访问
        Profile::new(vec![
            Operation::FileReadMetadata,
            Operation::FileRead,
            Operation::FileWrite,
        ])
    }
}

impl ChildSandbox for SimpleSandbox {
    fn child_sandbox(&self) -> Box<dyn Sandbox> {
        Box::new(SimpleSandbox)
    }
}

fn main() {
    // 创建沙箱环境
    let sandbox = SimpleSandbox;
    
    // 在沙箱中执行代码
    sandbox.run(|| {
        // 这里运行受限制的代码
        println!("Running in sandbox");
        
        // 尝试文件操作(允许)
        let _ = std::fs::read_to_string("example.txt");
        
        // 尝试网络操作(会被阻止)
        // let _ = reqwest::blocking::get("https://example.com");
    }).unwrap();
}

完整示例

use gaol::sandbox::{ChildSandbox, ChildSandboxMethods, Sandbox, SandboxMethods};
use gaol::profile::{Profile, Operation};
use std::process::Command;

// 自定义沙箱配置
struct CustomSandbox;

impl Sandbox for CustomSandbox {
    fn profile(&self) -> Profile {
        Profile::new(vec![
            // 允许基本文件操作
            Operation::FileReadMetadata,
            Operation::FileRead,
            Operation::FileWrite,
            
            // 允许进程控制
            Operation::ProcessSpawn,
            
            // 限制网络和其他系统调用
        ])
    }
}

impl ChildSandbox for CustomSandbox {
    fn child_sandbox(&self) -> Box<dyn Sandbox> {
        Box::new(CustomSandbox)
    }
}

fn main() {
    let sandbox = CustomSandbox;
    
    match sandbox.run(|| {
        // 在沙箱中执行受限制的代码
        
        // 1. 文件操作示例
        println!("Attempting file operations...");
        let result = std::fs::write("sandbox_test.txt", "Hello from sandbox");
        println!("File write result: {:?}", result);
        
        // 2. 进程操作示例
        println!("Attempting to spawn process...");
        let output = Command::new("echo")
            .arg("Hello from child process")
            .output()
            .expect("Failed to spawn process");
        println!("Process output: {:?}", output);
        
        // 3. 尝试受限操作(如网络访问)
        // 这会触发沙箱保护
        println!("Attempting network access...");
        // let _ = reqwest::blocking::get("https://example.com");
        
        Ok(())
    }) {
        Ok(_) => println!("Sandbox execution completed successfully"),
        Err(e) => eprintln!("Sandbox error: {}", e),
    }
}

注意事项

  1. gaol使用操作系统提供的安全机制(如Linux的seccomp)来实现进程隔离
  2. 不同的平台可能支持不同的操作限制
  3. 在生产环境中使用前,应充分测试沙箱配置
  4. 某些操作可能需要特定的权限才能正常工作

许可证

gaol采用MIT或Apache-2.0双重许可证


1 回复

Rust安全沙箱库gaol的使用:轻量级进程隔离与资源控制框架

介绍

gaol是一个Rust实现的安全沙箱库,提供了轻量级的进程隔离和资源控制功能。它允许你在受控环境中运行不可信代码,同时限制其对系统资源的访问。gaol特别适合需要执行第三方或不可信代码的场景,如插件系统、在线代码评测平台等。

gaol的主要特点包括:

  • 轻量级进程隔离
  • 细粒度的资源控制(CPU、内存、网络等)
  • 简单的API设计
  • 基于Linux命名空间和cgroups实现

安装方法

在Cargo.toml中添加依赖:

[dependencies]
gaol = "0.3"

基本使用方法

1. 创建简单的沙箱

use gaol::sandbox::{Sandbox, ChildSandbox, Profile};
use gaol::sandbox::profile::Operation;

fn main() {
    // 定义沙箱规则
    let profile = Profile::new(vec![
        Operation::SystemReadWhitelist(vec!["/etc/resolv.conf".into()]),
        Operation::SystemWriteWhitelist(vec![]),
    ]);

    // 创建沙箱
    let sandbox = Sandbox::new(profile).unwrap();

    // 在沙箱中运行代码
    sandbox.run(|| {
        println!("Hello from inside the sandbox!");
        // 这里运行的代码受到沙箱限制
    }).unwrap();
}

2. 限制资源使用

use gaol::sandbox::{Sandbox, Profile};
use gaol::sandbox::profile::{Operation, ResourceLimits};

fn main() {
    let profile = Profile::new(vec![
        Operation::ResourceLimits(ResourceLimits {
            max_cpu_time: Some(std::time::Duration::from_secs(1)),
            max_memory_bytes: Some(100 * 1024 * 1024), // 100MB
            ..Default::default()
        }),
    ]);

    let sandbox = Sandbox::new(profile).unwrap();

    match sandbox.run(|| {
        // 尝试分配大量内存会被阻止
        let _big_vec = vec![0u8; 200 * 1024 * 1024];
    }) {
        Ok(_) => println!("Execution completed"),
        Err(e) => eprintln!("Sandbox error: {}", e),
    }
}

3. 网络访问控制

use gaol::sandbox::{Sandbox, Profile};
use gaol::sandbox::profile::Operation;

fn main() {
    let profile = Profile::new(vec![
        // 禁止所有网络访问
        Operation::NetworkAccess(false),
    ]);

    let sandbox = Sandbox::new(profile).unwrap();

    sandbox.run(|| {
        // 尝试网络访问会失败
        if let Err(e) = std::net::TcpStream::connect("example.com:80") {
            println!("Network access blocked as expected: {}", e);
        }
    }).unwrap();
}

高级用法

1. 自定义错误处理

use gaol::sandbox::{Sandbox, Profile};
use gaol::sandbox::profile::Operation;

fn main() {
    let profile = Profile::new(vec![
        Operation::SystemReadWhitelist(vec!["/allowed/path".into()]),
    ]);

    let sandbox = Sandbox::new(profile).unwrap();

    let result = sandbox.run(|| {
        // 尝试读取不允许的文件
        std::fs::read_to_string("/etc/passwd")
    });

    match result {
        Ok(content) => println!("Got content: {}", content),
        Err(e) => eprintln!("Sandbox prevented file access: {}", e),
    }
}

2. 结合异步运行时

use gaol::sandbox::{Sandbox, Profile};
use gaol::sandbox::profile::Operation;
use tokio::runtime::Runtime;

fn main() {
    let profile = Profile::new(vec![
        Operation::SystemReadWhitelist(vec!["/allowed/path".into()]),
    ]);

    let sandbox = Sandbox::new(profile).unwrap();
    let rt = Runtime::new().unwrap();

    sandbox.run(|| {
        rt.block_on(async {
            // 在沙箱内执行异步代码
            tokio::time::sleep(std::time::Duration::from_secs(1).await;
            println!("Async code executed in sandbox");
        })
    }).unwrap();
}

完整示例demo

下面是一个综合使用gaol各种功能的完整示例:

use gaol::sandbox::{Sandbox, Profile};
use gaol::sandbox::profile::{Operation, ResourceLimits};
use std::time::Duration;

fn main() {
    // 定义沙箱规则
    let profile = Profile::new(vec![
        // 文件系统访问控制
        Operation::SystemReadWhitelist(vec![
            "/usr/lib".into(),
            "/lib".into(),
            "/lib64".into()
        ]),
        Operation::SystemWriteWhitelist(vec![]),
        
        // 资源限制
        Operation::ResourceLimits(ResourceLimits {
            max_cpu_time: Some(Duration::from_secs(2)),
            max_memory_bytes: Some(50 * 1024 * 1024), // 50MB
            max_stack_bytes: Some(1 * 1024 * 1024),   // 1MB
            ..Default::default()
        }),
        
        // 网络控制
        Operation::NetworkAccess(false),
        
        // 进程控制
        Operation::ProcessLimit(1),
    ]);

    // 创建沙箱
    let sandbox = Sandbox::new(profile).expect("Failed to create sandbox");

    // 在沙箱中运行代码
    match sandbox.run(|| {
        println!("Running in sandbox environment");
        
        // 尝试分配内存
        let vec = vec![0u8; 10 * 1024 * 1024]; // 10MB
        
        // 尝试网络访问
        if let Err(e) = std::net::TcpStream::connect("8.8.8.8:80") {
            println!("Network access blocked as expected: {}", e);
        }
        
        // 模拟CPU密集型任务
        let start = std::time::Instant::now();
        while start.elapsed() < Duration::from_secs(3) {
            // 长时间运行可能会被CPU时间限制中断
        }
        
        println!("Sandbox execution completed");
    }) {
        Ok(_) => println!("Sandbox exited normally"),
        Err(e) => eprintln!("Sandbox error: {}", e),
    }
}

注意事项

  1. gaol目前主要支持Linux平台
  2. 需要适当的系统权限(通常需要root或相应的capabilities)
  3. 沙箱不能提供完全的安全隔离,不适合运行恶意代码
  4. 资源限制可能有少量误差

gaol提供了一种在Rust中实现轻量级进程隔离的便捷方式,通过合理配置规则,可以在许多场景下增强应用程序的安全性。

回到顶部