Skip to content

Firewall the VM in locked and offline sessions (apple backend) - #9

Merged
Kernel-Hunter merged 4 commits into
mainfrom
guest-firewall
Oct 20, 2026
Merged

Kernel-Hunter merged 4 commits into
mainfrom
guest-firewall

Conversation

@Kernel-Hunter

Copy link
Copy Markdown
Owner

With the apple backend the host-only network's gateway is the Mac, so a locked sandbox could reach any service on the Mac that listens on all interfaces, and other VMs on the same network. This closes that gap.

The sandbox now starts as root with only CAP_NET_ADMIN, loads an nftables table that allows loopback and TCP to the proxy's address and port (nothing but loopback in offline mode), checks the table is loaded, and then runs the image's entrypoint and command through setpriv as the image's user with no capabilities, an empty bounding set and no_new_privs. If nft or setpriv is missing or the rules don't load, the agent is not started.

  • Agent image: adds nftables. Images built by 0.2.1 and earlier need mudroom image build before locked or offline sessions start; the error says so.
  • network check opens a port on all of the host's interfaces and probes it from the sandbox, and tries to remove the firewall as the sandbox user.
  • Docker and Podman are unchanged apart from the extra network check probe.

Tested on an M5 Mac with container 1.5.0: swift test 232 tests pass. mudroom network check --mode locked --backend apple with the new image: the host port and 1.1.1.1 get EHOSTUNREACH, nft flush ruleset as the sandbox user gets Operation not permitted, and the host port is still blocked after that. With the old image the check stops with the rebuild message and the agent never starts.

setpriv already comes with util-linux. Changing the Containerfile also
marks images from older versions as outdated in Setup.
The host-only network's gateway is the Mac, so a VM could connect to any
service on the Mac listening on all interfaces, and to other VMs. Locked
and offline sandboxes now start as root with CAP_NET_ADMIN in a short
shell script that loads an nftables table allowing only loopback and TCP
to the proxy (only loopback when offline), checks it is in place, and then
runs the image's entrypoint and command through setpriv as the image's
user, with no capabilities, an empty bounding set and no_new_privs.

If nft or setpriv is missing or the rules don't load, the script exits
with status 125 and the agent never runs. The pre-session probe runs
behind the same firewall, so such an image stops the session before it
starts. Docker and Podman are unchanged.
… VM firewall

Instead of port 7000, which may or may not be open, the check listens on
all of the host's interfaces (not on Windows, where that can bring up a
firewall prompt) and tries that port from the sandbox. Behind the VM
firewall it also runs nft flush ruleset as the sandbox's user and tries
the port again. Reaching the host now fails the check when the firewall
is on. Adds --image.
Locked and offline mode, the network check output, a section on how the
firewall is set up and what it needs from an image, and the limitation
that replaces the open gap to the Mac's services.
@Kernel-Hunter
Kernel-Hunter merged commit 7c0ac41 into main Oct 20, 2026
19 of 20 checks passed
@Kernel-Hunter
Kernel-Hunter deleted the guest-firewall branch October 21, 2026 13:44
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.

1 participant