You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As a user running the local Podman driver on a multi-homed Linux laptop (wired dock + Wi-Fi + Tailscale), I want openshell sandbox create to work without hand-editing the gateway config or bringing interfaces down.
Problem Statement
On a host with multiple network interfaces, the Podman driver and Podman disagree on which host IP host.containers.internal points to, so the in-container supervisor can't reach the gateway and provisioning fails.
The gateway binds its callback listener to the default-route interface plus loopback: 192.168.1.27:17670 and 127.0.0.1:17670.
The driver tells the supervisor to dial host.containers.internal:17670 and injects --add-host host.containers.internal:host-gateway.
Podman resolves host-gateway to a different interface — here the Tailscale address 100.64.0.2 (wt0, CGNAT 100.64.0.0/10), where nothing listens. Bringing Wi-Fi down didn't help; Podman then used the Tailscale IP instead of the wired one.
The supervisor's policy fetch fails, it exits 1, the sandbox container follows, and the sandbox enters Error.
The reported error is also misleading: ContainerExited: Container exited with code 0 refers to the sandbox container reacting to its supervisor dying. The real failure is only in the openshell-supervisor-<id> container logs.
Impact / Why This Matters
Consequence: sandbox creation fails outright on multi-homed hosts (dock + Wi-Fi + VPN/mesh laptops are common), and the surfaced error points at the wrong container, so it's hard to diagnose.
Workaround: set host_gateway_ip = "127.0.0.1" under [openshell.drivers.podman] in ~/.config/openshell/gateway.toml, then systemctl --user restart openshell-gateway. This works because the supervisor uses --network host, so loopback reaches the gateway's 127.0.0.1:17670 listener, and both host.containers.internal and 127.0.0.1 are cert SANs. The sandbox then reaches Ready.
Why insufficient: it relies on an undocumented field and non-obvious reasoning about host-network loopback; it isn't discoverable from the error. The default should just work on multi-homed hosts.
0.0.117-dev / current main (contains feat(isolation): implement the RFC 0012 sandbox architecture #2942, merged 2026-09-16 as c1f2e7189, first released in v0.1.0-pre.2): the same default config fails with Error, and only the host_gateway_ip = "127.0.0.1" workaround makes it succeed. ❌
The gateway binds the same two listeners (192.168.1.27 + 127.0.0.1) on both versions, so the DefaultRouteInterface listener is not the trigger — the change is the callback path.
Mechanism:
feat(isolation): implement the RFC 0012 sandbox architecture #2942 split the sandbox into two containers and moved the gateway callback onto a host-networked supervisor (crates/openshell-driver-podman/src/container.rs: supervisor.netns.nsmode = "host"). Previously a single container made the callback.
non-link-local host IP (here, the Tailscale interface)
The supervisor even warns about this: host.openshell.internal maps to a non-link-local IP; trusted-gateway SSRF exemption disabled. The callback path was designed around a link-local host-gateway (bridge/pasta), which host networking does not provide. On a single-homed host the host-netns resolution still lands on a reachable IP; on a multi-homed host it selects the wrong interface, where nothing listens.
User Story
As a user running the local Podman driver on a multi-homed Linux laptop (wired dock + Wi-Fi + Tailscale), I want
openshell sandbox createto work without hand-editing the gateway config or bringing interfaces down.Problem Statement
On a host with multiple network interfaces, the Podman driver and Podman disagree on which host IP
host.containers.internalpoints to, so the in-container supervisor can't reach the gateway and provisioning fails.192.168.1.27:17670and127.0.0.1:17670.host.containers.internal:17670and injects--add-host host.containers.internal:host-gateway.host-gatewayto a different interface — here the Tailscale address100.64.0.2(wt0, CGNAT100.64.0.0/10), where nothing listens. Bringing Wi-Fi down didn't help; Podman then used the Tailscale IP instead of the wired one.Error.The reported error is also misleading:
ContainerExited: Container exited with code 0refers to the sandbox container reacting to its supervisor dying. The real failure is only in theopenshell-supervisor-<id>container logs.Impact / Why This Matters
Consequence: sandbox creation fails outright on multi-homed hosts (dock + Wi-Fi + VPN/mesh laptops are common), and the surfaced error points at the wrong container, so it's hard to diagnose.
Workaround: set
host_gateway_ip = "127.0.0.1"under[openshell.drivers.podman]in~/.config/openshell/gateway.toml, thensystemctl --user restart openshell-gateway. This works because the supervisor uses--network host, so loopback reaches the gateway's127.0.0.1:17670listener, and bothhost.containers.internaland127.0.0.1are cert SANs. The sandbox then reachesReady.Why insufficient: it relies on an undocumented field and non-obvious reasoning about host-network loopback; it isn't discoverable from the error. The default should just work on multi-homed hosts.
Confirmed Regression (#2942)
Confirmed by version bisection: this is a regression introduced by PR #2942 (RFC 0012 sandbox architecture).
openshell sandbox createreaches a working sandbox shell with default config (nohost_gateway_ip) on this multi-homed host. ✅c1f2e7189, first released inv0.1.0-pre.2): the same default config fails withError, and only thehost_gateway_ip = "127.0.0.1"workaround makes it succeed. ❌192.168.1.27+127.0.0.1) on both versions, so theDefaultRouteInterfacelistener is not the trigger — the change is the callback path.Mechanism:
feat(isolation): implement the RFC 0012 sandbox architecture #2942 split the sandbox into two containers and moved the gateway callback onto a host-networked supervisor (
crates/openshell-driver-podman/src/container.rs:supervisor.netns.nsmode = "host"). Previously a single container made the callback.The callback machinery predates feat(isolation): implement the RFC 0012 sandbox architecture #2942 and assumes bridge/pasta semantics: the
DefaultRouteInterfacelistener negotiation is from feat(compute): negotiate gateway callback listeners #2492, and thehost-gateway--add-hostinjection from fix(podman): avoid host-gateway on macOS machines #1637.Under the same
--add-host host.containers.internal:host-gateway, the network mode changes what the alias resolves to:host.containers.internalresolves to--network openshell) — pre-feat(isolation): implement the RFC 0012 sandbox architecture #2942 style169.254.1.2(link-local host-gateway)--network host) — feat(isolation): implement the RFC 0012 sandbox architecture #2942 supervisorThe supervisor even warns about this:
host.openshell.internal maps to a non-link-local IP; trusted-gateway SSRF exemption disabled. The callback path was designed around a link-local host-gateway (bridge/pasta), which host networking does not provide. On a single-homed host the host-netns resolution still lands on a reachable IP; on a multi-homed host it selects the wrong interface, where nothing listens.Note: the
host_gateway_ip = "127.0.0.1"workaround only works because the supervisor is now host-networked (an artifact of the feat(isolation): implement the RFC 0012 sandbox architecture #2942 change) and therefore shares the host loopback.Acceptance Criteria
Readywith the Podman driver using default config (no manualhost_gateway_ip).host-gateway.ContainerExited: code 0.host_gateway_ipguidance is documented.Reproduction Steps
host-gatewayresolution (e.g. wired dock + Wi-Fi + Tailscale), configure the Podman driver.openshell sandbox create --provider <any>.Errorduring provisioning.Confirm the mismatch:
Environment
0.0.117-dev.167+g7e7a8d561(development build; regression absent in0.0.116), installed with:curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | OPENSHELL_VERSION=dev sh7.2.5-200.fc44.x86_645.8.4(netavark)podman(rootless); gateway runs as theopenshell-gatewaysystemd user service (native install, not containerized)192.168.1.27, Wi-Fi192.168.1.75(same subnet), Tailscalewt0in100.64.0.0/10Related
Related: #2540, #1952, and the macOS cases #1519 / #1634. Distinct from #1909 (containerized gateway on Fedora 44).
Logs
Supervisor container (
openshell-supervisor-<id>) — the actual failure: