netbird server setup behind nat

netbird | pfsync | haproxy | nginx | client

tested on debian12

                   ┌──────────────────┐       CARP      ┌──────────────────┐       
                   │        │    PUBLIC VIP   │         │       
                   │   pfsync1    │      │   pfsync2  │       
                   │   10.1.0.28/16   │       CARP      │   10.1.0.29/16   │       
                   │        │   INTERNAL VIP  │         │       
                   └──────────────────┘ 10.1.255.254/16 └──────────────────┘       

                            │ │  │                  
                            │ │  │                  
                            │ │  └───────────────────┐      
            ┌───────────────────────────────┘ │              │      
            │              │ 10000/tcp (http)       │   
     80,443/tcp │              │                 │      
            ▼              │ 3478,5349/tcp         │    
┌────────────────────────┐              │ 3478,5349/udp          │    
│         │             │ 49152:49999/udp      │      
│   dnc-haproxy     │               ▼              │      
│   10.1.0.27/16   │          ┌────────────────────────┐          │     
│         ├────────────────► │          │       │     
└────────────────────────┘        │   dnc-netbird   │  ┌───────────┤    
                        │   10.1.0.20/16   │  │      │    
                        │         │  │ 51853/udp │ 51854/udp
                        └────────────────────────┘  │    │    
                                    ▼    ▼    
                                  ┌──────────────┐ ┌──────────────┐
                                  │         │ │         │
                                  │ bastion53    │ │ bastion54    │
                                  │ 10.1.0.53/16 │ │ 10.1.0.54/16 │
                                  │         │ │         │
                                  └──────────────┘ └──────────────┘

warning // lessons learnedwarning // lessons learned

public poc

that poc needs to be on the public network as NETBIRD_DOMAIN resolves while SSL is required – not sure it’s possible to PoC within with static name resolution

behind a reverse-proxy

in the compose file, api mgmt endpoints need to be fixed manually

NETBIRD_MGMT_API_ENDPOINT
NETBIRD_MGMT_GRPC_API_ENDPOINT

mgmt grpc needs to be reverse-proxied in a special way

as for signal grpc, we did not manage: haproxy was constantly reporting a 503, therefore we switched to plain text http for that haproxy backend.

network requirementsnetwork requirements

you need an auth server and it needs to resolve from within the docker instances e.g.

ping -c1 keycloak.nethence.com
nmap -p 443 keycloak.nethence.com

see netbird-pfsync if you want DNAT

and eventually a reverse-proxy e.g. haproxy or nginx

system requirementssystem requirements

unless you want docker-ce

apt install docker.io docker-compose
docker ps

apt install jq curl gettext-base

keycloak setupkeycloak setup

see keycloak and setup as such

realm       netbird

user        netbird & credentials (not temporary)

clients
  client id netbird-client -- NETBIRD_AUTH_CLIENT_ID
            + oauth2 device auth grant
            + direct access grants
  root url  https://netbird.nethence.com/
  redirect  https://netbird.nethence.com/* & http://localhost:53000
  post logout   https://netbird.nethence.com/*
  web origins   "+"

client scopes   "api" (default & OIDC)
            + include in token scope
  new mapper    type audience netbird-audience (client audience: netbird-client)

clients
        netbird-client / client scopes --> api (default)

clients
  client id netbird-backend -- NETBIRD_IDP_MGMT_CLIENT_ID
            + client auth
            + oauth2 device auth grant
            + direct access grants
            + service accounts roles
        credentials tab / check credentials client secret -- NETBIRD_IDP_MGMT_CLIENT_SECRET
        service accounts roles tab / assign view-users (realm mgmt)

installinstall

grab latest tag

ver=0.43.3

cd /opt/
wget https://github.com/netbirdio/netbird/archive/refs/tags/v$ver.tar.gz
tar xzf v$ver.tar.gz
rm -f v$ver.tar.gz

ln -s netbird-$ver netbird

setupsetup

cd netbird/infrastructure_files/
ls -lF setup.env.example

curl ifconfig.me; echo

# new file
vi setup.env
NETBIRD_DOMAIN="netbird.nethence.com"
NETBIRD_TURN_EXTERNAL_IP="@@@@@ front-facing public ip here @@@@@"

# keycloak setup
NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT="https://keycloak.nethence.com/realms/netbird/.well-known/openid-configuration"
NETBIRD_USE_AUTH0=false
NETBIRD_AUTH_CLIENT_ID="netbird-client"
NETBIRD_AUTH_SUPPORTED_SCOPES="openid profile email offline_access api"
NETBIRD_AUTH_AUDIENCE="netbird-client"
NETBIRD_AUTH_DEVICE_AUTH_CLIENT_ID="netbird-client"
NETBIRD_MGMT_IDP="keycloak"
NETBIRD_IDP_MGMT_CLIENT_ID="netbird-backend"
NETBIRD_IDP_MGMT_CLIENT_SECRET="@@@@@ netbird-backend client secret here @@@@@"
NETBIRD_IDP_MGMT_EXTRA_ADMIN_ENDPOINT="https://keycloak.nethence.com/admin/realms/netbird"

# we already got an ssl certificate
NETBIRD_DISABLE_LETSENCRYPT=true
NETBIRD_DISABLE_ANONYMOUS_METRICS=true

#NETBIRD_MGMT_API_PORT=
#NETBIRD_SIGNAL_PORT=
#TURN_MIN_PORT="49152"
#TURN_MAX_PORT="49999"

NETBIRD_MGMT_DNS_DOMAIN=netbird.nethence.com
NETBIRD_SIGNAL_PROTOCOL=http

proceed

cp -pi base.setup.env base.setup.env.dist
vi base.setup.env

# default https port is good enough
NETBIRD_MGMT_API_ENDPOINT=https://$NETBIRD_DOMAIN

cp -pi docker-compose.yml.tmpl docker-compose.yml.tmpl.dist
vi docker-compose.yml.tmpl

(make the dashboard listen 80 only)
s/:443//
(remove nginx ssl & letsencrypt volume)

  dashboard:
  signal:
  relay:
  management:
  coturn:
    extra_hosts:
      - "keycloak.nethence.com=127.0.0.1"
      - "netbird.nethence.com=127.0.0.1"

./configure.sh
cd artifacts/

check that you obtained the right kc setup (mgmt needs that to get a token endpoint)

#curl -s https://keycloak.nethence.com/realms/netbird/.well-known/openid-configuration > openid-configuration.json
jq < openid-configuration.json

vi docker-compose.yml

tuning 1/3

in our case we also had to add static name resolution (anyhow it might help, makes the path shorter)

tuning 2/3

vi management.json

    "Signal": {
    "Proto": "http",

ready to goready to go

#docker compose down
docker compose up -d
# --force-recreate

docker ps -a
netstat -lntup

https://netbird.nethence.com/ ==> login as netbird (owner)

troubleshootingtroubleshooting

docker compose logs signal
docker compose logs management
docker compose logs coturn
docker compose logs dashboard

troubleshootingtroubleshooting

Fatal glibc error: CPU does not support x86-64-v2

==> either rebuild keycloak (w/o RHEL9 as base) or change the VPS – works fine on xen/pvh

Error: failed retrieving a new idp manager with err: keycloak IdP configuration is incomplete, TokenEndpoint is missing

==> fix openid-configuration.json

resourcesresources

https://docs.netbird.io/selfhosted/selfhosted-guide

https://docs.netbird.io/selfhosted/identity-providers#keycloak

kc setup

https://docs.netbird.io/selfhosted/identity-providers#keycloak

troubles

https://github.com/netbirdio/netbird/issues/1247 ==> using advanced install and kc instead


HOME | GUIDES | LECTURES | LAB | SMTP HEALTH | HTML5 | CONTACT
Licensed under MIT