OpenSandbox FQDN白名单实战:只让AI沙箱访问你批准的域名
【免费下载链接】OpenSandboxSecure, Fast, and Extensible Sandbox runtime for AI agents.项目地址: https://gitcode.com/GitHub_Trending/ope/OpenSandbox
OpenSandbox是面向 AI Agent 的开源安全沙箱运行时,其FQDN 白名单(域名级出口网络控制)能力可以让你在创建沙箱时用一行声明式配置,限制沙箱只能访问你批准的域名(如api.github.com、*.pypi.org),其余出站流量默认全部拒绝。对于需要运行第三方代码或让 Coding Agent 自由执行命令的场景,这是防止数据外泄和恶意请求的关键防线 🛡️。
为什么用 FQDN 白名单,而不是 IP 白名单?
很多沙箱方案(包括部分商业平台)用 IP 或 CIDR 段做出口控制,但在 AI Agent 场景下有明显短板:
| 痛点 | 说明 |
|---|---|
| 🔄 IP 漂移 | 云服务、CDN 的 IP 经常变动,人工维护 IP 白名单成本高且容易出错 |
| 🔓 共享 IP 漏洞 | 多个服务共享同一 IP 时,按 IP 放行可能意外放行同主机上的其他服务 |
| ✍️ 体验差 | 让开发者先做 DNS 解析再填 CIDR,远不如直接写"允许访问openai.com"直观 |
FQDN 白名单让策略声明更贴近人的心智模型,且由 OpenSandbox 的 Egress Sidecar 自动完成"域名 → IP"的动态跟踪。
工作原理:DNS 代理 + 网络层双保险
OpenSandbox 的 FQDN 出口控制由一个与沙箱应用共享网络命名空间的Egress Sidecar实现(设计提案见 oseps/0001-fqdn-based-egress-control.md):
- 第 1 层 · DNS 代理(软拦截):Sidecar 启动 DNS 代理服务并拦截沙箱内所有 53 端口的 DNS 请求,未授权的域名直接返回
NXDOMAIN,应用无需任何改造(核心实现见 components/egress/pkg/dnsproxy/proxy.go)。 - 第 2 层 · nftables 过滤(硬拦截):在
dns+nft模式下,被允许的域名解析出的 IP 会自动加入内核级放行表(带 TTL 动态更新),即使有人绕过 DNS 直连 IP 也会被拦截。
只有 Sidecar 持有CAP_NET_ADMIN权限,你的应用容器始终无额外特权,Docker 和 Kubernetes 上行为一致。
⚠️ 注意:仅开启
dns模式时,白名单是"软限制"(可被直连 IP 绕过);生产环境建议使用dns+nft模式获得真正隔离。若 Sidecar 无法安装强制重定向规则,会直接退出(fail-closed),不会静默放行。
三步开启 FQDN 白名单
1️⃣ 声明网络策略
使用 Python SDK 创建沙箱时,传入network_policy参数(接口定义见 specs/sandbox-lifecycle.yml):
from opensandbox import Sandbox, NetworkPolicy, NetworkRule sandbox = await Sandbox.create( image="python:3.11", network_policy=NetworkPolicy( default_action="deny", # 默认拒绝所有出站流量 egress=[ NetworkRule(action="allow", target="api.github.com"), NetworkRule(action="allow", target="*.pypi.org"), # 通配符 NetworkRule(action="allow", target="10.96.0.0/12"), # IP/CIDR ], ), )2️⃣ 选择执行模式
在 Server 配置中设置 Egress 模式(详见 server/configuration.md):
[egress] mode = "dns+nft" # 推荐:DNS 过滤 + nftables 内核级强制3️⃣ 在沙箱内验证
在沙箱里执行命令即可验证效果:
curl https://pypi.org/simple/ # ✅ 白名单内,正常返回 curl https://baidu.com # ❌ DNS 解析 NXDOMAIN,无法访问Kubernetes 集群上的部署演示可以参考下方示例,策略随沙箱创建自动生效:
规则语法速查表 📋
| 写法 | 示例 | 说明 |
|---|---|---|
| 精确域名 | api.github.com | 只放行该 FQDN |
| 通配符 | *.pypi.org | 放行所有子域名 |
| 单 IP | 10.0.0.5 | 需dns+nft模式生效 |
| CIDR 段 | 10.96.0.0/12 | 如 K8s Service CIDR |
| 默认动作 | defaultAction: deny | 未命中任何规则时拒绝 |
| 严格模式 | require_full_isolation: true | 网络层强制不可用时创建直接失败 |
补充说明:
- 🌐
localhost、127.0.0.1及沙箱内部通信始终放行,不影响本地服务调试; - 📜 规则按顺序匹配,支持运行时通过 Sidecar 的
PATCH /policy接口增量追加规则(默认端口18080); - 🚫 平台级强制规则可写入 Sidecar 镜像的
/var/egress/rules/deny.always,优先级高于用户策略且每分钟热加载,适合在集群层面封禁 Pod/Service CIDR(见 docs/architecture/network-isolation.md)。
避坑指南 ⚠️
K8s 集群内访问 Service 需要"双重放行":defaultAction: deny下,访问postgres.opensandbox.svc.cluster.local既要在 DNS 层放行该域名,又要在网络层放行其 ClusterIP 所属 CIDR(如10.96.0.0/12),只放其一都会被拦截。
Pool 沙箱不支持按请求下发策略:池化沙箱在创建 Pod 时无法再注入 Egress Sidecar,因此 API 会拒绝同时携带networkPolicy和poolRef的请求。需要出口控制的请写进 Pool 的 Pod 模板,或使用非池化沙箱。
不支持 hostNetwork:K8s 中hostNetwork=true或 Docker--network host与 FQDN 白名单互斥,创建请求会被直接拒绝,避免策略误伤宿主机。
与透明 Service Mesh 冲突:Istio/Envoy 自动注入的 Pod 暂不支持 Egress Sidecar,两者在同一网络命名空间改写流量会产生双重拦截问题,建议将沙箱 Pod 排除出 Mesh 注入范围。
总结
OpenSandbox 的 FQDN 白名单让"给 AI 沙箱开网"从危险的裸奔变成一行声明式配置:声明允许的域名,其余默认拒绝;DNS 层保证易用性,nftables 层保证安全性,权限隔离保证应用容器零特权提升。配合 Credential Vault 等能力,你可以在安全边界内放心地把网络访问交给 AI Agent。
延伸阅读:
- 设计提案:oseps/0001-fqdn-based-egress-control.md
- Egress 组件文档:docs/components/egress.md
- 网络隔离架构:docs/architecture/network-isolation.md
- Egress Sidecar 源码:components/egress/
- Python SDK:sdks/sandbox/python/
【免费下载链接】OpenSandboxSecure, Fast, and Extensible Sandbox runtime for AI agents.项目地址: https://gitcode.com/GitHub_Trending/ope/OpenSandbox
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考