Kibotos

网络策略

网络策略的 mode 与目的地规则决定 Workspace 能直接访问哪些地址。本页介绍怎样用 kibo 修改它们、一个目的地址怎样判定,以及修改什么时候生效。

用 kibo 修改策略

kibo workspace network 有三个子命令:

命令效果
network set <workspace-id> <mode>整体替换:命令行写的就是完整策略,没写的表为空
network add <workspace-id>把给出的条目加进对应的表,mode 与其他条目不变
network remove <workspace-id>从对应的表里删掉给出的条目,mode 与其他条目不变

下面的命令依次只许访问一段 IPv4 地址(IPv6 全部拒绝)、封一个地址、解封它,最后关闭公网:

kibo workspace network set "$workspace_id" public-internet --deny 0.0.0.0/0 --deny ::/0 --allow 203.0.113.0/24
kibo workspace network add "$workspace_id" --deny 198.51.100.7
kibo workspace network remove "$workspace_id" --deny 198.51.100.7
kibo workspace network set "$workspace_id" deny-all
  • 改成 deny-all 时两张表一并清空。
  • add 只用于 public-internet 的 Workspace,先用 set 改 mode。
  • add 已有的条目、remove 没有的条目只在 stderr 提示,不算失败。
  • 不规范的条目、两表合计超过 256 条,都在发请求前被拒绝,退出 2,见条目的写法。

并发修改

策略有一个服务端分配的版本:创建时为 1,mode、目的地规则、Egress 或 Resolver 任一变化时加一。

  • set 不带 --expected-revision 时不检查版本。
  • add 与 remove 先读取当前策略,再以读到的版本提交。期间策略被别人改过时什么都不改,退出 13,重新读取后再决定。
  • 脚本要重放 add 或 remove 时,把 --command-id 与第一次读到的 --expected-revision 一起传入。

目的地的判定

PUBLIC_INTERNET 放行 guest 发起的 TCP 连接与 ping;DNS 查询只发往 guest 链路上的一个地址,见链路 DNS。其他 UDP(例如 QUIC(HTTP/3)与发往外部服务器的 NTP)在两种模式下都被拒绝。一个目的地址按下面的顺序判定:

  1. 私有地址与特殊用途地址:拒绝。两种 mode 下都一样,allow 也放不开。
  2. 在 allow 里:放行。
  3. 在 deny 里:拒绝,连接立即失败,不是超时。
  4. 其余:放行。

下图是不经 Egress 的连接:发往公网的从 node 的上联直出,发往私网与特殊用途地址的在策略检查处被拒绝。经 Egress 的连接不受第 1 条约束,见连接的走向。

例如 deny 写 0.0.0.0/0、allow 写 203.0.113.0/24,即「IPv4 只许这一段」。

  • 每项只作用于自己的地址族。 0.0.0.0/0 不影响 IPv6,两族都要收窄时同时写 ::/0。
  • DNS 不受 allow、deny 影响。 发往链路 DNS 地址的查询照常成功,deny 覆盖部署 DNS 服务器或整个地址族时也一样;解析出的地址落在 deny 里时,随后的连接立即失败。

条目的写法

  • 写法必须规范。 CIDR 的主机位为零,IPv4 没有前导零,IPv6 用小写压缩形式,不带 zone;单个地址可以不写前缀长度。
  • 不规范的条目被拒绝,不会被改写后接受。 10.0.0.1/8 这样的条目返回 invalid_argument。
  • 两张表合计最多 256 项。 超出被拒绝。DENY_ALL 带任一项也被拒绝。
  • 按给出的顺序保存。 顺序与重复不影响效果,但只改顺序也算内容变化,版本加一。

修改什么时候生效

修改的效果取决于 Workspace 的状态:

状态效果
AVAILABLEnode 应用新策略后请求返回,最长等待 1 分钟。此后新连接按新策略判定,既有连接按下表处理
STOPPED只更新期望,下次启动时生效
CREATING、STARTING、STOPPING、DELETING、FAILED、UNKNOWN返回 failed_precondition,策略不变

运行中的 Workspace 改策略后:

变化既有连接新连接
收窄目标落入新拒绝范围的不能再收发数据,其余不受影响按新策略判定
改为 DENY_ALL全部切断全部拒绝
放宽不受影响立即可用,不需要重启

改变连接走向的修改(直出改为经 Egress,或反过来)另有宽限期,见改变连接走向。

带 allow 或 deny 的 Workspace 只运行在支持这两张表的 node 上,不会退回为不带规则的 PUBLIC_INTERNET:

  • 创建或启动时没有这样的 node,返回 failed_precondition,reason 为 CAPABILITY_UNAVAILABLE。
  • 运行中加规则而所在的 node 不支持时,返回同样的错误,期望不变。

对 AVAILABLE 的 Workspace 修改没有成功时:

  • node 应用失败。 请求返回这个错误,Workspace 变为 FAILED,没有已应用的策略。guest 仍在运行,但它受哪个策略约束已经无法确定。用 kibo workspace stop --force 停止 Workspace,再启动它。
  • node 在 1 分钟内没有应答。 请求返回可重试的 UNAVAILABLE,Workspace 处于 UNKNOWN,直到 node 再次汇报。用同一个 --command-id 重发这次修改,或用 kibo workspace get 查看结果。

请求成功只说明策略本身已经应用。以下情形用 kibo workspace get 确认:修改的是 STOPPED 的 Workspace,在它启动之后;更新了策略引用的 Egress 或 Resolver 之后;旧连接仍在宽限期内时。见确认策略已经生效。

用 API

UpdateWorkspaceNetworkPolicy 整体替换策略。

  • 版本是 revision。 由服务端分配:创建时为 1,mode、allow、deny、egresses、resolvers 任一变化时加一,请求里的值被忽略。
  • 只想改一部分时, 先读出当前策略,改好后以读到的版本作为期望版本提交。期间被别人改过时修改被拒绝,策略不变。
  • expected_revision 可以不带。 为 0 时不检查;不为 0 时即使内容与当前相同,版本不符也返回 aborted。
  • 比较幂等输入时不看 network_policy.revision, 见幂等键。
  • 是否已经生效看 Workspace 的 network_policy_status。

能力名:allow 与 deny 是 workspace.network_policy.destination_rules,expected_revision 是 workspace.network_policy.update.expected_revision。

警告

老版本的服务端会静默丢掉 allow、deny 与 expected_revision,不做版本检查。写这些字段前先确认能力名存在。

下一步

  • Egress:让部分连接经调用方自己的 SOCKS5 端点离开。
  • DNS 与 Resolver:guest 的 DNS 查询去哪里。
  • 网络排查:确认修改已经生效,以及连接失败时怎样分辨原因。

本页内容