Netbird VPN Installation and Configuration

NetBird is a WireGuard-based mesh VPN platform that automatically establishes encrypted peer-to-peer connections between devices without manual WireGuard key exchange. With a self-hosted management server, SSO integration, ACL policies, and network routes, NetBird provides zero-config secure networking for distributed Linux infrastructure.

Prerequisites

  • A VPS for the management server (at least 1 GB RAM)
  • Ubuntu/Debian or CentOS/Rocky on all nodes
  • Docker and Docker Compose on the management server
  • A domain name for the management server
  • Ports 80, 443, 33073 (management), and 10000 (Signal) open

Self-Hosted Management Server Setup

# Clone the NetBird management setup
git clone https://github.com/netbirdio/netbird.git
cd netbird/infrastructure_files

# Or use the quickstart script
export NETBIRD_DOMAIN="netbird.yourdomain.com"
export NETBIRD_AUTH_AUTHORITY="none"  # Use built-in auth
export NETBIRD_AUTH_JWT_CERTS="https://netbird.yourdomain.com/.well-known/jwks.json"

# Download and configure
curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/netbird_management_linux_amd64.tar.gz | \
  tar -xz

Docker Compose Deployment

# docker-compose.yml for NetBird management server
version: '3'

services:
  # Coturn STUN/TURN server
  coturn:
    image: coturn/coturn
    network_mode: host
    volumes:
      - ./turnserver.conf:/etc/turnserver.conf
    command: ["-c", "/etc/turnserver.conf"]
    restart: unless-stopped

  # Signal server
  signal:
    image: netbirdio/signal:latest
    ports:
      - "10000:10000"
    restart: unless-stopped
    volumes:
      - netbird-signal:/var/lib/netbird

  # Management server
  management:
    image: netbirdio/management:latest
    ports:
      - "33073:33073"
      - "33071:33071"
    volumes:
      - netbird-mgmt:/var/lib/netbird
      - ./management.json:/etc/netbird/management.json
    environment:
      - NETBIRD_STORE_ENGINE=sqlite
    command: [
      "--port", "33073",
      "--log-file", "console",
      "--single-account-mode-domain", "netbird.yourdomain.com",
      "--dns-domain", "netbird.yourdomain.com"
    ]
    restart: unless-stopped

  # Dashboard
  dashboard:
    image: netbirdio/dashboard:latest
    ports:
      - "80:80"
      - "443:443"
    environment:
      - NETBIRD_MGMT_API_ENDPOINT=https://netbird.yourdomain.com:33073
      - NETBIRD_SIGNAL_URI=grpcs://netbird.yourdomain.com:10000
      - AUTH_AUTHORITY=https://netbird.yourdomain.com
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    restart: unless-stopped

volumes:
  netbird-signal:
  netbird-mgmt:
# Start the management stack
docker compose up -d

# Check all services are running
docker compose ps

# View management server logs
docker compose logs management --tail 50 -f

Installing the NetBird Client

# Ubuntu/Debian
curl -fsSL https://pkgs.netbird.io/install.sh | sudo bash

# CentOS/Rocky
curl -fsSL https://pkgs.netbird.io/install.sh | sudo bash

# Or install via APT directly
curl -sSL https://pkgs.netbird.io/debian/public.key | sudo gpg --dearmor -o /usr/share/keyrings/netbird-archive-keyring.gpg
echo 'deb [signed-by=/usr/share/keyrings/netbird-archive-keyring.gpg] https://pkgs.netbird.io/debian stable main' | \
  sudo tee /etc/apt/sources.list.d/netbird.list
sudo apt-get update
sudo apt-get install -y netbird

# Verify installation
netbird version

Peer Configuration and Login

# Connect to your self-hosted management server
sudo netbird up \
  --management-url https://netbird.yourdomain.com:33073 \
  --admin-url https://netbird.yourdomain.com

# For hosted NetBird (app.netbird.io)
sudo netbird up

# The command will output a setup key URL or SSO login URL
# Open the URL in a browser to authenticate

# Login with a setup key (for headless/automated registration)
sudo netbird up \
  --management-url https://netbird.yourdomain.com:33073 \
  --setup-key YOUR-SETUP-KEY

# Check connection status
sudo netbird status
sudo netbird status --detail

After connecting, each peer gets a NetBird IP (default range: 100.64.0.0/10):

# Check assigned IP
sudo netbird status | grep "NetBird IP"

# Test connectivity between peers
ping 100.64.0.2  # Replace with peer's NetBird IP

# Check WireGuard interface
ip addr show wt0
wg show wt0

ACL Policies

NetBird uses policies to control which peers can communicate with each other:

# List current policies via API
curl -s "https://netbird.yourdomain.com/api/policies" \
  -H "Authorization: Token your-api-token" | python3 -m json.tool

# Create a policy allowing web servers to talk to database servers
curl -X POST "https://netbird.yourdomain.com/api/policies" \
  -H "Authorization: Token your-api-token" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "WebDB Access",
    "description": "Allow web servers to reach database servers",
    "enabled": true,
    "rules": [
      {
        "name": "web-to-db",
        "enabled": true,
        "action": "accept",
        "bidirectional": false,
        "protocol": "tcp",
        "ports": ["5432", "3306"],
        "sources": [{"id": "web-servers-group-id"}],
        "destinations": [{"id": "db-servers-group-id"}]
      }
    ]
  }'

Managing Groups

# Create a peer group
curl -X POST "https://netbird.yourdomain.com/api/groups" \
  -H "Authorization: Token your-api-token" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "web-servers",
    "peers": ["peer-id-1", "peer-id-2"]
  }'

# List peers
curl -s "https://netbird.yourdomain.com/api/peers" \
  -H "Authorization: Token your-api-token"

# Add peer to a group
curl -X PUT "https://netbird.yourdomain.com/api/groups/group-id" \
  -H "Authorization: Token your-api-token" \
  -H "Content-Type: application/json" \
  -d '{"name": "web-servers", "peers": ["peer-id-1", "peer-id-2", "peer-id-3"]}'

SSO Integration

Configure SSO so team members log in with existing credentials:

# NetBird supports:
# - Google Workspace
# - Okta
# - Azure AD / Entra ID
# - Auth0
# - Keycloak (self-hosted)

# Configure in management.json
cat > management.json << 'EOF'
{
  "AuthClaims": {
    "UserIDClaim": "sub",
    "GroupsClaim": "groups"
  },
  "IdpManagerConfig": {
    "ManagerType": "auth0",
    "ClientConfig": {
      "Issuer": "https://your-tenant.auth0.com",
      "ClientID": "your-client-id",
      "ClientSecret": "your-client-secret",
      "GrantType": "client_credentials",
      "TokenEndpoint": "https://your-tenant.auth0.com/oauth/token",
      "Audience": "https://your-tenant.auth0.com/api/v2/"
    }
  }
}
EOF

Network Routes

NetBird can route traffic to non-NetBird networks through designated peers:

# Add a route to reach an on-premises network (e.g., 192.168.1.0/24)
# through a gateway peer
curl -X POST "https://netbird.yourdomain.com/api/routes" \
  -H "Authorization: Token your-api-token" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "On-premises network",
    "network_id": "onprem-01",
    "enabled": true,
    "peer": "gateway-peer-id",
    "network": "192.168.1.0/24",
    "metric": 9999,
    "masquerade": true,
    "groups": ["all-peers-group-id"]
  }'

# On the gateway peer, enable IP forwarding
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf

Managing Peers via CLI

# View detailed peer status
sudo netbird status --detail

# Bring the NetBird interface down
sudo netbird down

# Bring it back up
sudo netbird up --management-url https://netbird.yourdomain.com:33073

# View WireGuard configuration
sudo cat /etc/wireguard/wt0.conf

# Check NetBird daemon logs
sudo journalctl -u netbird -f

# Get peer list from management server
sudo netbird peers list

Troubleshooting

Peer shows "Disconnected" in dashboard:

# Check client is running
sudo systemctl status netbird

# Check management server connectivity
curl -I https://netbird.yourdomain.com:33073

# View connection errors
sudo journalctl -u netbird --since "1 hour ago" | grep -i error

Cannot ping other peers:

# Verify both peers are connected to management
sudo netbird status

# Check ACL policy allows communication
# Verify peers are in the same or allowed groups

# Check WireGuard interface
wg show wt0
ip route | grep wt0

Management server port 33073 not accessible:

# Check firewall
sudo ufw allow 33073/tcp

# Check Docker port binding
docker ps | grep management
netstat -tlnp | grep 33073

Conclusion

NetBird simplifies WireGuard mesh networking by automating key exchange and peer discovery, eliminating the manual configuration that makes traditional WireGuard deployments complex. With a self-hosted management server, SSO integration, and granular ACL policies, it provides enterprise-grade zero-trust networking for Linux infrastructure without relying on any external cloud services.