Diagram of a NetBird mesh network connecting multiple nodes over WireGuard
Network

NetBird: a peer-to-peer WireGuard mesh VPN with a fully self-hostable control plane

You have a laptop, a couple of production servers, a NAS at home, and a contractor who needs temporary access to one database. The classic answer: point-to-point WireGuard, keys generated by hand, wg-quick on every machine, and an AllowedIPs line you edit every time a new peer shows up. It works, until the mesh grows to a dozen nodes and every new peer means touching the config on the other eleven.

This is exactly the gap managed mesh VPNs fill: Tailscale, ZeroTier and others solve it, but with a trade-off - the control plane (identity, topology, access policy) lives on someone else’s servers. NetBird (netbird.io ) is the open-source project (BSD-3 licensed) that keeps the same peer-to-peer WireGuard model but makes the entire control plane self-hostable: both the management server and the signal server that helps pairs of nodes negotiate a direct connection. We evaluated it as an alternative to the commercial stack for cases where you want a mesh VPN without your network topology living on a third party’s infrastructure.

What NetBird actually is

NetBird builds an overlay network on top of WireGuard: every node (server, laptop, container, phone) gets a cryptographic identity and an IP address from a private range, and traffic between nodes travels, ideally, directly between them, encrypted with WireGuard, without passing through a central hub. The hard part - establishing the connection - uses an ICE-like mechanism (Interactive Connectivity Establishment), similar to what WebRTC uses: nodes first attempt a direct peer-to-peer connection (with NAT hole punching where possible), and if NAT traversal fails (double symmetric NAT, restrictive firewalls), NetBird falls back to a relay server so you don’t end up with no connectivity at all.

The server side is two distinct components, both of which you run on your own infrastructure in the self-hosted setup:

  • Management server: tracks nodes, groups, access policies and registration keys. It’s the “brain” of the network.
  • Signal server: a signaling channel through which two nodes exchange what they need (WireGuard public keys, connection candidates) before establishing the actual tunnel. It never sees application traffic, only coordinates the handshake.

User identity isn’t reinvented: NetBird plugs into any OIDC/SSO provider (Keycloak, Authentik, Zitadel, Google, and others), so adding or removing a teammate from the network is essentially a matter of managing an account in the IdP you already run.

Why this matters

The difference from a commercial mesh VPN isn’t cosmetic. If the vendor behind the service shuts down, loses your data, or abruptly changes its pricing, a self-hosted control plane means that’s a technical problem you can solve yourself, not a negotiation with a vendor. It comes down to whether the full map of your infrastructure (who talks to whom, what access rules exist) lives on your servers or someone else’s. For teams with compliance requirements, or anyone who simply doesn’t want a critical external dependency on connectivity, that difference is real.

What you get out of the box

  • A peer-to-peer overlay network built on WireGuard, with automatic private addressing per node
  • NAT traversal via ICE/STUN with fallback to a TURN-like relay when direct traversal fails
  • Authentication via SSO/OIDC (Keycloak, Authentik, Zitadel, Google, and others), so you don’t have to build a separate user system
  • Group-based access policies (who can talk to whom, on which ports), not just “everyone sees everything”
  • Setup keys for automatically registering nodes, useful for scripted provisioning or ephemeral containers
  • Cross-platform clients (Linux, Windows, macOS, mobile) plus a CLI for automation
  • Written in Go, easy to build and run in a container

Installing NetBird on a VPS

The simplest way to get the self-hosted stack running is the official install script on a dedicated VPS , separate from the nodes you want to join to the mesh. You’ll need your own domain (the management API and signal server are exposed over TLS) and, ideally, an OIDC IdP already configured.

# on a clean Debian/Ubuntu VPS, with a domain already pointing here
export NETBIRD_DOMAIN=netbird.example.com
curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started-with-zitadel.sh | bash

# once the stack (management + signal + Zitadel + Caddy) is up,
# add a client node on any machine with:
curl -fsSL https://pkgs.netbird.io/install.sh | sh
netbird up --management-url https://netbird.example.com

The official script brings up the whole stack via Docker Compose (management, signal, a Zitadel IdP if you don’t already have one, and a Caddy reverse proxy for automatic TLS). If you already run an IdP, you can skip the Zitadel component and point management.json at your existing OIDC issuer manually.

On the VPS firewall, you’ll need at minimum:

# HTTPS for the management API and UI
ufw allow 443/tcp
# signal server, if exposed on its own port (by default it rides on 443/gRPC-web)
ufw allow 10000/tcp
# TURN-like relay for NAT traversal fallback
ufw allow 3478/udp
ufw allow 49152:65535/udp

The exact relay port depends on the configuration you chose (external coturn vs. the bundled relay); check docker compose ps after installation to confirm which ports each container actually listens on.

Configuration patterns worth knowing

Access policies, not just connectivity

Out of the box, every node in the network can talk to every other node. The first thing worth configuring is groups (e.g. servers, laptops, contractors) and explicit policies restricting traffic between them. A temporary contractor doesn’t need to see the production database just because they’re on the same mesh.

Setup keys for automated provisioning

If you’re adding nodes via Ansible or cloud-init - exactly the scenario of a freshly provisioned VPS - use an expiring, usage-limited setup key instead of authenticating each machine manually through a browser. The key is generated from the UI or API and passed as an environment variable to netbird up --setup-key ....

Relay as a safety net, not the default path

If you notice most connections falling back to relay instead of direct peer-to-peer, check the NAT and firewall on both ends. A permanent relay means extra latency and a dependency on your relay infrastructure for every connection, precisely what you wanted to avoid by choosing a peer-to-peer mesh in the first place.

The signal server is not a trust boundary for traffic

It’s easy to wrongly assume the signal server sees application traffic. It doesn’t: it only brokers the WireGuard handshake. That simplifies the threat model, but it’s worth spelling out clearly when explaining the architecture to a team or auditors.

Where NetBird is not the right answer

If you only need 2-3 servers connected point-to-point and don’t want to maintain another stack (management + signal + IdP), plain wg-quick is simpler and has fewer moving parts that can break. NetBird earns its keep once the node count grows or you need granular access policies and fast onboarding/offboarding through SSO, not for a static handful of nodes.

Self-hosting also means you’re responsible for the availability of the management and signal servers: if both go down, already-connected nodes keep their existing WireGuard tunnels, but you can’t add new nodes or change policies until the stack is back up. It’s worth having a backup plan for the management database.

Alternatives we considered

  • Tailscale : the same peer-to-peer WireGuard model, but the control plane is SaaS (there’s also a self-hosted coordination server, Headscale, maintained by the community rather than Tailscale Inc.)
  • Headscale : an open-source, unofficial reimplementation of the Tailscale control plane; good if you want the Tailscale client with a self-hosted server
  • ZeroTier : a mesh VPN with its own protocol (not WireGuard), a layer-2 overlay, with a self-hosted controller option

So, should you run it?

If you’ve already outgrown a handful of manually managed WireGuard peers and want to keep full control over topology and identity, NetBird is a solid choice: it’s open-source, built on WireGuard (so the cryptography is well-vetted and stable), and self-hosting the entire control plane means you don’t depend on the uptime or pricing decisions of an external vendor.

The stack (management, signal, optionally coturn, and an IdP) runs comfortably on a dedicated VPS with modest resources for small-to-medium teams. If you want it in production but don’t want to own all the maintenance yourself (patching, backups for the management database, monitoring the signal server), take a look at our server administration service, or our network section for context on the kind of infrastructure such a stack would run on.

Trusted By & Member Of

We are proud members of leading internet infrastructure organizations.

RIPE NCC MANRS PeeringDB RoTLD DSIX SBIX 4IXP LOCIX Euro-IX RIPE NCC MANRS PeeringDB RoTLD DSIX SBIX 4IXP LOCIX Euro-IX