网络策略
网络策略的 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)在两种模式下都被拒绝。一个目的地址按下面的顺序判定:
- 私有地址与特殊用途地址:拒绝。两种 mode 下都一样,
allow也放不开。 - 在
allow里:放行。 - 在
deny里:拒绝,连接立即失败,不是超时。 - 其余:放行。
下图是不经 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 的状态:
| 状态 | 效果 |
|---|---|
AVAILABLE | node 应用新策略后请求返回,最长等待 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 查询去哪里。
- 网络排查:确认修改已经生效,以及连接失败时怎样分辨原因。