ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

OpenSandbox Egress Fleet Profile:多沙箱出网策略、流量执行链路与凭据金库的完整剖析

OpenSandbox Egress Fleet Profile:多沙箱出网策略、流量执行链路与凭据金库的完整剖析 OpenSandbox Egress Fleet Profile多沙箱出网策略、流量执行链路与凭据金库的完整剖析【免费下载链接】OpenSandboxSecure, Fast, and Extensible Sandbox runtime for AI agents.项目地址: https://gitcode.com/GitHub_Trending/ope/OpenSandbox本文围绕 OpenSandbox 的components/egress组件中 fleet profile 的运行机制展开一个 egress 控制面如何服务同一网络域内的 N 个沙箱每个沙箱作为独立 subject 拥有各自的出网策略、内核规则与凭据。读完你将理解 subject 从 deny-first 注册到激活的完整生命周期、控制面的策略/凭据推送协议、Pod netns 中 nftables 与 DNS 代理的数据面执行链路以及内存态 credential vault 的 fail-closed 保证——这些内容在 fleet profile 专题文档 中给出了权威描述本文在此基础上结合源码实现进一步展开。1. fleet profile 的模型一个控制面N 个 subjectfleet profile 面向 fast-sandbox 场景多个沙箱共享同一个宿主/网络域Fastlet Podegress 进程以单一控制面的形式为它们分别维护策略。核心抽象是subject每个沙箱对应一个不透明标识由 sandbox UID 派生前缀s-独占一片策略、凭据与内核规则切片并通过平台提供的身份键fast-sandbox 场景下即沙箱源 IP在热路径上被分发。这一点在 subject 包 的包注释中有明确定义。需要注意 sidecar profile 与此不同它是单沙箱、单策略模型依赖hook output与 15353 端口上的 iptables DNS REDIRECT本文只剖析 fleet 模型。两者的 nftables 表名也刻意区分——fleet 使用opensandbox-fleet见 fleetnft.gosidecar 使用opensandbox避免残留规则被误认为存活规则。2. subject 生命周期fastlet action 协议 → deny-first → active2.1 协议面egress 进程就是 Sandbox Actions HandlerFastlet 是唯一的生命周期分发器Sandbox Actions Handler 协议sandbox.fast.io/actions/v1。egress 进程实现两个 Pod loopback HTTP 端点见 fleet_actions.goGET /_fastlet/v1/actions/status进程化身incarnation探针返回ready与instanceIdPOST /_fastlet/v1/actions承载SET_BINDING/LIFECYCLE_HOOK/REMOVE_BINDING三种操作。协议线模型与校验集中在 pkg/actionhandler。从源码可以看到几个关键约束binding input 即策略本身CRD 的actionBindings携带声明式策略attachment 块携带网络身份源 IP、网关、veth、私有 CIDR不存在文件驱动的观测源fencing 字段强制必填revision.runtimeInstanceId与revision.attachmentId构成身份围栏任一变化即视为沙箱被重绑旧状态必须全部丢弃Envelope.Validate 中显式校验空围栏会让每次重绑看起来相同、导致 reset 永远无法被检测specGeneration刻意不参与围栏因为它在每次 spec 更新含策略更新时都会递增而策略更新应当原地生效、不能把 subject 打回 deny-first畸形信封即验证错误未知 apiVersion、未知操作、未知 Hook 名都会被拒绝HTTP 400对应never silently ignore的协议要求——subject 永远不会因为一条半懂不懂的消息被激活instanceId是重启恢复的触发器newHandlerInstanceID 为每个进程铸造随机化身 id进程重启后 id 变化Fastlet 检测到即失效 Binding 就绪状态并重放最新SET_BINDING及所有已达成的 Hooks。2.2 状态机absent → denying → activesubject 从SET_BINDING注册那一刻起就是 fail-closed 的直到其sandbox.data-plane-readyHook 成功注册时立即安装 deny-first 规则策略被置为 pendingDNS 持续拒绝。状态机定义见 State 常量各操作的落地语义在 applySetBinding / applyLifecycleHook / applyRemoveBinding 中实现几个值得注意的细节SET_BINDING 先解析策略再变更状态绑定输入在状态变更前先经policy.ParsePolicy校验一条永久无效的策略400不可能让 subject 处于半注册状态已 active 的 subject 收到新绑定输入视为普通策略更新原地应用、不重放 HooksJSON null 输入表示绑定从存活沙箱上移除丢弃 pending 推送并回退到 deny-firstdata-plane-ready 采用窥视而不消费若 nft 应用瞬时失败pending 策略保留原处Fastlet 重试同一个 Hook 即可成功而不是 409 死循环没有 pending 策略时收到 />其中 create-then-configure 的竞态处理值得展开server 侧可能先于 Fastlet 的 SET_BINDING 到达推送。fleetPolicyServer 为此维护了pending缓存bounded TTL默认值可经EnvPendingPushTTL调整见 fleet.go推送携带的X-Fast-Sandbox-Generation与注册时记录的 spec 代际不符时pending 条目会被丢弃而不是应用——reset 永远不可能把旧策略带进新沙箱。pending 策略刻意不存放在 registry 中见 pendingPolicies 字段注释策略未生效期间DNS 分发必须持续拒绝。4. 数据面出网流量执行链路权威执行层是 Pod netns 的forwardhooktable opensandbox-fleet。整个规则集的形状在 fleetnft.go 的包注释 中有完整描述table inet opensandbox-fleet chain mark { hook prerouting, priority 0 } - per-subject allow marks ip saddr ip jump mark_id - one rule per subject chain mark_id (regular chain) - what to mark ip daddr subj_id_allow_v4 meta mark set 0x2 ip daddr subj_id_dyn_v4 meta mark set 0x2 (default-allow subjects: unconditional mark) chain dispatch { hook forward, policy ACCEPT } - master chain ct state established,related accept - return traffic tcp/udp dport 853 drop - DoT bypass blocked ip saddr ip jump subj_id - one rule per subject meta mark 0x2 ! 0x2 drop - fail-closed tail chain subj_id (regular chain) - deny sets only ip daddr subj_id_deny_v4/v6 drop这套设计有三个非直觉但源码里写得非常清楚的要点1forward 路径从不显式 accept。主链 policy 是 ACCEPT 加无标记即丢弃尾部meta mark 0x2 ! 0x2 drop。因为在 fast-sandbox 的 Firecracker 桥拓扑bridge-nf-call-iptables1下forward hook 给出 accept 判决会把帧送回桥的 L2 路径在 postrouting 之前就被丢弃只有不命中任何 drop 规则才能让帧继续 IP 路由。允许的目的地址在 per-subject 的 prerouting 标记链中打0x2标记allow/dyn set 成员打标记default-allow 策略无条件打标记。0x2与 DNS 代理自己的SO_MARK 0x1旁路标记刻意区分。fleetnft_test.go 直接断言了这些 nft 脚本内容主链policy accept、尾部meta mark 0x2 ! 0x2 drop、per-subject 的ip saddr ... jump subj_id分发规则。2分发只按源 IP从不匹配 iifname。桥拓扑下进入 IP 栈的帧其skb-dev是桥本身对 pod 侧 veth 的 iifname 匹配永远不会命中。源 IP 的不可伪造性依赖 IPAM每沙箱唯一 IP与沙箱不具备NET_ADMIN/NET_RAW权限。3subject 链中只有 deny 集合没有 accept/drop 全量规则。命中deny_v4/v6集合的显式 drop其余命运由 prerouting 标记决定deny-first 状态下整个 subject 链就是一条drop规则。DNS 解析出的 IP 会写入dyn_v4/v6动态集合并带 TTL 租约DNS 代理在 fleet.go 中通过SetQueryPolicySelector注入按源 IP 的逐查询策略分发OnResolved回调把解析结果经AddResolvedIPs落入动态集合未知源一律拒绝——fail closed永不返回默认策略。DNS 侧同样共享单一 DNS 代理监听:15353全接口因为 prerouting REDIRECT 重定向的是接口地址而非 loopback15353 也不会与宿主 53 端口冲突per-subject 的网关 REDIRECT 把发往gateway:53的沙箱 DNS 转发过来安装/释放逻辑见 installGatewayDNSRedirect按 subject 计数保证 at-least-once 的 SET_BINDING 投递幂等。被 MITM 拦截的流量经 DNAT 本地投递由专用 INPUT 链按 conntrack 原始目的ct original ip daddr执行见 INPUT 链的测试断言。DNS 学习到的租约由 per-subject 连接刷新循环保活Pod netns conntrack按源 IP 分桶每个 tick 一个批量事务启动处 注明每 30s 一轮只有 TCP 会话被续租——UDP/QUICHTTP/3依赖 DNS 租约 TTL 自然过期。5. Credential vault内存态修订版与按流的 ETag 条件探测金库修订版经 proxy-route 推送内存态按 subject 保存OSEP-0012 模型——无 Secret volume不写 egress 磁盘。存储结构见 credentialvault.Store每 subject 一个 Store原子替换修订版ActiveSnapshot携带公共修订号、bindings 与注入头结构定义。共享的 mitmdump 实例按客户端源 IP透明 REDIRECT/DNAT 保留源 IP选择该 subject 的金库并对每个新 flow 用其不透明ETag条件探测私有 Unix-socket 端点。handleActiveVaultSnapshot 实现了该探测语义tag 未变返回304 ETag复用不可变快照——不渲染、不传输任何凭据材料tag 变化返回200 完整快照 公共修订号 替换 ETag。注意即使 delete-then-create 把公共修订号重置回1tag 依然变化因此重建不可能误校验删除前的快照。结果是create、patch、delete 成功回执之后的第一个 flow就能观测到该变更无需定时器或缓存过期等待404有且只有一个含义该 subject 没有活动金库——旧缓存快照被清除flow 按普通无凭据出网处理传输超时/拒连、5xx、畸形 JSON/schema、非法 ETag、条件请求后 tag 不前进都是查找失败而非无金库丢弃未确认的缓存明文快照并对所有被拦截流量包括不匹配任何凭据绑定的主机fail-closed。请求体已安全缓冲时 addon 返回本地503流式/未知长度 flow 在到达上游前被直接掐断。因此运维上必须把私有 credential-proxy socket 视为透明拦截开启时的硬可用性依赖。ETag 的字符集约束长度 ≤128仅限[A-Za-z0-9-._~]在 parseActiveVaultETag 中强制校验非法即 400。MITM 数据面细节mitmdump 如何按源 IP 定位 subject、拦截重定向表如何随注册重建可继续阅读 fleet MITM 数据面文档。6. Fail-closed 不变量总表Transition / eventGuaranteeSET_BINDING, no contenteditable="false">【免费下载链接】OpenSandboxSecure, Fast, and Extensible Sandbox runtime for AI agents.项目地址: https://gitcode.com/GitHub_Trending/ope/OpenSandbox创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表