使用 OverlayNet 控制网络访问¶
OverlayNet 让 pVisor 对网络出口执行允许、拒绝和限速规则。Host/container Run 使用进程内 HTTP proxy;libkrun VM Run 使用进程内 smoltcp 数据面处理 IPv4 TCP 和 DNS。请结合 Capability 与 Evidence 模型理解这些控制。
网络边界¶
| 执行路径 | 控制范围 | 直接出口 |
|---|---|---|
| 普通 host/container 显式代理 | 经过代理的 HTTP/HTTPS | 忽略代理、NO_PROXY、直接 socket 可绕过 |
| Linux host deny-all | 私有 network namespace | 阻止直接 IP 出口;保留 Run 内必要通信 |
| macOS host deny-all | Seatbelt socket 策略 | 阻止直接外部 IP 和 ambient Unix socket;保留声明的本地通信 |
macOS host --safe |
Seatbelt 与分配的 loopback proxy | 直接外部连接被阻止;代理执行选择性规则 |
Linux host --safe 的选择性代理 |
supervisor loopback proxy | 仍是协作式;需要强制网络边界时选择 VM 或 deny-all |
container --container-network none |
OCI 网络隔离 | 离线;不能同时使用要求 host 网络的本地 proxy/Gateway |
VM auto |
pVisor smoltcp IPv4 TCP/DNS 数据面 | guest 无直接网络旁路;不支持的 UDP、IPv6、ICMP、QUIC、入站转发失败关闭 |
VM off |
不配置 guest 网络 | 离线 |
必须检查具体 Run 的观察证据;暂存文件不改变网络边界,证据口径见能力与证据。
只允许声明的目标¶
在 Agent 命令之前传入一个或多个 --overlaynet-allow:
pvisor run \
--overlaynet-allow api.openai.com:443 \
--overlaynet-allow pypi.org:443 \
-- agent-command
只要出现 allow 规则,pVisor 就会启用 OverlayNet,并把默认动作切换为拒绝。上例中, 经过代理的流量只能访问两个列出的 HTTPS 目标,其他目标都会被拒绝。
选择 driver 模式¶
使用 --overlaynet off|auto|proxy 作为 OverlayNet 的主要开关:
| 模式 | Executor | 边界 |
|---|---|---|
off |
任意 | 关闭 OverlayNet |
proxy |
Host/container | cooperative host proxy |
auto |
VM(推荐) | 不可绕过的 smoltcp 数据面 |
省略该参数时,策略参数和 Gateway capture 会按 executor 自动推导模式。
选择策略¶
策略参数用于配置已选择的 driver(未显式指定模式时会自动推导):
| 目标 | 参数 | 对其他代理流量的处理 |
|---|---|---|
| 只允许指定目标 | --overlaynet-allow TARGET |
拒绝 |
| 拒绝指定目标 | --overlaynet-deny TARGET |
允许 |
| 拒绝普通出口,边界见上表 | --overlaynet-deny-all |
拒绝 |
| 限制带宽 | --overlaynet-limit [TARGET=]RATE |
不改变允许/拒绝动作 |
allow、deny 和 limit 参数都可以重复。显式 deny 的优先级高于 allow。
--overlaynet-deny-all 是独立策略,不能与其他策略参数组合。
目标可以是精确 hostname、通配后缀、IP 或 CIDR,并可附带端口:
pvisor run \
--overlaynet-allow '*.example.com:443' \
--overlaynet-allow 203.0.113.10:443 \
--overlaynet-deny 169.254.0.0/16 \
-- agent-command
拒绝普通出口¶
Host Run 会安装上表中的 namespace/Seatbelt 网络边界;容器应使用
--container-network none 阻断代理之外的连接。VM auto 拒绝普通 guest TCP 出口。
deny-all 不阻止已配置的内部 Gateway 路由;需要完全离线时关闭 Gateway,并在 VM 上使用 off。
--overlaynet-deny-all 不支持再叠加 allow 例外。目标是“默认全部拒绝,只允许少数
地址”时,直接声明允许的目标,不要先写 deny-all:只要出现 --overlaynet-allow,pVisor
就采用 allowlist 策略,匹配的目标允许,其余经过代理的目标默认拒绝。
限制带宽¶
同时设置全局限制和更严格的目标限制:
pvisor run \
--overlaynet-limit 10mbps \
--overlaynet-limit api.openai.com:443=2mbps \
-- agent-command
多个匹配的限制会叠加,最终采用最严格的有效速率。kbps、mbps、gbps 表示每秒
比特数;kb/s、mb/s、gb/s 表示每秒字节数。限速只约束流量,不会授予访问权限。
使用结构化规则¶
当规则需要多个端口、transport 约束,或者 hostname 有意解析到私网地址时,使用 TOML:
[run]
command = ["agent-command"]
[overlaynet]
mode = "auto" # VM 使用 smoltcp;host/container 使用 "proxy"
policy = "allowlist"
[[overlaynet.rules]]
host = "api.example.com"
ports = [443]
transports = ["tcp_tunnel"]
allow_private_ips = false
[[overlaynet.deny]]
host = "169.254.0.0/16"
[[overlaynet.limits]]
host = "api.example.com"
port = 443
bytes_per_second = 250000
运行:
transport 支持 http、https 和 tcp_tunnel。ports 或 transports 为空时,表示该
维度不受限制。
hostname 规则默认拒绝解析到私网或 loopback 的地址。有意访问私有服务时,优先使用
明确的 IP/CIDR 规则;也可以在范围足够窄的 hostname 规则上设置
allow_private_ips = true。link-local 等其他特殊地址段仍需显式 IP 或 CIDR 规则。
如果 host 使用 DNS/TUN fake-IP connector,VM 出站只会在逻辑 hostname 与 port 已通过
授权后,把 198.18/15 结果视为不透明的 connector alias;guest 不能把该网段作为 IP
literal 直接连接。connector 不暴露最终真实地址,因此需要对 hostname 解析结果执行
IP/CIDR 策略时,应使用能返回具体地址的 resolver。
理解哪些客户端会被控制¶
对于 host/container Run,pVisor 会向 Agent 进程注入 HTTP_PROXY、HTTPS_PROXY、
对应的小写形式和 ALL_PROXY。遵守这些设置的 HTTP 客户端会经过 OverlayNet;代理
支持普通 HTTP 转发和 HTTPS CONNECT 隧道。
以下路径不在普通 cooperative host/container 代理策略边界内:
- 客户端忽略或删除代理环境变量;
- 目标被加入
NO_PROXY; - 程序直接创建 socket;
- 不经过 HTTP proxy 的 DNS 和 UDP 流量。
因此 host/container cooperative-proxy Run 会报告
safety.network_non_bypassable = false。如果必须
阻止直接出口,使用 pvisor run --overlaynet-deny-all -- COMMAND:Linux 会创建私有
network namespace;macOS 会用 Seatbelt 阻断非 loopback IP 与宿主 ambient Unix socket,同时保留
loopback proxy、精确的 AgentCtl 和 Run 私有目录内 IPC。Container Run 也可以使用 --container-network none。
VM executor 默认使用 [overlaynet] mode = "auto",guest 使用静态 IPv4 地址,由 smoltcp
提供合成 DNS 与受策略控制的 IPv4 TCP;mode = "off" 会让 VM 离线。Gateway capture
通过 guest 虚拟路由器暴露;container executor 使用进程内 proxy 时仍要求
--container-network host。
Session、workspace 与 user 策略¶
CLI 从工作区 .pvisor/policy.toml 和用户
$XDG_CONFIG_HOME/pvisor/policy.toml(默认 ~/.config/pvisor/policy.toml)
读取策略,文件包含 [network] 和/或 [filesystem]。Run TOML 可显式设置
[policies.session]、[policies.workspace]、[policies.user];显式配置的
network/filesystem 条目替换同层文件默认值。
策略目录和文件必须归当前用户所有且不能被其他用户写入;目录和文件均不允许 符号链接,文件必须为不超过 1 MiB 的普通文件。缺失文件不增加策略;不安全的 路径、权限、文件类型或无效内容会阻止启动。仓库策略自动加载,但只能收窄权限。
例如,用户允许指定 API 并拒绝敏感文件:
[network]
allow = [{ host = "api.example.com", ports = [80, 443] }]
[filesystem]
deny = ["secrets/**"]
Run 可在 Session 层进一步限制:
[policies.session.network]
allow = [{ host = "api.example.com", ports = [443] }]
[policies.session.filesystem]
deny = ["generated/private/**"]
所有已声明的网络层与基础网络策略均须放行。省略 default_action 默认拒绝
未匹配目标;需要 deny-only 或带宽限制策略时应显式写 default_action = "allow"。
任一层显式 deny、端口/协议限制或解析地址安全检查失败都会拒绝请求,各层
匹配的带宽限制全部叠加。交互审批不能覆盖显式 deny 或基础 deny-all。
文件策略跨层按 deny、ask、warn、allow 取最严格决策;allow 不能覆盖其他层限制。
文件 glob 相对于暂存工作区视图。策略在 Attempt 内固定,修改文件只影响后续 Session。
网络层策略会为 host/container 的 auto 启用显式 proxy,该边界仍是协作式。
文件层策略在未配置暂存工作区时创建暂存视图。VM auto 使用不可绕过的网络
驱动;off 保持离线。
嵌入 API 使用 RunSpec.policies,并须通过 PVisorBuilder 配置对应的
OverlayFS 视图和网络驱动;缺少驱动时拒绝启动。
检查运行结果¶
当前目录默认就是可重复使用的 workspace;每次调用都会在 pVisor 默认记录根目录下保留 一条独立 Run:
pvisor run \
--overlaynet-deny 169.254.0.0/16 \
-- agent-command
pvisor status --review --json last | jq '{policy: .network.policy,
interception: .network.interception,
counters: .network.intercepted,
non_bypassable: .safety.network_non_bypassable}'
这些 counter 描述由当前 OverlayNet driver 处理的流量。它们无法统计绕过 cooperative host/container proxy 的流量;VM smoltcp profile 在已支持的 TCP/DNS 数据面之外没有 guest 网络旁路。
常见问题¶
| 现象 | 检查项 |
|---|---|
| 已允许的 hostname 解析到 loopback 或私网地址后仍被拒绝 | 使用显式 IP/CIDR,或仅在范围足够窄的结构化规则上设置 allow_private_ips = true |
使用 --overlaynet-deny-all 后请求仍然成功 |
检查 executor、实际安装的网络边界及内部 Gateway 路由;容器离线使用 --container-network none |
| pVisor 无法绑定代理端口 | 使用 --overlaynet-listen 127.0.0.1:19082 选择一个空闲的非零端口 |
| 容器无法连接代理 | 使用 --container-network host |
VM 的 proxy 模式被拒绝 |
使用 auto 选择 smoltcp,或使用 off 让 guest 离线 |
可以运行
examples/pvisor/03-network-isolation
离线复现 allowlist、deny-all 和 direct-socket bypass。