From 018ea1a34dc54cfeb323ee81a63dd806b1665efc Mon Sep 17 00:00:00 2001 From: Pedro Henrique Penna Date: Thu, 29 Oct 2026 07:30:39 -0700 Subject: [PATCH] doc: say which network policies attach no network device doc/run.md and doc/usage.md said that a sandbox policy that "lets nothing through" attaches no network device, and listed egress denied without allow rules, ingress denied, and --host-loopback deny. That is not the rule that nvx::host::network::openvmm_arguments applies: it attaches no device exactly when a policy has no proxy, denies egress by default without allow rules, and denies ingress and host-loopback access, whatever its deny rules. Both parts of the description were too broad: - A policy can let nothing through and still attach a device. A sandbox with --network-egress deny and --host-loopback deny renders --net and both rules when it also has --network-egress-allow 192.0.2.1 and --network-egress-deny 192.0.2.0/24, whose deny rule covers the allow rule. Through the Rust API, a NetworkPolicy whose allow rule excepts its whole destination lowers to no OpenVMM rule but attaches a device too, as #1001 reports. - A proxy-only policy has every option that the documents listed, but attaches a device for its proxy. The documents also did not say which allow rules count. The CLI compiles a --network-egress-policy-file to native rules before it builds the policy, so a file whose allow rules all except their whole destinations leaves no allow rule and attaches no device, while the same rule in a typed policy of the Rust API counts. Name the condition by its options in the Sandbox networking section of doc/run.md, in its note on what changed since earlier releases, and in the --net row of the sandbox options in doc/usage.md. Say that a policy file's allow rules are those that it compiles to, that any other policy attaches a device even if it lets nothing through, and that the typed policy of the Rust API counts every allow rule. The issue also offers attaching no device for a policy whose allow rules lower to no OpenVMM rule. That would change behavior and the template key of such policies, which the open template stack, #958 and the pull requests above it, derives from this lowering; #958 even defines the device of a closed policy as the one that the same policy gets with one more such rule. So this change keeps the behavior and documents it. Fixes #1001. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- doc/run.md | 31 ++++++++++++++++++++----------- doc/usage.md | 2 +- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/doc/run.md b/doc/run.md index 86f27fd13..9029cf250 100644 --- a/doc/run.md +++ b/doc/run.md @@ -1180,13 +1180,20 @@ message. Without `--net`, the sandbox has no network device, and the other network options are refused. With it, an omitted option takes OpenVMM's default: egress allowed, ingress denied, and host-loopback access from the workload -alone, through its gateway. A policy that lets nothing through, egress denied -without allow rules, ingress denied, and `--host-loopback deny`, attaches no -network device. Egress rules need an explicit `--network-egress`, as OpenVMM -requires. Forwards need `--host-loopback allow`; UDP forwards also need egress -allowed by default and no deny rule that covers the guest network, which -carries their replies. `--host-loopback allow` needs a guest network prefix of -`/29` or shorter; see [Host-loopback access](#host-loopback-access). +alone, through its gateway. A policy attaches no network device when it has +`--network-egress deny` and `--host-loopback deny`, and no allow rules, +`--network-ingress allow`, or `--network-proxy`, whatever its deny rules. The +allow rules of a `--network-egress-policy-file` are the native rules that it +compiles to, so a file whose allow rules all except their whole destinations +compiles to none. Any other policy attaches a network device, even one that +lets nothing through, such as one whose `--network-egress-deny 192.0.2.0/24` +covers its `--network-egress-allow 192.0.2.1`. In the typed policy of the NVX +Rust API, every allow rule counts, even one that lowers to no OpenVMM rule. +Egress rules need an explicit `--network-egress`, as OpenVMM requires. Forwards +need `--host-loopback allow`; UDP forwards also need egress allowed by default +and no deny rule that covers the guest network, which carries their replies. +`--host-loopback allow` needs a guest network prefix of `/29` or shorter; see +[Host-loopback access](#host-loopback-access). #### Proxy-only networking @@ -1237,10 +1244,12 @@ refuses, before launch: proxy, and a proxy that is not at the gateway, which OpenVMM refused as it started. -A policy that lets nothing through now attaches no network device, where -OpenVMM attached one that carried nothing. `start` refuses a sandbox that an -earlier release provisioned, whose configuration records the network options -rather than the typed policy; deprovision it and provision it again. +A policy with `--network-egress deny` and `--host-loopback deny`, and no allow +rules, `--network-ingress allow`, or `--network-proxy`, now attaches no network +device, where OpenVMM attached one that carried nothing. `start` refuses a +sandbox that an earlier release provisioned, whose configuration records the +network options rather than the typed policy; deprovision it and provision it +again. The explicit `test-microvm --scenario sandbox-proxy-only --backend BACKEND` scenario is the acceptance for proxy-only networking. Like the diff --git a/doc/usage.md b/doc/usage.md index 6c27549df..cec2afab6 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -301,7 +301,7 @@ do, and their names cannot be abbreviated either. | `--mount-allow HOST_PATH` | none | Expose one existing file or directory inside a `--mount-deny` path of the same share again, for example a readable `mcp-payloads` directory inside hidden logs. The hidden directories on the way list only the entries that lead to it, and the workload cannot modify them. Relative paths are resolved inside the share; with several shares, it applies to the `--mount` before it. Repeat to allow multiple paths. See [Access policy](run.md#access-policy). | | `--mount-write HOST_PATH` | none | Make one existing file or directory one of the only writable parts of an `rw` share; the workload's writes anywhere else in the share fail with `EROFS`. Relative paths are resolved inside the share; with several shares, it applies to the `--mount` before it, which must be `rw`. Repeat to declare multiple writable paths. `provision` persists the denied, allowed, and writable paths. | | `--mount-owner {vmm,caller}` | `vmm` | Select the host identity of the shares' file operations for `run` or `provision`. `vmm` performs them as OpenVMM; `caller` performs them as the workload's UID and GID, squashes guest root to the owner of each shared host directory or file, and fails them with `EPERM` when OpenVMM cannot assume that identity. `caller` requires a Linux host and is persisted by `provision`. See [File ownership](run.md#file-ownership). | -| `--net IPV4/PREFIX` | none | Enable virtio-net with a static guest address. The guest also gets the IPv6 address that embeds it in `fd00::/96`. The other network options need it. A policy that lets nothing through, `--network-egress deny` without allow rules, with ingress denied and `--host-loopback deny`, attaches no network device. | +| `--net IPV4/PREFIX` | none | Enable virtio-net with a static guest address. The guest also gets the IPv6 address that embeds it in `fd00::/96`. The other network options need it. A policy with `--network-egress deny` and `--host-loopback deny`, and no allow rules, `--network-ingress allow`, or `--network-proxy`, attaches no network device, whatever its deny rules; a policy file's allow rules are those that it compiles to. Any other policy attaches one, even one that lets nothing through; see [Sandbox networking](run.md#sandbox-networking). | | `--network-profile {portable}` | none | Select the required cross-platform network behavior contract; must be specified with `--net`. | | `--network-egress {allow,deny}` | `allow` | Set the default guest egress policy for `run` or `provision`. | | `--network-ingress {allow,deny}` | `deny` | Set the host ingress policy for `run` or `provision`. `allow` publishes every TCP and UDP port on which the workload listens to clients on the host's private networks, and to the host itself only with `--host-loopback allow`; see [Private-network ingress](run.md#private-network-ingress). |