- 开发工具
- 应用安全
- AI 安全治理
【免费下载链接】fence
Lightweight, container-free sandbox for running commands with network and filesystem restrictions
Fence 是一个轻量级、无需容器的沙箱工具,能通过网络与文件系统限制安全运行命令。除了命令行用法,Fence 还可以作为Go 库直接嵌入你的应用:几行代码即可对任意命令做编程式沙箱化(Go library API),实现网络白名单、文件读写隔离和危险命令拦截。本文将带你完成从安装到实战的完整流程,让你快速把 Fence 沙箱能力集成进自己的 CI、插件或 Agent 工具中。
一、为什么选择 Fence Go 库模式?
很多团队需要在自己的程序里"跑命令但不能失控":CI Runner 执行未知构建脚本、IDE 插件运行 AI 生成的代码、Agent 框架调用 shell 工具……手动拼bwrap或sandbox-exec参数既繁琐又容易踩坑。
Fence 库模式把这些全部封装好了:
- 默认断网:所有出站网络流量默认被阻断,只放行白名单域名;
- 文件系统策略:按路径精确控制读/写权限,并内置危险路径强制保护;
- 命令黑名单:自动拦截
rm -rf /、git push等高危命令,支持管道与&&链解析; - 跨平台:macOS 走 sandbox-exec(Seatbelt),Linux 走 bubblewrap + Landlock + seccomp,核心逻辑统一在 internal/sandbox/ 中实现。
库的公共 API 全部收敛在 pkg/fence/fence.go,一个 package 就是完整入口;配置结构定义见 internal/config/config.go。
二、安装 Fence 库
Fence 的标准模块路径是github.com/fencesandbox/fence(见 go.mod),在你的 Go 项目里执行:
go get github.com/fencesandbox/fence导入时只需用到公共包:
import "github.com/fencesandbox/fence/pkg/fence"💡 Linux 平台还依赖系统包
bubblewrap(沙箱)与socat(网络桥接);macOS 无额外依赖。
三、快速上手:5 步沙箱化一条命令
下面是库模式最核心的工作流(完整示例见 docs/library.md):
// 1. 平台检查 if !fence.IsSupported() { return } // 2. 定义配置:只允许访问 api.example.com cfg := &fence.Config{ Network: fence.NetworkConfig{ AllowedDomains: []string{"api.example.com"}, }, } // 3. 创建并初始化 Manager manager := fence.NewManager(cfg, false, false) defer manager.Cleanup() // 4. 包装命令,得到"带沙箱"的新命令 wrapped, err := manager.WrapCommand("curl https://api.example.com/data") // 5. 用 sh 执行包装后的命令 output, _ := exec.Command("sh", "-c", wrapped).CombinedOutput()其中NewManager(cfg, debug, monitor)的 实现 很简洁:debug打开详细日志(代理活动、沙箱命令),monitor只记录被拦截的请求。WrapCommand内部会先做命令策略预检、再生成平台对应的沙箱包装命令,核心逻辑见 WrapCommandInDir。
Linux 多一步:配置 helper 可执行文件
Linux 下需要告知 Fence 一个能实现私有 helper 模式的程序(可以是安装好的 fence CLI,也可以是你的程序自己):
// 方式 A:指向已安装的 fence 二进制 manager.SetLinuxHelperPath("/usr/local/bin/fence") // 方式 B:让自己的可执行文件充当 helper if handled, code, err := fence.DispatchInternalHelper(os.Args); handled { if err != nil { fmt.Fprintln(os.Stderr, err) } os.Exit(code) } manager.SetLinuxHelperPath(mustExecutable()) // os.Executable()未配置 helper 时,Linux 上的WrapCommand会直接返回ErrLinuxHelperRequired——它绝不悄悄降级到更弱的沙箱,这个"失败即报错"的设计值得称赞。
四、核心 API 速查表
| API | 作用 | 备注 |
|---|---|---|
IsSupported() | 判断当前平台是否支持沙箱 | 目前为 macOS / Linux |
NewManager(cfg, debug, monitor) | 创建沙箱管理器 | 内部启动 HTTP + SOCKS 过滤代理 |
manager.Initialize() | 初始化沙箱基础设施 | WrapCommand会自动调用 |
manager.WrapCommand(cmd) | 把命令包装为沙箱命令 | 返回可直接执行的 shell 字符串 |
manager.SetService(opts) | 声明入站端口暴露 | 须在Initialize之前调用 |
manager.ExposeHostPath(path, writable) | 把宿主文件暴露进沙箱 | 须在WrapCommand之前调用 |
manager.Cleanup() | 停止代理、释放资源 | 务必defer调用 |
DefaultConfig()/LoadConfig(path) | 创建 / 加载配置 | 支持 JSON 与 JSONC 注释 |
CheckCommand/CheckReadPath等 | 策略预检(不实际运行) | 无需 Manager 即可使用 |
完整 API 参考请阅读 docs/library.md。
五、配置三种姿势:从代码到文件
姿势 1:代码里直接构造——适合策略由程序动态生成的场景:
cfg := &fence.Config{ Network: fence.NetworkConfig{AllowedDomains: []string{"registry.npmjs.org", "*.github.com"}}, Filesystem: fence.FilesystemConfig{AllowWrite: []string{".", "/tmp"}, DenyRead: []string{"~/.ssh", "~/.aws"}}, Command: fence.CommandConfig{Deny: []string{"git push", "npm publish"}}, }姿势 2:加载配置文件——复用用户已有的fence.jsonc,与 CLI 完全一致的行为:
path := fence.ResolveDefaultConfigPath() // 自动发现 fence.jsonc / fence.json cfg, err := fence.LoadConfigResolved(path) // 会解析 extends 继承链 if err != nil { log.Fatal(err) } if cfg == nil { cfg = fence.DefaultConfig() }姿势 3:基线 + 覆盖合并——多配置源场景非常实用:
merged := fence.MergeConfigs(baseCfg, overrideCfg)配置字段的完整 schema 可参考 docs/schema/fence.schema.json,内置模板(如code)源码在 internal/templates/。
六、进阶:端口暴露与宿主文件共享
暴露开发服务器端口。沙箱默认隔离网络,但你的 dev server 仍需被宿主访问。通过SetService声明入站端口,Fence 会自动建立反向桥接:
manager.SetService(fence.ServiceOptions{ Exposures: []fence.ExposedPort{fence.LoopbackPort(3000)}, // 默认只绑 127.0.0.1 }) wrapped, _ := manager.WrapCommand("npm run dev")若端口实际由外部守护进程(dockerd、systemctl 等)在宿主绑定,改用ExecutionModel: fence.ServiceBindsOnHost,避免桥接冲突。
把宿主临时文件"递"进沙箱。Linux 上 Fence 会用 tmpfs 覆盖/tmp,导致os.CreateTemp生成的文件在沙箱内不可见。此时一行ExposeHostPath解决,无需理解其内部挂载计划:
manager.ExposeHostPath(tempFile, false) // 只读暴露两种能力的细节与实现分别见 manager.go#L143-L174 和 docs/library.md#L225-L292。
七、策略预检:不启动沙箱就判定"能不能做"
如果你的工具里有不经过WrapCommand的代码路径(如 Agent 的read_file/web_fetch工具),Fence 提供一组轻量预检函数,让同一份fence.jsonc成为全局唯一策略来源:
if err := fence.CheckCommand(cfg, "echo ok && git push origin main"); err != nil { var blocked *fence.CommandBlockedError if errors.As(err, &blocked) { // blocked.Command = "git push origin main" // blocked.BlockedPrefix = "git push" } return err // 拒绝执行 }CheckReadPath/CheckWritePath:判定文件读/写,返回*PathBlockedError(含匹配规则与拒绝原因);CheckCommand:能解析管道、&&/||/;链与嵌套sh -c,逐个子命令检查;CheckURL:按allowedDomains/deniedDomains判定 URL,deny 规则优先。
⚠️ 注意:预检只是"意图检查",权威执行仍在内核级沙箱与流量代理,不要用它替代WrapCommand。
八、库模式 vs CLI 模式:四个差异要知道
| 差异点 | fenceCLI | Go 库 |
|---|---|---|
| 环境加固 | 自动剥离LD_PRELOAD等注入变量 | 需自己在 exec 时清理子进程环境 |
| 违规监控 | -m附带平台级监控(log stream / eBPF) | monitor参数仅覆盖代理拦截 |
| 交互会话 | 管理 TTY 交接、作业控制、信号转发 | 需自行接管 stdio |
| 配置发现 | 自动寻找最近fence.jsonc | 需显式LoadConfigResolved |
详见 docs/library.md#CLI vs Library Differences。
九、实战避坑清单
- Manager 非线程安全:每个 goroutine 建一个 manager,或自行加锁;代理本身可并发处理连接(docs/library.md#L636-L639)。
SetService与ExposeHostPath有时序:前者必须在Initialize前,后者必须在WrapCommand前。Cleanup一定要defer,否则代理进程会残留。- 空
AllowedDomains= 全拒绝:想放行流量必须显式配置白名单,这正是"默认最安全"的哲学。 - Linux 忘记配 helper会得到
ErrLinuxHelperRequired,属于预期报错而非 bug。
十、总结
Fence 的 Go 库 API 用极小的表面积(一个 package + 一个 Manager)覆盖了沙箱化的全部关键场景:配置 → 包装 → 执行 → 预检 → 清理。无论是给 CI 系统加一层保险,还是为 AI Agent 的命令工具装"护栏",只需十几行代码即可实现网络与文件系统的强隔离——而这一切都不需要容器。
📚 延伸阅读:
- 库完整参考:docs/library.md
- 配置参考:docs/configuration.md
- 安全模型:docs/security-model.md
- 内置模板:internal/templates/
- 架构总览:ARCHITECTURE.md
- 开发工具
- 应用安全
- AI 安全治理
【免费下载链接】fence
Lightweight, container-free sandbox for running commands with network and filesystem restrictions
相关推荐
Fence快速上手:5分钟安装,跑通你的第一个沙箱命令(macOS/Linux完整教程)
Fence快速上手:5分钟安装,跑通你的第一个沙箱命令(macOS/Linux完整教程) Fence 是一款轻量级、免容器的命令沙箱工具,默认屏蔽所有网络访问,
开发工具应用安全AI 安全治理深入掌握 Litestream Go 库编程:嵌入式流式复制 API 实战指南
深入掌握 Litestream Go 库编程:嵌入式流式复制 API 实战指南 导读 本文围绕 Litestream https://link.gitcode.
数据库数据同步灾备如何逐个沙箱化AI Agent的Shell命令?Fence hooks集成Claude Code、Cursor与OpenCode全解
如何逐个沙箱化AI Agent的Shell命令?Fence hooks集成Claude Code、Cursor与OpenCode全解 Fence 是一个轻量级、
开发工具应用安全AI 安全治理
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考