
CubeSandbox 网络模型深度解析CubeVS 三层 eBPF 架构与内核态安全策略【免费下载链接】CubeSandboxInstant, Concurrent, Secure Lightweight Sandbox for AI Agents.项目地址: https://gitcode.com/GitHub_Trending/cu/CubeSandbox本文是 CubeSandbox 网络子系统CubeVS的架构技术指南。CubeSandbox 为每个沙箱实例提供独立虚拟网络与私网连通性并在内核态强制执行逐沙箱安全策略——这一切都建立在由三个 eBPF 程序、一组共享 BPF Map 和一套 Go 控制面库构成的 CubeVS 之上。读完本文你将掌握 CubeVS 的三程序挂载模型、出/入站流量路径、双表会话跟踪、SNAT/DNAT 机制、CIDR 与域名两级网络策略、端口映射与 TAP 设备全生命周期管理并能对照仓库源码理解每条关键路径的实现细节。1. 架构总览1.1 设计目标传统容器网络栈Linux Bridge、OVS、基于 iptables 的 NAT会在每个数据包上叠加与宿主机租户数成正比的额外开销。CubeVS 用三个小型协作的 eBPF 程序替换了这一整套栈将它们挂载在内核数据路径的关键点上其核心设计目标有三点无共享网桥或软件交换机每个沙箱通过自己独立的 TAP 设备直接挂到内核数据路径上避免了网桥方案的广播域和逐跳成本。两个沙箱之间不存在任何共享 L2 网段天然隔离。内核态策略执行网络策略在数据包到达用户态之前就由 eBPF 完成评估CPU 开销最小化。可扩展 NATSNAT 端口分配使用带锁保护的端口池与抗冲突插入避免了大规模部署中 iptables 规则爆炸的问题。1.2 三个 BPF 程序CubeVS 在数据包穿越宿主机的三个网络边界上各挂一个 BPF 程序程序源文件挂载点方向职责from_cubemvmtap.bpf.c每个 TAP 设备的 TC ingress沙箱 -- 宿主机策略检查、DNS 检查、SNAT、会话创建、ARP 代理from_worldnodenic.bpf.c宿主机网卡的 TC ingress外部 -- 宿主机反向 NAT、端口映射代理from_envoylocalgw.bpf.ccube-dev 的 TC egress宿主机 -- 沙箱处理宿主机侧发往沙箱的流量透明代理回包CubeEgress与宿主机主动探测从源码看三个程序的生成声明集中在 cubevs.go 的go:generate指令中分别通过bpf2go编译localgw.bpf.c、mvmtap.bpf.c和nodenic.bpf.c目标架构由$GOARCH决定并引用vmlinux/$GOARCH下的内核头文件vmlinux 目录按 amd64/arm64 分别提供。1.3 Go 控制面CubeNet/cubevs/这个 Go 包封装了 BPF 的完整生命周期主要 API 与文档一一对应Init()加载并 pin 三个 BPF 对象文件注入宿主机相关常量IP、MAC、接口索引并挂载共享 TC 过滤器详见第 9 节。AddTAPDevice()/DelTAPDevice()注册/注销沙箱 TAP 设备包括其元数据与网络策略CIDR 与域名两类。注册失败时会回滚已写入的元数据tap.go。AttachFilter()在 TAP 设备上创建 clsact qdisc 并挂载from_cubeTC 过滤器详见第 8 节。SetSNATIPs()填充 SNAT IP 池详见第 4 节。端口映射 APIAddPortMapping、DelPortMapping、ListPortMapping、GetPortMapping等运行时更新端口映射表详见第 7 节。Reaper 后台协程一个清扫过期的 NAT 会话另一个清扫过期的 DNS 学习策略条目reaper.go 中StartSessionReaper()通过sync.Once启动doReap每 5 秒依次执行reapSessions()与reapDNSState()。1.4 BPF Maps三个程序通过/sys/fs/bpf/下的 pinned BPF Map 共享状态共分六个功能组Map 名常量见 cubevs.go分组Maps用途设备注册表mvmip_to_ifindex、ifindex_to_mvmmeta每个沙箱的 IP 到设备、设备到元数据的双向查找NAT 会话egress_sessions、ingress_sessions双向 5 元组会话跟踪见第 3 节SNAT 池snat_iplistSNAT IP 及每个 IP 的源端口水位线端口映射remote_port_mapping、local_port_mapping沙箱对外暴露服务的静态 NAT 规则见第 7 节L3/L4 策略allow_out_v3、deny_out逐沙箱 CIDR 允许/拒绝列表见第 5 节L7/域名策略dns_allow_v2、dns_query_track逐沙箱域名规则与待处理的 DNS 查询状态见第 6 节allow_out_v3中的条目带有可选过期时间这使得 DNS 学习规则能与静态配置规则共享同一张 Map。仓库中的用户态结构体与 BPF 侧结构体通过编译期unsafe.Sizeof静态断言保证内存布局一致cubevs.go例如natSession固定 64 字节、sessionKey固定 20 字节、mvmMetadata固定 128 字节。Map 采用 pin 机制因此不同时间加载的程序例如Init()之后逐个挂载的 per-TAP 过滤器可以通过文件系统共享状态。bpfFSPath默认为/sys/fs/bpf且被声明为变量以便测试将其指向临时 bpffs 挂载点map.go。2. 流量路径2.1 出站沙箱到外部网络当沙箱进程向外部发起连接时数据包路径如下逐步拆解沙箱发出源 IP 为169.254.68.6固定内部地址、源端口由其 TCP/UDP 协议栈选择的报文。报文进入 TAP 设备命中from_cubeTC ingress 过滤器。from_cube检查目的地址。如果目标是沙箱网关169.254.68.5过滤器将报文重定向进cube-dev交给宿主协议栈处理。对于其他所有目标from_cube依次执行评估网络策略见第 5 节。被策略标记为需要 L7 透明代理CubeEgress检查的流量被重定向进cube-dev而不是直接 NAT宿主机侧的代理从那里接管。检查出站 DNS 查询以便基于域名的规则见第 6 节在响应返回时学习已解析的 IP。在egress_sessions与ingress_sessions中创建或更新 NAT 会话。执行 SNAT用 SNAT 池中的 IP 与动态分配的端口替换沙箱源 IP 和端口并更新 L3/L4 校验和。将改写后的报文重定向到宿主网卡。2.2 入站外部网络到沙箱回包和端口映射的入站连接到达宿主网卡后被路由回正确的沙箱from_world处理两类情况基于会话的反向 NAT过滤器在ingress_sessions中按报文 5 元组查找。命中后重建沙箱侧的原始 5 元组执行反向 DNAT并将报文重定向到正确的 TAP 设备。端口映射入站若无会话命中过滤器用目的端口查remote_port_mapping。命中说明这是对沙箱对外暴露服务的入站连接过滤器将报文 DNAT 到沙箱的监听端口并重定向到 TAP。2.3 宿主机到沙箱的流量两类宿主机侧流量通过cube-dev进入沙箱都由from_envoy处理两种情况下from_envoy都会把目的地址改写为沙箱内部 IP169.254.68.6并重定向到沙箱的 TAP。二者的差异在于源地址的处理CubeEgress 代理回包当沙箱的出站 HTTP/HTTPS 被重定向到宿主机上的 L7 透明代理CubeEgress后CubeEgress 代连真实远端服务器并收到回包再通过cube-dev把回包送回沙箱并通过IP_TRANSPARENT保留真实远端 IP 作为源地址。from_envoy保留该源 IP因此沙箱看到的回包就像直接来自远端对端。宿主机主动探测宿主机自身向沙箱服务发送就绪/存活探测。这些报文源自宿主协议栈以 cube-dev 自身地址为源地址从cube-dev发出。from_envoy将源改写为沙箱网关169.254.68.5因此沙箱看到探测来自其默认网关。这一机制在 localgw.bpf.c 中实现其 L7 mark 常量cube_l7_mark_http、cube_l7_mark_https、cube_l7_mark_mask可在Params中通过L7MarkHTTP/L7MarkHTTPS/L7MarkMask覆盖默认值与 iptables TPROXY 初始化脚本共享cubevs.go。3. 会话跟踪CubeVS 维护有状态连接跟踪以便正确反向 NAT 回包并清理过期连接。3.1 双表设计两张 Map 协同工作egress_sessions是主会话表。键为沙箱侧看到的原始 5 元组。值保存完整 NAT 状态SNAT IP 与端口、TAP ifindex、时间戳、TCP 状态以及主动关闭处理标志。对应的用户态结构体natSession中还有PacketClass、L7Scheme与PolicyVersion字段——其中PolicyVersion是策略代数数据面会将其与每个 NAT 会话缓存的副本比较以决定既有连接是否需要重新评估策略cubevs.go。ingress_sessions是反向查找表。键为外部侧看到的 5 元组。值只保存重建egress_sessions键所需的最小信息ingressSessionValue仅 16 字节包含 Version、VMIP、VMPort用于执行反向 NAT。这种双表设计避免了在两个方向上重复保存完整会话状态同时支持从连接任意一侧进行 O(1) 查找。会话键按协议区分TCP 键带有Version字段TAP 代次参与会话键而 UDP 键的 Version 固定为 0——这从 reaper.go 的sessionKey结构体可以看出。3.2 协议跟踪CubeVS 在 TCP 上镜像 Linux 内核nf_conntrack跟踪标准状态SYN_SENT、ESTABLISHED、FIN_WAIT、TIME_WAIT等使会话超时反映其协议状态——ESTABLISHED会话可以安全存活数小时而半开会话与已关闭会话在数秒到数分钟内被回收。UDP 与 ICMP 使用更简单的两状态模型UNREPLIED/REPLIED首个回包到达时延长超时。TCP 状态枚举tcpConntrackState完整复刻了内核enum tcp_conntrack从tcpCTNone一直到tcpCTIgnoredreaper.goUDP/ICMP 状态枚举亦与 icmp.h 中的ICMP_CT_*常量保持一致。3.3 会话 ReaperGo 后台协程每 5 秒运行一次遍历egress_sessions对每个会话比较now - access_time与状态相关超时。仓库中的实际超时表reaper.go如下协议状态超时TCPNONE0内核为 2 分钟TCPSYN_SENT / SYN_RECV1 分钟TCPESTABLISHED3 小时TCPFIN_WAIT2 分钟TCPCLOSE_WAIT1 分钟TCPLAST_ACK30 秒TCPTIME_WAIT2 分钟若沙箱主动关闭则为 10 秒TCPCLOSE10 秒UDPUNREPLIED / REPLIED30 秒 / 180 秒ICMP任意30 秒其中tcpTimeout()有一个特殊分支当会话处于TIME_WAIT且ActiveClose 1沙箱侧主动关闭时套用CLOSE的 10 秒超时而非默认的 2 分钟加速回收沙箱主动关闭的连接reaper.go。会话过期时reaper 同时删除egress_sessions与ingress_sessions条目——删除顺序是先删 ingress 再删 egress因为需要用 egress 会话构造 ingress 键reaper.go。若会话并非在正常终态过期例如ESTABLISHED未收到 FIN 而超时reaper 通过 1024 容量的事件通道上报ErrSessionExpiredNotClosed告警日志。它还监控会话总数当占用率超过 Map 容量maxSessions 1048576的 80% 时上报ErrSessionsTooMany事件reaper.go。4. SNAT 与 DNAT4.1 SNAT出站地址转换沙箱的每个出站报文在离开宿主机前都必须被改写为可路由的源地址。CubeVS 在from_cube中通过最多 4 个 SNAT IP 的池完成这一操作。IP 选择对每个沙箱是确定性的index jhash(sandbox_ip) % 4。因此同一沙箱的所有连接使用同一 SNAT IP简化了外部防火墙规则与日志分析。端口分配按每个 SNAT IP 条目单调递增的水位线工作起始端口为 30000。该条目由 BPF spin lock 保护因此不同 CPU 上的并发分配不会竞争。若选中的SNAT-IP:port与ingress_sessions中已有条目冲突分配器递增端口并重试有限次数仍失败则丢弃报文。源码层面SetSNATIPs()将传入的 IP 列表按 IP 升序排序后写入snat_iplist的前 4 个槽位不足时循环复用并将每个条目的MaxPort初始化为maxPortStart 30000snat.go。分配成功后from_cube就地更新 IP 与传输层头并将报文重定向到宿主网卡。4.2 DNAT入站地址转换DNAT 发生在三种场景宿主机到沙箱流量cube-dev 上的from_envoy——目的 IP 被改写为沙箱内部 IP169.254.68.6。源地址要么保留CubeEgress 代理回包要么改写为沙箱网关宿主机主动探测见 §2.3。会话回包流量宿主网卡上的from_world——目的 IP 和端口从节点的 SNAT 地址改写回沙箱的原始源地址和端口使用ingress_sessions中的反向查找。端口映射流量宿主网卡上的from_world——对通过端口映射暴露的服务直接用remote_port_mapping将目的改写为沙箱的监听端口不触碰会话表。5. 网络策略基于 CIDRCubeVS 完全在内核态执行逐沙箱出站网络策略使用 LPM最长前缀匹配trie 承载 CIDR 规则。5.1 架构每个沙箱的 TAP 设备关联两张 LPM trieallow_out_v3—— 目的 CIDR 允许列表。若目的匹配无论拒绝列表如何都放行。条目可携带过期时间这正是 DNS 学习规则第 6 节与静态规则共存于同一张 Map 的方式。v3 布局lpmKeyV3将端口放入键中prefixlen 48 为精确(ip, port)规则、32 为仅 IP 规则、32 为网段规则值中直接保存 scheme从而支持 L7 按端口规则cubevs.go。deny_out—— 目的 CIDR 拒绝列表。若目的匹配且不在允许列表中报文被丢弃。两者都实现为以 TAP ifindex 为键的 hash-of-maps因此对一个沙箱的策略更新永远不会触碰其他沙箱的 Map。每张内层 LPM trie 的容量上限为maxNetPolicyEntries 8192条创建时使用BPF_F_NO_PREALLOC标志netpolicy.go。5.2 评估顺序对每个出站报文若目的为沙箱网关169.254.68.5放行内部流量。若allow_out_v3有匹配条目放行。若deny_out有匹配条目丢弃。否则放行。优先级为allow deny default-allow因此运维人员可以安装一条宽泛的拒绝规则0.0.0.0/0阻断所有互联网访问再用允许规则打洞。无论策略如何配置CubeVS 始终拒绝以下私网与链路本地网段防止沙箱探测宿主内部网络或其他沙箱netpolicy.go 中的alwaysDeniedSandboxCIDRs10.0.0.0/8127.0.0.0/8169.254.0.0/16172.16.0.0/12192.168.0.0/16这些恒定拒绝规则会在 TAP 注册/替换策略时与用户规则合并写入effectiveDenyOutEntriesForReplacenetpolicy.go确保该不变量永远不会被策略更新覆盖掉。5.3 策略配置注册 TAP 设备时调用方提供一个MVMOptions结构体tap.goAllowInternetAccess—— 若为false安装0.0.0.0/0的 blanket 拒绝规则netpolicy.go。AllowOut/DenyOut—— CIDR 列表AllowOut还可填域名见第 6 节。AllowOut中的目标会在用户态被自动分类IPv4/CIDR 字面量进入allow_out_v3域名进入dns_allow_v2splitAllowOutTargets。L7AllowOut——L7Target列表每个目标由Host 可选(Port, Scheme)组成用于 L7 透明代理策略。Port 0 Scheme 0表示未指定会展开为默认端口集{80/http, 443/https}expandDefaultPortSet。策略可以在运行时更新通过修改内层 LPM trie 即可生效无需摘除或重载 BPF 程序。仓库提供了三种更新模式netpolicy.goapplyNetPolicy创建路径的增量添加replaceNetPolicy恢复路径的冲刷 重填UpdateTAPDevicePolicy运行中沙箱的差异收敛——先计算当前安装状态与期望状态的差异只执行必要的逐条目写入先撤销后添加保证任何中间状态都不会比新旧策略都更宽松最后再递增策略代数PolicyVersion让数据面在下一个报文上对既有连接重新评估。6. 网络策略基于域名当服务的 IP 是动态的CDN、云 API时CIDR 规则就不够用了。CubeVS 因此还支持从沙箱自身 DNS 流量学习的基于域名的允许规则。6.1 工作原理域名规则按沙箱存储在dns_allow_v2中这是一张以反转的小写域名为键的 LPM trie。支持两种形态编码规则见 dnspolicy.go 的makeDNSAllowRule精确匹配例如qq.com—— 只匹配qq.com。编码为反转名加\0结尾qq.com-moc.qq\0。通配前缀例如*.qq.com—— 匹配a.qq.com等子域但不匹配 apex。编码为反转名加.结尾*.qq.com-moc.qq.前缀长度按字节计算后写入Prefixlen。当沙箱发出 DNS 查询时from_cube提取被查询的域名并在dns_allow中查找。若域名被允许查询 id 与源端口被记录到dns_query_track键包含 ifindex、服务器 IP、源端口、DNS ID 与 qname 哈希值缓存了命中规则的端口集合见 cubevs.go。响应返回时from_world用dns_query_track匹配响应提取 A 记录并将每个解析出的 IP 以源自 DNS TTL 的过期时间插入该沙箱的allow_out_v3。DNS reaper 以与 NAT 会话 reaper 相同的方式清扫过期条目——netPolicyValueV3Expired判定动态条目ExpiresAtNS ! 0是否到期dns_reaper.go。一个值得注意的实现细节静态规则与 DNS 学习规则在同一键上相遇时静态规则过期时间为 0胜出使条目变成永久条目而不是让 DNS 的 TTL 到期后把静态裁决一起删掉netpolicy.go。因为 DNS 学习规则落在与静态 CIDR 相同的allow_out_v3中第 5 节的快速路径不需要为它们做任何特殊处理。域名解析出的 IP 在dns_query_track过期前一直被跟踪未收到响应的查询由reapDNSQueryTrack定期清理。6.2 未启用时零开销DNS 检查是按沙箱选择性开启的。from_cube与from_world用沙箱元数据中的一个标志dns_policy_flags即dnsPolicyFlagLearningEnabled门控整条 DNS 管线该标志只在调用方配置了域名规则时才会被设置dnsPolicyFlagsForDomainsnetpolicy.go。未配置时DNS 报文走普通 UDP 路径不进行额外解析、不做dns_query_track记账、不做逐包dns_allow查找。只使用 CIDR 策略的沙箱不会为域名策略机制支付任何开销。7. 端口映射沙箱从外部不可直接到达。当沙箱需要暴露服务时CubeVS 提供端口映射——一条将到达特定宿主机端口的流量转发到特定沙箱端口的静态 NAT 规则。7.1 双向映射两张 BPF Map 支撑端口映射remote_port_mapping—— 将宿主机端口映射到(TAP ifindex, 沙箱监听端口)对。from_world用它把入站连接路由到正确的沙箱。local_port_mapping—— 将(TAP ifindex, 沙箱监听端口)反向映射到宿主机端口。from_cube将其用作优化当沙箱从已映射的监听端口发包时过滤器可跳过完整会话创建直接用节点 IP 和正确端口执行 SNAT。Go 侧的MVMPort结构体8 字节静态断言保证以网络字节序存储端口与数据面的 tcphdr 字段直接可比cubevs.go。7.2 入站流程外部客户端发送报文到node_ip:host_port。from_world查找remote_port_mapping[host_port]。命中后过滤器将目的改写为169.254.68.6:sandbox_listen_port并重定向到 TAP 设备。此路径不创建会话表条目使长连接服务的 Map 保持精简。7.3 管理Go API 提供AddPortMapping()、DelPortMapping()、ListPortMapping()与GetPortMapping()用于运行时管理映射。port.go 中的addPortMapping实现了完整的冲突检测与并发安全插入前先查双向映射任一方向已被其他元组占用即报错本地表插入失败时回滚已插入的远端表条目rollbackRemotePortMapping。DelPortMapping只删除仍与期望元组匹配的条目避免误删并发变更port.go。此外DeletePortMappingsByIfindex可独立扫描两张表并清理属于指定 ifindex 的全部映射。7.4 计算节点端口划分为防止子系统间冲突宿主机可用端口空间被划分为三个区间端口区间用途10000–19999宿主机临时端口ip_local_port_range20000–29999CubeProxy 用于到达沙箱的端口30000–65535SNAT 为沙箱发起流量使用的源端口Cubelet 内嵌的网络运行时只为沙箱端口映射从20000–29999分配宿主机端口。产品创建路径通过exposedPorts暴露容器端口并且始终请求自动宿主机端口分配HostPort0用户不能选择特定宿主机端口。运行时随后从该受管区间分配空闲端口并在创建响应中返回映射。这与 SNAT 起始端口 30000maxPortStart上下呼应两个子系统各自占用互不重叠的端口段。8. TAP 设备生命周期每个沙箱都有一个专用 TAP 设备作为其在宿主机侧的唯一网络接口。CubeVS 管理这些设备的完整生命周期。注册。沙箱运行时创建新沙箱时调用AddTAPDevice(ifindex, ip, id, version, options)该函数将沙箱元数据写入ifindex_to_mvmmeta与mvmip_to_ifindex并根据options初始化逐沙箱策略 MapCIDR 与域名规则。第 5.2 节的恒定拒绝 CIDR 首先安装然后才是调用方指定的规则tap.go。若策略安装失败注册会回滚已写入的元数据。元数据中的UUID最多 64 字节maxIDLength超长时报ErrTooLongVersion字段记录 TAP 代次用于沙箱回滚场景——BumpMvmVersion通过读改写递增该代次数据面据此判定旧会话失效并重置tap.go。过滤器挂载。一旦 TAP 设备在 OS 层存在AttachFilter(ifindex)就在其上创建 clsact qdisc 并挂载from_cubeTC 过滤器。从此刻起沙箱发出的每个报文都被拦截。tc.go 展示了底层实现createQdisc通过tc.Open添加 clsact qdisc已存在时报EEXIST则忽略attachFilter以direct-action标志、handle 1、优先级 1、ETH_P_ALL协议挂载 BPF 过滤器并使用tcnl.Filter().Replace保证幂等。拆除。DelTAPDevice(ifindex, ip)移除逐沙箱策略 Map 与设备注册表条目。引用该 TAP 设备的活跃会话留在原处——会话 reaper 会在它们超时后清理从而避免在拆除时做昂贵的全表扫描。实现上拆除被拆分为两个可组合步骤CleanupTAPDevicePolicy冲刷allow_out_v3、deny_out、dns_allow_v2内层 Map 并清零 DNS 策略标志与DeleteTAPDeviceMetadata删除双向注册表条目幂等处理缺失键。只有 TAP 网卡本身被销毁时才会删除 hash-of-maps 的外层键DeleteTAPDevicePolicyMaps、GCStaleNetPolicyMaps就绪池复用场景保留外层键并重装默认拒绝规则netpolicy.go。9. 初始化cubevs.Init()在 Cubelet 内嵌网络运行时启动时网络插件 /NetworkController启动阶段只调用一次。它执行以下步骤加载并 pin三个 BPF 程序及其 Map 到/sys/fs/bpf/注入宿主机相关值到 BPF 字节码加载前替换沙箱 IP 与网关 IP、cube-dev 接口索引/IP/MAC、宿主网卡接口索引/IP/MAC、下一跳网关 MAC以及 L7 mark 常量挂载共享 TC 过滤器from_envoy挂到 cube-dev 的 egressfrom_world挂到宿主网卡的 ingress。per-TAP 的from_cube过滤器在稍后沙箱逐个创建时挂载第 8 节。从 cubevs.go 的Params结构体可以看到初始化所需的全部宿主机参数MVMInnerIP/MVMMacAddr沙箱内部 IP/MAC、MVMGatewayIP沙箱网关、Cubegw0Ifindex/IP/MacAddrcube-dev即文档所称 cube-dev 设备、EgressSrcMacAddr/EgressDstMacAddr/EgressRedirectFlags出站 L2 改写与重定向行为、NodeIfindex/IP/Mask/MacAddr节点自身、NodeGatewayMacAddr下一跳网关 MAC。若CubeRouterIfindex为 0 则禁用 cube-router 钩子挂载。10. ARP 代理沙箱被分配链路本地 IP169.254.68.6默认网关为169.254.68.5。由于这些地址只存在于 TAP 设备的点对点链路内169.254.68.5处没有真实主机应答 ARP 请求——而且与网桥方案不同这里也没有可广播该请求的共享 L2 网段。from_cube充当 ARP 应答者当沙箱询问谁是 169.254.68.5时过滤器当场构造一个 ARP 回复用 cube-dev 网关 MAC 填充发送方 MAC并重定向回 TAP。沙箱由此获得网关的有效 ARP 条目可以正常发送 IP 报文所有 IP 报文随后都进入第 2.1 节的出站路径。由于沙箱链路使用169.254.0.0/16地址而该网段同时位于恒定拒绝 CIDR 列表中第 5.2 节沙箱自身永远无法直接访问宿主或其他沙箱的链路本地地址——ARP 代理只服务于网关地址本身。11. 总结CubeVS 通过三层 eBPF 架构实现沙箱网络隔离这套设计建立在两个核心理念之上数据路径逻辑全部住在内核态。策略评估、NAT、会话跟踪、DNS 学习与 ARP 解析全部在 eBPF 中完成Go 控制面只负责生命周期管理与周期性清理。每个沙箱端到端隔离。独立的 TAP 设备、独立的策略 Map、独立的会话——同一宿主机上的两个沙箱之间不存在任何共享网桥或交换机。附源码地图本文全部内容均有仓库源码佐证以下路径可供深入阅读主题源码位置BPF 程序定义与go:generateCubeNet/cubevs/cubevs.go三个 BPF 程序源码CubeNet/src/mvmtap.bpf.c、CubeNet/src/nodenic.bpf.c、CubeNet/src/localgw.bpf.cBPF 侧结构体与常量cubevs.hCubeNet/src/cubevs.h会话 Reaper 与超时表CubeNet/cubevs/reaper.goSNAT IP 池CubeNet/cubevs/snat.goTAP 设备生命周期 APICubeNet/cubevs/tap.go端口映射管理CubeNet/cubevs/port.goCIDR/L7 策略规划与安装CubeNet/cubevs/netpolicy.go域名策略编码CubeNet/cubevs/dnspolicy.goDNS 学习条目回收CubeNet/cubevs/dns_reaper.goTC qdisc / 过滤器挂载CubeNet/cubevs/tc.goBPF Map pin 加载CubeNet/cubevs/map.go相关单元测试CubeNet/cubevs/netpolicy_test.go、CubeNet/cubevs/dns_learn_test.go、CubeNet/cubevs/tap_test.go、CubeNet/cubevs/egress_policy_test.go、CubeNet/cubevs/port_test.go、CubeNet/cubevs/reaper_test.go若存在说明本文所述的端口区间、超时数值、Map 名称与容量上限均以当前仓库 CubeNet/cubevs/ 的实现为准。CubeVS 运行在内核 eBPF 数据面上需要较新的内核版本支持 TC clsact、LPM trie、spin lock 与 BPF pin 等特性沙箱侧固定内部地址169.254.68.6与网关169.254.68.5为链路本地段约定属于实现事实而非可配置参数。【免费下载链接】CubeSandboxInstant, Concurrent, Secure Lightweight Sandbox for AI Agents.项目地址: https://gitcode.com/GitHub_Trending/cu/CubeSandbox创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考