Skip to content

BuildNot yet confirmed elsewhere1 publisher2 min readPublished

Tailscale in unprivileged LXC: the green dot that answers nothing

The standard --tun=userspace-networking advice produces a tailnet member you cannot SSH into. The repair is two lines of container config, not a privileged container.

The Engineer · Build desk

How we use AISend a correction

What happened

  • The standard userspace-networking flag registers the container in the tailnet and reports healthy status, then SSH from a laptop hangs until TCP times out.
  • The cause is that tailscaled runs gVisor's netstack inside its own process and never opens /dev/net/tun.
  • Netstack's UDP has been partial for years, so mosh-server starts and prints its key while the client waits for datagrams that never arrive.
  • The author's fix is two lines in the LXC config file, with the container remaining unprivileged.

Why it matters

  • exposure Any process that misses the proxy variable sends traffic you believe is on the tailnet out over the ordinary default route, and nothing logs a failure.
  • constraint Staying in userspace mode means your hardened sshd_config is no longer the thing answering, so tuned SSH policy has to be duplicated in a second place.
  • decision The forum shortcut to working TUN asks you to hand a VPN-facing container a root that maps to host root, which is the choice this config removes.
  • capability Each container can hold its own tailnet identity and ACL surface rather than depending on one subnet router to speak for all of them.

Rank the failure modes before you rank the fixes. A hung SSH session is loud, and you find it inside an hour [2]. The quiet one is outbound traffic: in userspace mode nothing on the system routes to 100.64.0.0/10, because there is no interface and no route, so every client has to be pointed at the SOCKS5 or HTTP proxy that tailscaled exposes on a local port [4]. Miss that variable in one systemd unit or one cron job and the packets take the normal default route with no error at all [5]. That is the sort of thing that stays wrong for months, and it is a property of the design rather than a mistake in it.

Tailscale SSH is what keeps the design's edges out of view. It genuinely works in userspace mode, which is why plenty of operators never discover the limitation, according to the post [7]. What they have is tailscaled acting as the SSH server, not OpenSSH answering on the container's own port, because tailnet packets terminate in netstack with no path to a kernel-owned socket unless you build one [6][7].

The debugging trail is where the time goes. Forum advice converges on three knobs, and by the post's account two of them are irrelevant to the problem: nesting governs cgroup hierarchy and procfs/sysfs views, and device access is a separate mechanism entirely [10], while AppArmor unconfined is named as the third dead end [11]. So of the three remedies in circulation, two change nothing about TUN and the third changes the container's security model [14]. The working answer sits in the mechanism none of them touch, and the post supplies it as two lines that leave the container unprivileged [1][10].

The test of success is also worth restating, because the admin console is not it. What you are buying is a kernel network interface that `ip addr` can see, a real address in the CGNAT range, and a direct WireGuard path rather than reachability borrowed from something else [13]. A green dot and a healthy `tailscale status` were available all along [2].

What to watch

  • Whether Tailscale closes the netstack UDP gap, which would remove the strongest functional reason to leave userspace mode.
  • Whether the device-access config keys survive Proxmox and LXC template changes, since a silently ignored line reverts you to the hanging-SSH state.
  • Whether per-container identities multiply into an ACL set nobody maintains once the node count grows.

Clarity's read

What the record supports and how the coverage leans. The claims behind it follow.

Reality

Evidence52
Adoption
Insufficient
Hype gap+14
Incentives30
Confidence55
Why these scores

Claim ledger

Ranked by verification strength, evidence, and original report placement.

  1. [1]

    Two lines in the LXC config file fix the problem, and the container stays unprivileged.

  2. [2]

    With tailscale up --tun=userspace-networking, the node appears in the tailnet and tailscale status looks healthy, but SSH into that container from a laptop hangs until TCP gives up.

    ReportedSupportedView cited source
  3. [3]

    In userspace mode tailscaled runs a userspace TCP/IP stack (gVisor's netstack) inside its own process and never opens /dev/net/tun.

    ReportedSupportedView cited source

Sources

1 independent publisher whose own reporting we read for this story.

  1. dev.to

    1 article · August 21, 2026

    Tailscale Kernel TUN in Unprivileged LXC: Direct SSH Without Userspace Networking

Share your take

Let Clarity write the post for you.

Signed-in readers get a short post drafted on this story in the register they choose — narrative, analytical, or a direct position — editable to the last word before it goes anywhere. The share buttons at the top of this story work without an account.

Topics and entities

Follow any of these and your For You feed starts watching them — no settings page required.

Topics

  • Silent network failure modesFollow
  • Tailscale / WireGuard mesh VPNFollow
  • Userspace vs kernel networking stacksFollow
  • LXC and Proxmox container operationsFollow
  • Container isolation tradeoffsFollow
Loading related stories