WireGuard to Netbird Migration
Migrate a multi-cluster WireGuard setup to a Netbird mesh overlay network using per-cluster maintenance VMs as subnet routers — without installing any agent on every individual host.
Why migrate to Netbird
WireGuard is a fantastic kernel-level VPN, but managing it across multiple clusters quickly becomes
painful: you write config files by hand, distribute keys out-of-band, maintain per-host
wg0.conf updates, and have no central view of who is connected to what. Netbird wraps
WireGuard in an automated mesh control plane that solves all of this.
Key advantages over raw WireGuard:
- Zero-touch mesh — peers register automatically; no manual key exchange.
- NAT traversal built in — direct peer-to-peer tunnels even behind strict NAT, with TURN relay as fallback.
- Subnet routing — one agent on a gateway VM can expose an entire cluster subnet; other hosts need no agent at all.
- Central ACL dashboard — fine-grained policy (which peer can reach which network) without SSHing into every machine.
- Self-hostable — management, signal and relay servers can all run on your own infrastructure.
- No admin privileges required on clients — the agent runs in userspace on both Linux and Windows.
The main trade-offs to be aware of:
- The management server is a new dependency — if it goes down, existing tunnels stay up but you can't change policy or onboard new peers.
- Self-hosting adds operational overhead (management + signal + TURN).
- Slightly more latency when the direct path fails and traffic is relayed via TURN.
Netbird uses WireGuard as its data-plane transport. All the performance characteristics of WireGuard (kernel bypass, ChaCha20 encryption, minimal attack surface) are preserved.
Recommended architecture
The recommended pattern for a 3-cluster environment is the subnet router gateway model. You install the Netbird agent only on the maintenance VM of each cluster. That VM advertises the cluster's internal subnet into the Netbird overlay network. All other hosts in the cluster remain untouched — they simply route traffic through the maintenance VM as they would for any other gateway.
The components involved are:
- Netbird Management Server — stores peer config, issues credentials, evaluates
ACL policy. Can be self-hosted (Docker Compose) or use
app.netbird.io. - Signal Server — facilitates the initial peer-to-peer hole-punching handshake. Bundled with the management server in self-hosted mode.
- TURN/Relay Server — relays traffic when direct P2P is not possible (e.g. symmetric NAT). Based on Coturn.
- Maintenance VM (×3) — one per cluster; runs the Netbird agent and is configured as a subnet router for that cluster's internal CIDR.
The three maintenance VMs form a full-mesh of WireGuard tunnels between each other, coordinated by the management server. Traffic from Host A in Cluster 1 destined for Host B in Cluster 2 travels: Host A → Maintenance VM 1 (WireGuard) → Maintenance VM 2 → Host B. Fully transparent, no changes on Host A or Host B.
The maintenance VM must have kernel IP forwarding enabled
(net.ipv4.ip_forward=1) for subnet routing to work. Netbird will remind you if
it is missing.
Prerequisites
Before you begin, make sure you have the following:
- 3 clusters, each with a Linux maintenance VM (Ubuntu 20.04+ or any systemd-based distro recommended).
- Outbound internet access from each maintenance VM (ports 443 TCP and 3478/49152-65535 UDP for TURN).
- A dedicated VM or server to host the Netbird management stack (if self-hosting) — 1 vCPU / 1 GB RAM is sufficient for small deployments.
- Docker and Docker Compose installed on the management server.
sudo/ root access on the maintenance VMs for the initial agent installation.- The internal subnet CIDR of each cluster noted down (e.g.
10.1.0.0/24,10.2.0.0/24,10.3.0.0/24).
If you don't need full on-premise control, you can skip sections 4 and 5 and use
app.netbird.io (free up to 5 peers). Jump straight to section 6 in that case.
Deploy the management server (self-hosted)
Netbird provides an official Docker Compose bundle that brings up the management API, the signal server, and a Caddy reverse proxy with automatic TLS. Run the following on your dedicated management VM.
# Download the setup script
curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started-with-zitadel.sh \
| bash
The script will prompt you for your domain name and will configure Caddy, Zitadel (the built-in
identity provider), and the Netbird management service. Once complete, the dashboard will be
reachable at https://<your-domain>.
# Verify all containers are running
docker compose ps
You should see the following services in running state: management,
signal, caddy, and zitadel.
For environments where maintenance VMs sit behind symmetric NAT, also deploy a Coturn server
and reference it in the management server's management.json under the
TURNConfig block. See the official Netbird docs for the exact config keys.
Create a setup key
A setup key is a one-time (or reusable) token that authorises a new peer to join your network. Create one setup key per cluster so you can track which peers belong to which cluster.
- Open the Netbird dashboard and navigate to Setup Keys.
- Click Create Setup Key.
- Give it a descriptive name (e.g.
cluster-1-gateway). - Set the key type to Reusable if you plan to re-enrol the same VM (e.g. after a rebuild).
- Copy the generated key — you will use it in the next section.
Anyone with a valid setup key can register a peer into your network. Rotate or expire keys after use if your security policy requires it.
Install the Netbird agent on each maintenance VM
Repeat these steps on each of the three maintenance VMs. The agent will auto-register with the management server using the setup key and establish WireGuard tunnels to the other peers.
# Add the Netbird repository and install the agent
curl -fsSL https://pkgs.netbird.io/install.sh | sh
Once installed, bring the agent up and point it at your management server:
# Replace the placeholders with your actual values
netbird up \
--management-url https://<your-management-domain> \
--setup-key <your-setup-key>
If you are using the hosted app.netbird.io service, omit the
--management-url flag — the agent defaults to the cloud endpoint.
# Verify the agent is connected
netbird status
You should see the peer listed as Connected and an assigned Netbird IP in the
100.64.0.0/10 range (or your custom range).
The maintenance VM will also appear in the Netbird dashboard under Peers
within a few seconds of running netbird up.
Enable subnet routing on each maintenance VM
This is the key step that lets each maintenance VM act as a gateway for its entire cluster subnet. Hosts inside the cluster do not need to run the Netbird agent — they will reach other clusters through the maintenance VM.
First, enable IP forwarding at the OS level:
# Enable IP forwarding (persistent)
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Then advertise the cluster subnet as a route via the Netbird CLI or the dashboard.
Via CLI (on each maintenance VM, substituting the correct CIDR):
# Cluster 1 — maintenance VM 1
netbird routes add \
--network 10.1.0.0/24 \
--description "Cluster 1 internal subnet"
# Cluster 2 — maintenance VM 2
netbird routes add \
--network 10.2.0.0/24 \
--description "Cluster 2 internal subnet"
# Cluster 3 — maintenance VM 3
netbird routes add \
--network 10.3.0.0/24 \
--description "Cluster 3 internal subnet"
Via dashboard: navigate to Network Routes → Add Route, set the CIDR, and select the corresponding maintenance VM as the routing peer.
For hosts inside the cluster to route inter-cluster traffic correctly, their default gateway (or a static route) must point to the maintenance VM. This is usually already the case if the maintenance VM is the cluster gateway — no change needed.
Define access control policy
By default, Netbird creates an allow all policy between peers in the same account. You can restrict this from the dashboard under Access Control → Policies.
A typical setup for 3 isolated clusters that need selective cross-cluster access:
- Create a Group per cluster (e.g.
cluster-1,cluster-2,cluster-3) and assign the respective maintenance VM to each group. - Create policies between the groups you want to allow. For example, to allow Cluster 1 and
Cluster 2 to communicate bidirectionally, create a policy with source
cluster-1and destinationcluster-2, protocol All. - Leave Cluster 3 out of that policy if it should remain isolated.
ACL policies govern which Netbird peers (i.e. maintenance VMs) can communicate. Traffic from cluster hosts travels through those VMs, so the policy effectively controls cluster-to-cluster reachability.
Migration strategy from WireGuard
You don't need to cut over all three clusters at once. A safe rolling migration looks like this:
- Stand up Netbird in parallel — install the agent on Cluster 1's maintenance VM
while WireGuard is still running. The two can coexist since Netbird uses a different network
interface (
wt0) and a different subnet. - Test Cluster 1 in isolation — verify that the Netbird overlay is reachable, the route is advertised correctly, and internal hosts can reach the management server via the maintenance VM.
- Enrol Cluster 2 and Cluster 3 — repeat the agent installation and subnet route steps on the other two maintenance VMs.
- Validate cross-cluster connectivity — ping a host in Cluster 2 from a host in Cluster 1 before touching WireGuard.
- Remove WireGuard — once validated, bring down the WireGuard interfaces cluster by cluster and remove the old config files.
# Bring down WireGuard on a host (after Netbird is validated)
sudo wg-quick down wg0
sudo systemctl disable wg-quick@wg0
Archive your /etc/wireguard/ directory before removing anything. If you need to
roll back quickly, a wg-quick up wg0 will restore connectivity instantly.
Verification
Run the following checks to confirm the migration is complete and healthy.
Check agent status on each maintenance VM:
netbird status --detail
Expected output: all three maintenance VMs listed as peers with status Connected and a
valid direct or relayed connection type.
Test cross-cluster reachability from a regular host:
# From a host in Cluster 1, ping a host in Cluster 2
ping -c 4 10.2.0.50
# Trace the path — first hop should be the maintenance VM
traceroute 10.2.0.50
Verify routes are advertised:
netbird routes list
If cross-cluster pings succeed and all three peers show Connected in
netbird status, your migration from WireGuard to Netbird is complete.
If netbird status --detail shows relayed instead of
direct between two maintenance VMs, the peers cannot hole-punch through their
respective NATs. Deploy a Coturn TURN server and configure it in the management server's
settings to fix this.