Netbird is a rapidly growing WireGuard-based P2P overlay network management platform that provides zero-configuration mesh networking across distributed infrastructure. Unlike traditional VPNs, Netbird creates direct encrypted tunnels between peers coordinated by a central management server — compromising the management plane gives an attacker full visibility into the network topology and the ability to add unauthorized nodes. Key assessment areas: the Netbird management API accepts JWT tokens and admin tokens can enumerate all registered peers, their WireGuard public keys, IP addresses, and access control group memberships; setup keys created for peer enrollment allow adding new machines to the overlay network without per-user authentication; the peer-local configuration at /etc/netbird/netbird.conf stores the peer's WireGuard private key; access control policies define which peers can communicate and policy bypass analysis reveals network segmentation gaps; and self-hosted Netbird management server deployments have their own web UI authentication surface. This guide covers systematic Netbird security assessment.
# Netbird management API — JWT authentication and peer enumeration
NETBIRD_URL="https://app.netbird.io" # or self-hosted management URL
# Get management API token from Netbird dashboard:
# Settings > API Access Tokens > Generate Token
TOKEN="your-netbird-api-token"
# Enumerate all peers in the account
curl -s "${NETBIRD_URL}/api/peers" \
-H "Authorization: Token ${TOKEN}" 2>/dev/null | python3 -c "
import json,sys
peers=json.load(sys.stdin)
print(f'Registered peers: {len(peers)}')
for p in peers:
print(f' {p.get(\"name\")} IP={p.get(\"ip\")} OS={p.get(\"os\")} version={p.get(\"version\")}')
print(f' Connected={p.get(\"connected\")} Last seen={p.get(\"last_seen\")}')
print(f' Groups={[g.get(\"name\") for g in p.get(\"groups\",[])]}')
print(f' WireGuard public key={p.get(\"public_key\",\"\")[:20]}...')
" 2>/dev/null
# List all networks/routes
curl -s "${NETBIRD_URL}/api/routes" \
-H "Authorization: Token ${TOKEN}" 2>/dev/null | python3 -c "
import json,sys
routes=json.load(sys.stdin)
print(f'Routes: {len(routes)}')
for r in routes:
print(f' {r.get(\"network\")} via {r.get(\"peer_groups\")} metric={r.get(\"metric\")} enabled={r.get(\"enabled\")}')
print(f' Description: {r.get(\"description\")}')
" 2>/dev/null
# Access control policies — defines which peers can communicate
curl -s "${NETBIRD_URL}/api/policies" \
-H "Authorization: Token ${TOKEN}" 2>/dev/null | python3 -c "
import json,sys
policies=json.load(sys.stdin)
print(f'ACL Policies: {len(policies)}')
for p in policies:
print(f' [{p.get(\"name\")}] enabled={p.get(\"enabled\")}')
for rule in p.get('rules',[]):
src = [g.get('name') for g in rule.get('sources',[])]
dst = [g.get('name') for g in rule.get('destinations',[])]
print(f' {src} -> {dst} action={rule.get(\"action\")} ports={rule.get(\"ports\")}')
" 2>/dev/null
# Netbird setup keys — peer enrollment without per-user authentication
NETBIRD_URL="https://app.netbird.io"
TOKEN="your-netbird-api-token"
# List all setup keys — a valid setup key allows adding any machine to the network
curl -s "${NETBIRD_URL}/api/setup-keys" \
-H "Authorization: Token ${TOKEN}" 2>/dev/null | python3 -c "
import json,sys
keys=json.load(sys.stdin)
print(f'Setup keys: {len(keys)}')
for k in keys:
print(f' [{k.get(\"name\")}] type={k.get(\"type\")} expires={k.get(\"expires_at\")}')
print(f' Uses: {k.get(\"used_times\")} / {k.get(\"usage_limit\",\"unlimited\")}')
print(f' Auto groups: {[g.get(\"name\") for g in k.get(\"auto_groups\",[])]}')
print(f' Revoked: {k.get(\"revoked\")} Ephemeral: {k.get(\"ephemeral\")}')
# Key value is only shown at creation — the API returns a masked value
# But if key was shared or stored in an env var/Docker Compose file...
key_val = k.get('key','')
if key_val:
print(f' Key: {key_val}')
" 2>/dev/null
# Using a setup key to register a new peer
# The Netbird client registers using the setup key and management URL
netbird up --management-url "${NETBIRD_URL}:443" \
--setup-key "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" 2>/dev/null
# After successful registration, the new peer receives:
# - An IP address in the Netbird overlay network (typically 100.64.0.0/10)
# - WireGuard tunnel connections to all peers allowed by ACL policies
# - Direct network access to any service on those peers without additional authentication
# Netbird peer configuration — WireGuard key and credential extraction
# Netbird stores configuration in /etc/netbird/netbird.conf (Linux)
# or ~/Library/Application Support/Netbird/netbird.conf (macOS)
cat /etc/netbird/netbird.conf 2>/dev/null | python3 -c "
import json,sys
try:
config=json.load(sys.stdin)
# WireGuard private key for this peer
wg_key = config.get('WgPrivateKey','')
if wg_key:
print(f'WireGuard private key: {wg_key}')
# Management URL (control plane)
mgmt = config.get('ManagementURL','')
print(f'Management server: {mgmt}')
# Signal server
signal = config.get('SignalURL','')
print(f'Signal server: {signal}')
# Peer SSHKey (if SSH over Netbird is enabled)
ssh = config.get('SSHKey','')
if ssh:
print(f'SSH private key: {ssh[:40]}...')
except: pass
" 2>/dev/null
# WireGuard interface state on running peer
wg show netbird0 2>/dev/null
# Shows:
# - Peer public keys for all connected peers
# - Preshared key status (if configured)
# - Allowed IPs (overlay addresses reachable via each peer)
# - Latest handshake (last connection time)
# - Transfer statistics
| Security Test | Method | Risk |
|---|---|---|
| API token peer and topology enumeration | GET /api/peers — returns all overlay network nodes with WireGuard public keys, IP addresses, group memberships, OS, version, and last seen time; maps the complete internal network topology | High |
| Setup key extraction and unauthorized peer registration | GET /api/setup-keys — lists all enrollment keys; a valid unrestricted setup key allows netbird up registration of unauthorized machines into the overlay network with full peer-group access | Critical |
| WireGuard private key extraction from netbird.conf | Read /etc/netbird/netbird.conf — stores WireGuard PrivateKey in plaintext; enables impersonating the peer in the overlay network and decrypting the peer's WireGuard traffic | Critical |
| ACL policy bypass analysis | GET /api/policies — maps all peer group communication rules; identify groups with overly permissive all-to-all access; cross-reference peer group memberships with routes to find unintended network access paths | High |
| Route/subnet enumeration | GET /api/routes — lists all network routes advertised through the overlay including CIDR ranges of internal networks; reveals internal subnet structure and which peers act as network gateways | Medium |
Ironimo tests Netbird deployments for API token peer and topology enumeration, setup key lifecycle and usage limit audit, unauthorized peer registration risk via leaked setup keys, WireGuard private key exposure in netbird.conf, access control policy review for over-permissive group rules, route enumeration and internal network mapping, and management server authentication assessment for self-hosted deployments.
Start free scan