fix(net): run sly-net-client in the host user namespace - #126
Merged
Conversation
On a daemon started with `userns-remap`, Docker rejects the net-client outright:
"privileged mode is incompatible with user namespaces. You must run the
container in the host namespace when running privileged mode". The container is
never created, so the agent comes up with no VPN and only warns
("can't find sly-net-client attached to this agent") -- tasks still run, v2 apps
have no tunnel.
UsernsMode only controls whether the DAEMON's userns-remap applies to this
container. A daemon without one -- the default, and what every normal install
runs -- is unaffected, and rootless Docker has no remap either: its namespace
comes from RootlessKit at daemon level and is untouched by this. So this is a
no-op everywhere except the hosts where it is currently fatal.
Also carried through the update path, which rebuilds the container from the
HostConfig of the one it replaces. It copies Binds, CapAdd, Privileged, Devices
and RestartPolicy but had no reason to know about UsernsMode, so without this
the net-client would survive its own update exactly once.
Verified on a userns-remap daemon: privileged alone is rejected, privileged +
userns=host starts BoringTun and brings up the sly-net interface. Worth noting
--privileged may not be needed at all here -- NET_ADMIN plus /dev/net/tun is
enough for both the userspace and the kernel WireGuard paths on this host -- but
it was added deliberately in 6889108d1 (2023-08-02) on top of an already-working
NET_ADMIN setup, with no recorded reason, so it is left alone.
tonybart1337
force-pushed
the
fix/net-client-userns-host
branch
from
August 8, 2026 14:35
a52abe3 to
d7df30a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On a daemon started with
userns-remap, sly-net-client is never created at all:The agent's own logs make this look like a network problem —
Something went wrong: couldn't start sly-net-client, thencan't find sly-net-client attached to this agent— so the natural first guess is a firewall or an unexposed WireGuard port. It isn't: no container was ever created, so nothing had a chance to connect. Tasks keep running; v2 apps have no tunnel.Fix
userns_mode="host"on the net-client container.UsernsModeonly controls whether the daemon'suserns-remapapplies to this container. A daemon without one — the default, and what every normal install runs — is unaffected, so this is a no-op there. Rootless Docker has no remap either; its namespace comes from RootlessKit at daemon level and is untouched by this. The only hosts where it changes anything are the ones where the container currently cannot start.Also carried through
agent.py's update path, which rebuilds the container from the HostConfig of the one it replaces. It copiesBinds,CapAdd,Privileged,DevicesandRestartPolicybut had no reason to know aboutUsernsMode, so without this the net-client would survive its own update exactly once, then fail on the next one. Read with.getso a container created before this change (no such key) still updates cleanly.Verification
On a
userns-remapdaemon:--privilegedalone--privileged --userns=hostsly-netinterface comes upOne side note, deliberately not changed here.
--privilegedlooks unnecessary:NET_ADMINplus/dev/net/tunis enough for both the userspace and the kernel WireGuard paths (wg-quickprefers the kernel module when present and only falls back toWG_QUICK_USERSPACE_IMPLEMENTATIONotherwise — both were verified working without privileged). But privileged was added deliberately in supervisely/main6889108d1(2023-08-02) on top of an already-workingNET_ADMINsetup, as a standalone one-liner with no recorded reason — most likely to fix a specific customer host. Dropping it is a separate, riskier change that wants whoever remembers that incident.Releasing as 6.9.7.
app/config.jsonis deliberately untouched --app-release.ymlrunsapp/update_config.py $VERSIONfrom the tag and commits the bump itself after the release ispublished, which is where the
Update config for release ...commits on master come from.