Skip to content

Instantly share code, notes, and snippets.

@drio
Created April 10, 2025 14:16
Show Gist options
  • Save drio/858480d091ad1a4d72930732c9095768 to your computer and use it in GitHub Desktop.
Save drio/858480d091ad1a4d72930732c9095768 to your computer and use it in GitHub Desktop.
The most fascinating thing...
The most fascinating thing I've learned recently is how userspace networking
works, particularly in mesh networks like Tailscale.
When you want to encrypt network traffic, you typically use a TUN/TAP device
provided by the operating system. At a high level, here's how (I think) it works:
When applications send data over the network via sockets, the data follows
the OS networking stack, which adds the necessary headers. If the destination
IP address matches your TUN device, the kernel redirects that packet to the
userland application controlling the TUN device (e.g., tailscaled).
This userland application then processes the packet however needed - in
Tailscale's case, typically encrypting and sending it over an established
WireGuard connection. For incoming traffic, packets reaching the network
interface are processed by the device driver and move up the network stack.
The kernel delivers these packets to tailscaled, which decrypts them and
reinjects them into the network stack for delivery to the appropriate
application.
But creating a TUN device requires root privileges. This is
where userspace networking becomes valuable. Tailscale's binary includes
a complete userspace TCP/IP stack from gVisor. When userspace networking is
enabled, you're still conceptually creating a TUN device, but at the userspace
level - socket creation uses gVisor's entry points instead of the kernel's.
The payload gets processed entirely in userspace. When Tailscale receives the
resulting IP or UDP packet, it encapsulates and sends it over another socket
through the WireGuard connection. This packet then flows through the kernel's
TCP stack before being transmitted.
This approach lets you join a device to a Tailscale network (a "tailnet")
without root access. With one limitation: other processes on that machine
cannot send data to the tailnet. To overcome this, you can use Tailscale's
SOCKS5 proxy feature with the --socks5-server flag.
This capability is truly mind-blowing. It's how Tailscale can run in browsers,
which lack traditional socket APIs and rely on technologies like WebSockets for
networking. One Tailscale engineer (Brad) has created a demonstration of this
concept. His implementation (from my understanding) tunnels WireGuard UDP
packets over WebSockets, using Tailscale's relay servers (DERP) which
"talk" websockets.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment