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 │
│ │ │ │
└──────────────┘ └──────────────┘
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
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.
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
unless you want docker-ce
apt install docker.io docker-compose docker ps apt install jq curl gettext-base
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)
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
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
in our case we also had to add static name resolution (anyhow it might help, makes the path shorter)
vi management.json
"Signal": {
"Proto": "http",
#docker compose down docker compose up -d # --force-recreate docker ps -a netstat -lntup https://netbird.nethence.com/ ==> login as netbird (owner)
docker compose logs signal docker compose logs management docker compose logs coturn docker compose logs dashboard
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
https://docs.netbird.io/selfhosted/selfhosted-guide
https://docs.netbird.io/selfhosted/identity-providers#keycloak
https://docs.netbird.io/selfhosted/identity-providers#keycloak
https://github.com/netbirdio/netbird/issues/1247 ==> using advanced install and kc instead