Netbird Security Testing: Management API, Peer Configuration, Pre-Shared Keys, and Network Access

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.

Table of Contents

  1. Management API and Peer Enumeration
  2. Setup Key Exploitation
  3. Peer Configuration and Key Extraction
  4. Netbird Security Hardening

Management API and Peer Enumeration

# 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

Setup Key Exploitation

# 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

Peer Configuration and Key Extraction

# 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

Netbird Security Hardening

Netbird Security Hardening Checklist:
Security TestMethodRisk
API token peer and topology enumerationGET /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 topologyHigh
Setup key extraction and unauthorized peer registrationGET /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 accessCritical
WireGuard private key extraction from netbird.confRead /etc/netbird/netbird.conf — stores WireGuard PrivateKey in plaintext; enables impersonating the peer in the overlay network and decrypting the peer's WireGuard trafficCritical
ACL policy bypass analysisGET /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 pathsHigh
Route/subnet enumerationGET /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 gatewaysMedium

Automate Netbird Security Testing

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