进阶 docs.cubesandbox.com 2026-10-08 23:44:25 · 6 阅读

第26章 路由感知出网

路由感知出网 ​默认情况下,CubeSandbox 保持原有出网行为:CubeVS 会把沙箱出站包直接送到节点主网卡。这条路径简单,适合单网卡节点,但无法让 Linux 路由表选择其他出口设备,例如第二块网卡、GRE 隧道、VXLAN 设备、VPN 接口或策略路由路径。可选的 cube-router 模式只改变宿主机侧的出网路径。沙箱网络策略、DNS allow-list 学习、CubeEgress L7 代理、端口映射的语义保持不变。什么时候启用 ​当沙箱流量需要遵循宿主机路由,而不是固定从主网卡发出时,可以启用 cube-router。常见场景包括:节点有多块网卡,不同目的 CIDR 需要走不同出口。某些目标只能通过 GRE、VXLAN、WireGuard 或内部 VPN 等隧道设备访问。希望支持 route-aware sandbox egress,但不想修改宿主机全局默认路由。如果主网卡直出已经满足需求,保持关闭即可。为了兼容升级,默认不启用。工作方式 ​关闭 cube-router 时,CubeVS 使用原有的直接 SNAT 路径:启用 cube-router 时,CubeVS 先把出站包归一化到一个内部 NAT IP,再注入到名为 cube-router 的内部 dummy 设备。随后由 Linux 内核完成正常的 forwarding、conntrack、路由查询和最终 MASQUERADE:这意味着 CubeSandbox 不需要理解每一种网络设备类型。只要 Linux 能把流量路由到该设备,沙箱出网就可以使用它。端口映射仍然绑定在节点主网卡上,不会暴露到所有可能的出网设备。安装时启用 ​在运行 one-click 安装或升级前,在 deploy/one-click/.env 中设置:bashCUBE_SANDBOX_CUBE_ROUTER_ENABLE=1 # 可选。留空时会从 CUBE_SANDBOX_NETWORK_CIDR 派生地址。 CUBE_SANDBOX_CUBE_ROUTER_CIDR=如果 CUBE_SANDBOX_CUBE_ROUTER_CIDR 为空,CubeSandbox 会从沙箱 CIDR 末尾保留两个可用 IP。默认沙箱 CIDR 是 192.168.0.0/18,对应为:地址用途192.168.63.253/32cube-router 设备 IP192.168.63.254进入宿主机路由前使用的内部 SNAT IP如果指定自定义 cube-router CIDR,它必须是对齐的私有 IPv4 CIDR,掩码范围为 /16 到 /30。CubeSandbox 使用 .1 作为 router IP,.2 作为内部 SNAT IP:bashCUBE_SANDBOX_CUBE_ROUTER_ENABLE=1 CUBE_SANDBOX_CUBE_ROUTER_CIDR=10.254.0.0/24自定义 CIDR 不能和宿主机已有路由或接口地址冲突。首次启用 cube-router 时,已有沙箱的外访存量连接会中断;应用重连后会按新的 cube-router 路径正常建立连接。验证方式 ​安装完成后,先检查设备、路由和 NAT 规则:baship addr show cube-router ip route | grep cube-router iptables -t nat -S POSTROUTING | grep MASQUERADE创建一个具备出网权限的沙箱,然后访问一个应当走非主网卡路由的目标:baship route get tcpdump -ni cube-router host tcpdump -ni host 正常情况下,能先在 cube-router 上看到包,再在宿主机路由选中的出口设备上看到包。最终出口设备上的包源地址应当是 MASQUERADE 后的宿主机出口 IP。注意事项 ​cube-router 不改变沙箱的 allow_out、deny_out 或 L7 rules 语义。CubeEgress 仍然处理由 CubeVS 和宿主机 TPROXY 规则选中的 HTTP/HTTPS 流量。不要为了测试 cube-router 修改宿主机全局默认路由。建议为待验证目标添加更精确的 host route 或策略路由。如需关闭该功能,设置 CUBE_SANDBOX_CUBE_ROUTER_ENABLE=0,然后走正常升级/重装流程,让生成配置和宿主机网络状态重新收敛。示例 1:GRE Remote 作为公网网关 ​这个示例把默认出网路径切到 GRE 隧道,由 GRE remote 节点转发访问公网。10.0.0.0/8、172.16.0.0/12、192.168.0.0/16 等私网流量仍然走 Cube 节点物理网卡。如果你是通过 SSH 远程操作服务器,替换默认路由前需要先为 GRE underlay 对端和 SSH 客户端保留物理网卡路由。示例拓扑:角色示例值Cube 节点 underlay IP203.0.113.10Cube 节点物理网卡eth0Cube 节点物理网关203.0.113.1GRE remote underlay IP198.51.100.20GRE tunnel 名称natgreCube 侧 GRE IP169.254.100.1/30Remote 侧 GRE IP169.254.100.2/30GRE remote 公网出口网卡eth0云厂商安全组或防火墙需要放通两个 underlay IP 之间的 GRE 流量,GRE 是 IP protocol 47。在 GRE remote 节点执行:bash#!/usr/bin/env bash set -euo pipefail CUBE_UNDERLAY_IP="203.0.113.10" REMOTE_UNDERLAY_IP="198.51.100.20" REMOTE_EGRESS_NIC="eth0" TUNNEL_NAME="natgre" REMOTE_TUNNEL_CIDR="169.254.100.2/30" modprobe ip_gre ip tunnel del "${TUNNEL_NAME}" 2>/dev/null || true ip tunnel add "${TUNNEL_NAME}" mode gre local "${REMOTE_UNDERLAY_IP}" remote "${CUBE_UNDERLAY_IP}" ttl 255 ip addr replace "${REMOTE_TUNNEL_CIDR}" dev "${TUNNEL_NAME}" ip link set "${TUNNEL_NAME}" up mtu 1476 sysctl -w net.ipv4.ip_forward=1 iptables -t nat -C POSTROUTING -s 169.254.100.0/30 -o "${REMOTE_EGRESS_NIC}" -j MASQUERADE 2>/dev/null \ || iptables -t nat -A POSTROUTING -s 169.254.100.0/30 -o "${REMOTE_EGRESS_NIC}" -j MASQUERADE在 Cube 节点执行:bash#!/usr/bin/env bash set -euo pipefail CUBE_UNDERLAY_IP="203.0.113.10" REMOTE_UNDERLAY_IP="198.51.100.20" UNDERLAY_NIC="eth0" UNDERLAY_GW="203.0.113.1" TUNNEL_NAME="natgre" CUBE_TUNNEL_CIDR="169.254.100.1/30" SSH_CLIENT_IP="" modprobe ip_gre ip tunnel del "${TUNNEL_NAME}" 2>/dev/null || true ip tunnel add "${TUNNEL_NAME}" mode gre local "${CUBE_UNDERLAY_IP}" remote "${REMOTE_UNDERLAY_IP}" ttl 255 ip addr replace "${CUBE_TUNNEL_CIDR}" dev "${TUNNEL_NAME}" ip link set "${TUNNEL_NAME}" up mtu 1476 # 固定 GRE underlay 路径,避免默认路由切到 GRE 后,GRE 外层包也被送回 GRE。 ip route replace "${REMOTE_UNDERLAY_IP}/32" via "${UNDERLAY_GW}" dev "${UNDERLAY_NIC}" src "${CUBE_UNDERLAY_IP}" # 私网流量仍然走物理网卡,而不是 GRE 公网网关。请根据你的内网实际拓扑调整。 ip route replace 10.0.0.0/8 via "${UNDERLAY_GW}" dev "${UNDERLAY_NIC}" src "${CUBE_UNDERLAY_IP}" ip route replace 172.16.0.0/12 via "${UNDERLAY_GW}" dev "${UNDERLAY_NIC}" src "${CUBE_UNDERLAY_IP}" ip route replace 192.168.0.0/16 via "${UNDERLAY_GW}" dev "${UNDERLAY_NIC}" src "${CUBE_UNDERLAY_IP}" # 如果通过 SSH 远程操作,建议把 SSH_CLIENT_IP 设置为你的 SSH 客户端源 IP, # 避免替换默认路由后 SSH 会话断开。 if [[ -n "${SSH_CLIENT_IP}" ]]; then ip route replace "${SSH_CLIENT_IP}/32" via "${UNDERLAY_GW}" dev "${UNDERLAY_NIC}" src "${CUBE_UNDERLAY_IP}" fi # 默认出网路径切到 GRE remote 网关。 ip route replace default dev "${TUNNEL_NAME}"预期路由表片段:bashdefault dev natgre scope link 10.0.0.0/8 via 203.0.113.1 dev eth0 src 203.0.113.10 172.16.0.0/12 via 203.0.113.1 dev eth0 src 203.0.113.10 192.168.0.0/16 via 203.0.113.1 dev eth0 src 203.0.113.10 198.51.100.20 via 203.0.113.1 dev eth0 src 203.0.113.10 169.254.100.0/30 dev natgre proto kernel scope link src 169.254.100.1在 Cube 节点验证:baship addr show natgre ip route get 1.1.1.1 ip route get 10.1.2.3 tcpdump -ni cube-router 'host 1.1.1.1 or host 169.254.100.2' tcpdump -ni natgre 'host 1.1.1.1 or host 169.254.100.2' tcpdump -ni eth0 'proto gre or host 198.51.100.20 or net 10.0.0.0/8'随后创建一个 allow_out 包含隧道对端、公网目标和待验证内网目标的沙箱,例如 169.254.100.2/32、1.1.1.1/32 和 10.1.2.3/32。正常情况下,公网流量会先出现在 cube-router,再进入 natgre,最后由 GRE remote 节点做 NAT 后访问公网;私网流量会先出现在 cube-router,随后从物理网卡发出。示例 2:双网卡,一个访问公网,一个访问内网 ​这个示例让宿主机默认路由走一块网卡访问公网,同时让私网流量走另一块物理网卡。沙箱流量进入 cube-router 后,会按同一套路由表选择出口。示例拓扑:角色示例值公网出口网卡eth0,10.206.0.4公网网关10.206.0.1内网出口网卡eth1,10.206.0.15内网网关10.206.0.1公网目标1.1.1.1内网目标10.50.0.12在 Cube 节点配置路由:bash# 公网默认流量走 eth0。 ip route replace default via 10.206.0.1 dev eth0 src 10.206.0.4 # 私网流量走 eth1。 ip route replace 10.0.0.0/8 via 10.206.0.1 dev eth1 src 10.206.0.15 ip route replace 172.16.0.0/12 via 10.206.0.1 dev eth1 src 10.206.0.15 ip route replace 192.168.0.0/16 via 10.206.0.1 dev eth1 src 10.206.0.15预期路由表片段:bashdefault via 10.206.0.1 dev eth0 src 10.206.0.4 10.0.0.0/8 via 10.206.0.1 dev eth1 src 10.206.0.15 172.16.0.0/12 via 10.206.0.1 dev eth1 src 10.206.0.15 192.168.0.0/16 via 10.206.0.1 dev eth1 src 10.206.0.15测试沙箱前,先确认宿主机路由选择符合预期:baship route get 1.1.1.1 ip route get 10.50.0.12第一条应该选择 eth0,第二条应该选择 eth1。创建一个 allow_out 包含两个目标的沙箱,例如 1.1.1.1/32 和 10.50.0.12/32,然后在沙箱里执行:bashping -c 4 1.1.1.1 ping -c 4 10.50.0.12在 Cube 节点抓包验证:bashtcpdump -ni cube-router 'host 1.1.1.1 or host 10.50.0.12' tcpdump -ni eth0 'host 1.1.1.1 or host 10.50.0.12' tcpdump -ni eth1 'host 1.1.1.1 or host 10.50.0.12'预期结果:访问 1.1.1.1 的流量先出现在 cube-router,随后出现在 eth0。访问 10.50.0.12 的流量先出现在 cube-router,随后出现在 eth1。最终物理网卡上的源 IP 是 MASQUERADE 后的对应网卡 IP。

评论 (0)