Skip to content

network isolation - #311

Draft
jeckersb wants to merge 7 commits into
bootc-dev:mainfrom
jeckersb:network-isolation
Draft

network isolation#311
jeckersb wants to merge 7 commits into
bootc-dev:mainfrom
jeckersb:network-isolation

Conversation

@jeckersb

@jeckersb jeckersb commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator
  • feat: Add --network-isolation CLI flag (no-op)
    Add the --network-isolation flag to both the ephemeral (CommonVmOpts)
    and libvirt (LibvirtRunOpts) CLI option structs. The flag is accepted
    by the CLI parser but has no effect yet; the actual QEMU restrict=on
    wiring follows in subsequent commits.

    This allows the integration test to be written against the flag
    immediately, following TDD practice.

    Closes: Add network isolation support #304

    Assisted-by: AI
    Signed-off-by: John Eckersberg jeckersb@redhat.com

  • test: Add integration tests for network isolation
    Add two tests for --network-isolation support:

    • test_run_ephemeral_network_reachable: positive control that boots a
      normal VM and verifies it can ping 8.8.8.8 from inside the guest.
      This proves run-ssh, guest networking, and external reachability
      all work. Without this, the isolation test could pass vacuously
      when SSH or networking is broken for unrelated reasons.

    • test_run_ephemeral_network_isolation: boots a VM with
      --network-isolation and verifies that pinging 8.8.8.8 from inside
      the guest fails. Includes the same positive control as a first step
      to guard against false passes. The fact that run-ssh itself succeeds
      proves SSH (host-to-guest via hostfwd) is preserved.

    Both tests skip gracefully with a loud warning when the host cannot
    reach 8.8.8.8 (e.g. offline environments).

    The isolation test is expected to fail against the current no-op flag
    (the positive control succeeds, then the isolation check fails because
    the guest can still reach the internet). This establishes the TDD
    baseline that the implementation commits will fix.

    Assisted-by: AI
    Signed-off-by: John Eckersberg jeckersb@redhat.com

  • feat(qemu): Add restrict support to NetworkMode::User
    Add a restrict field to NetworkMode::User that maps to QEMU's
    slirp restrict=on option. When enabled, the guest cannot initiate
    outbound connections except through explicit hostfwd rules (e.g. SSH
    port forwarding). This is the mechanism that --network-isolation will
    use.

    • Add restrict: bool to NetworkMode::User, defaulting to false
    • Add set_network_restrict() builder method on QemuConfig
    • Update enable_ssh_access() to preserve the restrict setting
    • Emit restrict=on in the -netdev argument when enabled
    • Add unit tests for the new functionality

    Assisted-by: AI
    Signed-off-by: John Eckersberg jeckersb@redhat.com

  • feat: Wire --network-isolation to QEMU restrict for ephemeral VMs
    When --network-isolation is passed to bcvk ephemeral run or
    bcvk ephemeral run-ssh, set restrict=on on the QEMU slirp netdev.
    This blocks all guest-initiated outbound connections while preserving
    SSH access via hostfwd.

    DNS server injection is also skipped under isolation since external
    DNS servers are unreachable and the entries would only cause timeouts.

    Assisted-by: AI
    Signed-off-by: John Eckersberg jeckersb@redhat.com

  • feat: Wire --network-isolation to QEMU restrict for libvirt VMs
    When --network-isolation is passed to bcvk libvirt run, add
    restrict=on to the QEMU user-mode netdev arguments injected via
    qemu:commandline. This blocks all guest-initiated outbound
    connections while preserving SSH access via hostfwd, matching the
    ephemeral path behavior.

    Assisted-by: AI
    Signed-off-by: John Eckersberg jeckersb@redhat.com

  • docs: Sync manpages with --network-isolation option
    Run cargo xtask sync-manpages to regenerate the OPTIONS sections,
    picking up the new --network-isolation flag in:

    • bcvk-ephemeral-run(8)
    • bcvk-ephemeral-run-ssh(8)
    • bcvk-libvirt-run(8)
    • bcvk-to-disk(8)

    Also picks up a previously missing --virtiofsd option in
    bcvk-libvirt-run(8).

    Assisted-by: AI
    Signed-off-by: John Eckersberg jeckersb@redhat.com

  • docs: Add network isolation examples and prose
    Add hand-written documentation for --network-isolation to:

    Manpages (EXAMPLES sections, outside auto-generated markers):

    • bcvk-ephemeral-run(8): network isolation example with bind-storage-ro
    • bcvk-ephemeral-run-ssh(8): quick CI testing example
    • bcvk-libvirt-run(8): hermetic testing example

    mdBook conceptual docs:

    • ephemeral-run.md: new Network Isolation section with example
    • libvirt-advanced.md: network isolation subsection under Network
      Configuration

    All hand-written sections are outside the markers and will be preserved by future sync-manpages
    runs.

    Assisted-by: AI
    Signed-off-by: John Eckersberg jeckersb@redhat.com

Add the --network-isolation flag to both the ephemeral (CommonVmOpts)
and libvirt (LibvirtRunOpts) CLI option structs. The flag is accepted
by the CLI parser but has no effect yet; the actual QEMU restrict=on
wiring follows in subsequent commits.

This allows the integration test to be written against the flag
immediately, following TDD practice.

Closes: bootc-dev#304

Assisted-by: AI
Signed-off-by: John Eckersberg <jeckersb@redhat.com>
Add two tests for --network-isolation support:

- test_run_ephemeral_network_reachable: positive control that boots a
  normal VM and verifies it can ping 8.8.8.8 from inside the guest.
  This proves run-ssh, guest networking, and external reachability
  all work. Without this, the isolation test could pass vacuously
  when SSH or networking is broken for unrelated reasons.

- test_run_ephemeral_network_isolation: boots a VM with
  --network-isolation and verifies that pinging 8.8.8.8 from inside
  the guest fails. Includes the same positive control as a first step
  to guard against false passes. The fact that run-ssh itself succeeds
  proves SSH (host-to-guest via hostfwd) is preserved.

Both tests skip gracefully with a loud warning when the host cannot
reach 8.8.8.8 (e.g. offline environments).

The isolation test is expected to fail against the current no-op flag
(the positive control succeeds, then the isolation check fails because
the guest can still reach the internet). This establishes the TDD
baseline that the implementation commits will fix.

Assisted-by: AI
Signed-off-by: John Eckersberg <jeckersb@redhat.com>
Add a `restrict` field to `NetworkMode::User` that maps to QEMU's
slirp `restrict=on` option. When enabled, the guest cannot initiate
outbound connections except through explicit hostfwd rules (e.g. SSH
port forwarding). This is the mechanism that --network-isolation will
use.

- Add `restrict: bool` to `NetworkMode::User`, defaulting to false
- Add `set_network_restrict()` builder method on QemuConfig
- Update `enable_ssh_access()` to preserve the restrict setting
- Emit `restrict=on` in the -netdev argument when enabled
- Add unit tests for the new functionality

Assisted-by: AI
Signed-off-by: John Eckersberg <jeckersb@redhat.com>
When --network-isolation is passed to `bcvk ephemeral run` or
`bcvk ephemeral run-ssh`, set restrict=on on the QEMU slirp netdev.
This blocks all guest-initiated outbound connections while preserving
SSH access via hostfwd.

DNS server injection is also skipped under isolation since external
DNS servers are unreachable and the entries would only cause timeouts.

Assisted-by: AI
Signed-off-by: John Eckersberg <jeckersb@redhat.com>
When --network-isolation is passed to `bcvk libvirt run`, add
restrict=on to the QEMU user-mode netdev arguments injected via
qemu:commandline. This blocks all guest-initiated outbound
connections while preserving SSH access via hostfwd, matching the
ephemeral path behavior.

Assisted-by: AI
Signed-off-by: John Eckersberg <jeckersb@redhat.com>
Run `cargo xtask sync-manpages` to regenerate the OPTIONS sections,
picking up the new --network-isolation flag in:
- bcvk-ephemeral-run(8)
- bcvk-ephemeral-run-ssh(8)
- bcvk-libvirt-run(8)
- bcvk-to-disk(8)

Also picks up a previously missing --virtiofsd option in
bcvk-libvirt-run(8).

Assisted-by: AI
Signed-off-by: John Eckersberg <jeckersb@redhat.com>
Add hand-written documentation for --network-isolation to:

Manpages (EXAMPLES sections, outside auto-generated markers):
- bcvk-ephemeral-run(8): network isolation example with bind-storage-ro
- bcvk-ephemeral-run-ssh(8): quick CI testing example
- bcvk-libvirt-run(8): hermetic testing example

mdBook conceptual docs:
- ephemeral-run.md: new Network Isolation section with example
- libvirt-advanced.md: network isolation subsection under Network
  Configuration

All hand-written sections are outside the <!-- BEGIN/END GENERATED
OPTIONS --> markers and will be preserved by future sync-manpages
runs.

Assisted-by: AI
Signed-off-by: John Eckersberg <jeckersb@redhat.com>
@jeckersb

jeckersb commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator Author

Throwing this up as draft before I disappear for a week. Few quick thoughts:

  • I don't really love the way the tests do probing of 8.8.8.8 and then try to "fail loudly", some cursory AI probing suggests the test suite would be able to generate skips if the prereqs aren't met, that would be better but more involved (probably better as a prep PR)
  • I did intentionally order the commits though so we could run the commit that adds the tests and see them fail before fast-forwarding to the rest of it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add network isolation support

1 participant