Skip to content

Feature/netns#14

Open
netpleb wants to merge 2 commits into
rti:mainfrom
netpleb:feature/netns
Open

Feature/netns#14
netpleb wants to merge 2 commits into
rti:mainfrom
netpleb:feature/netns

Conversation

@netpleb
Copy link
Copy Markdown
Contributor

@netpleb netpleb commented Jun 4, 2026

I find myself occasionally doing something like sudo ip netns exec sandbox sudo -u netpleb nix run .#wrap -- -n ..., so I used claude to add a little feature to wrap which lets me just pass wrap -N sandbox <command>. It basically handles the use case discussed in #2

I wish there was a clean way to do it which did not require sudo, and for that reason I do not really expect this to be merged. Just wanted to share it here in case anyone else might be looking for a way to use wrap/bwrap with network namespaces.

WAYLAND_DISPLAY and XAUTHORITY may each be either a bare name (resolved
relative to XDG_RUNTIME_DIR and $HOME respectively) or an absolute path.
The old code always prepended the base directory, so an absolute value
produced a malformed path like /run/user/1001//run/user/1000/wayland-0
or /home/alice//run/user/1000/.mutter-Xwaylandauth.XXXXXX, causing a
bwrap "Can't find source path" error and breaking -d desktop access.

Detect the absolute form for both and use it as-is, otherwise resolve
relative to the base as before. Guard each bind with an existence check
so a stale/missing socket or auth file is skipped instead of crashing
bwrap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a -N NAME option that launches the wrapped program inside a
pre-existing Linux network namespace (e.g. one set up by the new
netns-sandbox.sh, which routes all traffic through a WireGuard VPN).

Unlike -n, which only shares the host net, -N keeps the target
namespace's network so the sandboxed process inherits the namespace's
routing, firewall, and VPN-provided DNS. To enter it, wrap prefixes the
launch with 'sudo ip netns exec NAME sudo -u $USER', dropping back to
the invoking user before exec'ing bwrap.

The process must live in the namespace's net, so -N keeps the default
--unshare-all and appends --share-net after it: per bwrap(1) --share-net
"retains the network namespace, overriding an earlier --unshare-all".
This yields full isolation minus net without hand-enumerating each
namespace, mirroring how -n already works. It also implies the network
binds (resolv.conf, ssl) so DNS and TLS work, relying on the kernel
exposing /etc/netns/NAME/resolv.conf as /etc/resolv.conf in the namespace.

Documents the flag under ADVANCED OPTIONS in usage and README.
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