From 4b23e1be7cf3b4095b4e3251dc292356ac533dfa Mon Sep 17 00:00:00 2001 From: Ashley Mensah Date: Wed, 21 Jan 2026 12:21:49 +0100 Subject: [PATCH 1/7] Add configuration files reference documentation for self-hosted deployments Adds comprehensive documentation for all NetBird self-hosted configuration files including docker-compose.yml, management.json, relay.env, dashboard.env, and turnserver.conf --- src/components/NavigationDocs.jsx | 1 + src/pages/selfhosted/configuration-files.mdx | 913 ++++++++++++++++++ .../selfhosted/environment-variables.mdx | 1 + src/pages/selfhosted/selfhosted-guide.mdx | 4 + .../selfhosted/selfhosted-quickstart.mdx | 4 + 5 files changed, 923 insertions(+) create mode 100644 src/pages/selfhosted/configuration-files.mdx diff --git a/src/components/NavigationDocs.jsx b/src/components/NavigationDocs.jsx index 528b2f5f..95d6ddfe 100644 --- a/src/components/NavigationDocs.jsx +++ b/src/components/NavigationDocs.jsx @@ -325,6 +325,7 @@ export const docsNavigation = [ { title: 'Reverse Proxy', href: '/selfhosted/reverse-proxy' }, { title: 'Advanced Guide', href: '/selfhosted/selfhosted-guide' }, { title: 'Environment Variables', href: '/selfhosted/environment-variables' }, + { title: 'Configuration Files', href: '/selfhosted/configuration-files' }, { title: 'Management SQLite Store', href: '/selfhosted/sqlite-store' }, { title: 'Management Postgres Store', href: '/selfhosted/postgres-store' }, { title: 'Activity Events Postgres Store', href: '/selfhosted/activity-postgres-store' }, diff --git a/src/pages/selfhosted/configuration-files.mdx b/src/pages/selfhosted/configuration-files.mdx new file mode 100644 index 00000000..51bb3931 --- /dev/null +++ b/src/pages/selfhosted/configuration-files.mdx @@ -0,0 +1,913 @@ +import {Note, Warning} from "@/components/mdx"; +import {Properties, Property} from "@/components/mdx"; + +# Configuration Files Reference + +This page provides a comprehensive reference for all configuration files used when self-hosting NetBird. Understanding these files helps you customize your deployment, troubleshoot issues, and integrate with existing infrastructure. + + +Most configuration files are **generated automatically** by the `getting-started.sh` or `configure.sh` scripts. Modifying files directly is only necessary for advanced customization. Changes to `setup.env` require re-running the configuration script to take effect. + + +## Overview + +A standard NetBird self-hosted deployment uses the following configuration files: + +| File | Purpose | Generated By | +|------|---------|--------------| +| `docker-compose.yml` | Service definitions and orchestration | `getting-started.sh` / `configure.sh` | +| `management.json` | Core management server configuration | `getting-started.sh` / `configure.sh` | +| `relay.env` | Relay server environment variables | `getting-started.sh` | +| `dashboard.env` | Dashboard UI configuration | `getting-started.sh` | +| `turnserver.conf` | Coturn STUN/TURN server configuration | `getting-started.sh` / `configure.sh` | +| `Caddyfile` | Reverse proxy configuration (when using built-in Caddy) | `getting-started.sh` | + +### File Locations + +After running the installation script, configuration files are located in the directory where you ran the script (typically `~/netbird/` or the current working directory): + +``` +./ +├── docker-compose.yml +├── management.json +├── relay.env +├── dashboard.env +├── turnserver.conf +└── Caddyfile # Only when using built-in Caddy +``` + +--- + +## docker-compose.yml + +The Docker Compose file defines all NetBird services, their dependencies, networking, and volumes. + +### Services Overview + +| Service | Image | Default Port | Description | +|---------|-------|--------------|-------------| +| `dashboard` | `netbirdio/dashboard` | 80, 443 | Web UI for managing NetBird | +| `management` | `netbirdio/management` | 33073 | Core API and peer coordination | +| `signal` | `netbirdio/signal` | 10000 | WebRTC signaling for peer connections | +| `relay` | `netbirdio/relay` | 33080 | Relay server for NAT traversal | +| `coturn` | `coturn/coturn` | 3478 | STUN/TURN server for connectivity | +| `caddy` | `caddy` | 80, 443 | Reverse proxy (optional, built-in setup) | + +### Default Settings + +The compose file includes these defaults applied to all services: + +```yaml +x-default: &default + restart: 'unless-stopped' + logging: + driver: 'json-file' + options: + max-size: '500m' + max-file: '2' +``` + +### Dashboard Service + +The dashboard provides the web interface for NetBird management. + +```yaml +dashboard: + image: netbirdio/dashboard:latest + ports: + - 80:80 + - 443:443 + environment: + - NETBIRD_MGMT_API_ENDPOINT=https://netbird.example.com + - NETBIRD_MGMT_GRPC_API_ENDPOINT=https://netbird.example.com + - AUTH_AUDIENCE=netbird-dashboard + - AUTH_CLIENT_ID=netbird-dashboard + - AUTH_AUTHORITY=https://netbird.example.com/oauth2 + - USE_AUTH0=false + - AUTH_SUPPORTED_SCOPES=openid profile email groups + - AUTH_REDIRECT_URI=/nb-auth + - AUTH_SILENT_REDIRECT_URI=/nb-silent-auth + - NGINX_SSL_PORT=443 + - LETSENCRYPT_DOMAIN=netbird.example.com + - LETSENCRYPT_EMAIL=admin@example.com + volumes: + - netbird-letsencrypt:/etc/letsencrypt/ +``` + + + + Full URL to the Management API endpoint. Used for REST API calls from the dashboard. + + + Full URL to the Management gRPC endpoint. Usually the same as the API endpoint. + + + OAuth2 audience for token validation. Default: `netbird-dashboard` + + + OAuth2 client ID for the dashboard application. + + + OAuth2 issuer URL. For embedded IdP: `https://your-domain/oauth2` + + + Set to `true` if using Auth0 as the identity provider. Default: `false` + + + Space-separated OAuth2 scopes. Default: `openid profile email groups` + + + OAuth2 redirect URI path. Default: `/nb-auth` + + + Silent authentication redirect URI. Default: `/nb-silent-auth` + + + HTTPS port for the dashboard. Default: `443` + + + Domain for Let's Encrypt certificate. Set to `none` to disable. + + + Email for Let's Encrypt registration and renewal notices. + + + +### Management Service + +The management service is the core of NetBird, handling peer registration, authentication, and network coordination. + +```yaml +management: + image: netbirdio/management:latest + depends_on: + - dashboard + volumes: + - netbird-mgmt:/var/lib/netbird + - netbird-letsencrypt:/etc/letsencrypt:ro + - ./management.json:/etc/netbird/management.json + ports: + - 33073:443 + command: [ + "--port", "443", + "--log-file", "console", + "--log-level", "info", + "--disable-anonymous-metrics=false", + "--single-account-mode-domain=netbird.example.com", + "--dns-domain=netbird.selfhosted" + ] + environment: + - NETBIRD_STORE_ENGINE_POSTGRES_DSN= + - NETBIRD_STORE_ENGINE_MYSQL_DSN= +``` + +#### Command-Line Flags + +| Flag | Default | Description | +|------|---------|-------------| +| `--port` | `443` | Internal listening port | +| `--log-file` | `console` | Log output destination | +| `--log-level` | `info` | Log verbosity: `debug`, `info`, `warn`, `error` | +| `--disable-anonymous-metrics` | `false` | Disable anonymous usage metrics | +| `--single-account-mode-domain` | - | Domain for single account mode | +| `--dns-domain` | `netbird.selfhosted` | DNS domain for peer resolution | + +### Signal Service + +The signal service handles WebRTC signaling for establishing peer-to-peer connections. + +```yaml +signal: + image: netbirdio/signal:latest + depends_on: + - dashboard + volumes: + - netbird-signal:/var/lib/netbird + - netbird-letsencrypt:/etc/letsencrypt:ro + ports: + - 10000:80 + command: [ + "--cert-file", "/etc/letsencrypt/live/netbird.example.com/fullchain.pem", + "--cert-key", "/etc/letsencrypt/live/netbird.example.com/privkey.pem", + "--log-file", "console", + "--port", "80" + ] +``` + +### Relay Service + +The relay service provides NAT traversal when direct peer-to-peer connections are not possible. + +```yaml +relay: + image: netbirdio/relay:latest + environment: + - NB_LOG_LEVEL=info + - NB_LISTEN_ADDRESS=:33080 + - NB_EXPOSED_ADDRESS=rel://netbird.example.com:33080 + - NB_AUTH_SECRET=your-secret-here + ports: + - 33080:33080 +``` + + + + Log verbosity level. Options: `debug`, `info`, `warn`, `error`. Default: `info` + + + Address and port to listen on. Format: `:port`. Default: `:33080` + + + Public address for peers to connect. Format: `rel://hostname:port` + + + Shared secret for relay authentication. Must match `management.json` Relay.Secret. + + + +### Coturn Service + +Coturn provides STUN/TURN services for NAT traversal. + +```yaml +coturn: + image: coturn/coturn:latest + volumes: + - ./turnserver.conf:/etc/turnserver.conf:ro + network_mode: host + command: + - -c /etc/turnserver.conf +``` + + +Coturn uses `network_mode: host` for optimal TURN relay performance. This means it binds directly to the host's network interfaces. + + +### Volume Configuration + +| Volume | Mount Point | Purpose | +|--------|-------------|---------| +| `netbird-mgmt` | `/var/lib/netbird` | Management database and state | +| `netbird-signal` | `/var/lib/netbird` | Signal service data | +| `netbird-letsencrypt` | `/etc/letsencrypt` | TLS certificates | + +--- + +## management.json + +The management configuration file controls the core behavior of the NetBird Management service. This is the most complex configuration file. + +### Complete Structure + +```json +{ + "Stuns": [...], + "TURNConfig": {...}, + "Relay": {...}, + "Signal": {...}, + "ReverseProxy": {...}, + "DisableDefaultPolicy": false, + "DataStoreEncryptionKey": "...", + "StoreConfig": {...}, + "HttpConfig": {...}, + "IdpManagerConfig": {...}, + "DeviceAuthorizationFlow": {...}, + "PKCEAuthorizationFlow": {...} +} +``` + +### Stuns Section + +Configures STUN servers used for NAT detection. + +```json +"Stuns": [ + { + "Proto": "udp", + "URI": "stun:netbird.example.com:3478", + "Username": "", + "Password": null + } +] +``` + + + + Protocol for STUN communication. Options: `udp`, `tcp`. Default: `udp` + + + STUN server URI. Format: `stun:hostname:port` + + + Optional username for authenticated STUN. Usually empty. + + + Optional password for authenticated STUN. Usually `null`. + + + +### TURNConfig Section + +Configures TURN servers for relay when direct connections fail. + +```json +"TURNConfig": { + "Turns": [ + { + "Proto": "udp", + "URI": "turn:netbird.example.com:3478", + "Username": "netbird", + "Password": "your-turn-password" + } + ], + "CredentialsTTL": "12h", + "Secret": "secret", + "TimeBasedCredentials": false +} +``` + + + + Array of TURN server configurations. + + + Protocol: `udp`, `tcp`, or `tls`. Default: `udp` + + + TURN server URI. Format: `turn:hostname:port` or `turns:hostname:port` for TLS. + + + TURN authentication username. + + + TURN authentication password. + + + Time-to-live for TURN credentials. Format: Go duration (e.g., `12h`, `30m`). Default: `12h` + + + Shared secret for time-based credentials (when enabled). + + + Enable time-based TURN credentials. Default: `false` + + + +### Relay Section + +Configures the NetBird relay server connection. + +```json +"Relay": { + "Addresses": ["rel://netbird.example.com:33080"], + "CredentialsTTL": "24h", + "Secret": "your-relay-secret" +} +``` + + + + Array of relay server addresses. Format: `rel://hostname:port` + + + Time-to-live for relay credentials. Default: `24h` + + + Shared authentication secret. Must match relay server's `NB_AUTH_SECRET`. + + + + +The relay secret must be identical in both `management.json` and the relay service environment. A mismatch will cause relay connections to fail. + + +### Signal Section + +Configures the connection to the Signal service. + +```json +"Signal": { + "Proto": "http", + "URI": "netbird.example.com:10000", + "Username": "", + "Password": null +} +``` + + + + Protocol for signal communication. Options: `http`, `https`. Default: `http` (internal), `https` (external). + + + Signal server address. Format: `hostname:port` + + + Optional authentication username. Usually empty. + + + Optional authentication password. Usually `null`. + + + +### ReverseProxy Section + +Configures trusted reverse proxies for proper client IP detection. + +```json +"ReverseProxy": { + "TrustedHTTPProxies": [], + "TrustedHTTPProxiesCount": 0, + "TrustedPeers": ["0.0.0.0/0"] +} +``` + + + + List of trusted proxy IP addresses or CIDR ranges. + + + Number of trusted proxy hops. Used with X-Forwarded-For header parsing. + + + CIDR ranges of trusted peers. Default: `["0.0.0.0/0"]` (trust all). + + + + +When running behind a reverse proxy, configure `TrustedHTTPProxies` with your proxy's IP to ensure accurate client IP logging and rate limiting. + + +### StoreConfig Section + +Configures the database backend. + +```json +"StoreConfig": { + "Engine": "sqlite" +} +``` + + + + Database engine. Options: `sqlite`, `postgres`, `mysql`. Default: `sqlite` + + + +For PostgreSQL or MySQL, set the connection string via environment variables: +- `NETBIRD_STORE_ENGINE_POSTGRES_DSN` for PostgreSQL +- `NETBIRD_STORE_ENGINE_MYSQL_DSN` for MySQL + +See [Management Postgres Store](/selfhosted/postgres-store) for PostgreSQL setup. + +### HttpConfig Section + +Configures the HTTP API server and authentication. + +```json +"HttpConfig": { + "Address": "0.0.0.0:33073", + "AuthIssuer": "https://netbird.example.com/oauth2", + "AuthAudience": "netbird-dashboard", + "AuthKeysLocation": "https://netbird.example.com/oauth2/keys", + "AuthUserIDClaim": "", + "CertFile": "/etc/letsencrypt/live/netbird.example.com/fullchain.pem", + "CertKey": "/etc/letsencrypt/live/netbird.example.com/privkey.pem", + "IdpSignKeyRefreshEnabled": false, + "OIDCConfigEndpoint": "https://netbird.example.com/oauth2/.well-known/openid-configuration" +} +``` + + + + Listen address for HTTP API. Format: `host:port`. Default: `0.0.0.0:33073` + + + OAuth2 token issuer URL for validation. + + + Expected audience claim in JWT tokens. + + + URL to fetch JWT signing keys (JWKS endpoint). + + + JWT claim to use as user ID. Empty uses `sub` claim. + + + Path to TLS certificate file. + + + Path to TLS certificate key file. + + + Enable automatic JWKS key refresh. Default: `false` + + + OIDC discovery endpoint URL. + + + +### IdpManagerConfig Section + +Configures the Identity Provider manager for user information retrieval. + +```json +"IdpManagerConfig": { + "ManagerType": "none", + "ClientConfig": { + "Issuer": "https://netbird.example.com/oauth2", + "TokenEndpoint": "https://netbird.example.com/oauth2/token", + "ClientID": "netbird-mgmt", + "ClientSecret": "your-client-secret", + "GrantType": "client_credentials" + }, + "ExtraConfig": {} +} +``` + + + + IdP type. Options: `none`, `auth0`, `azure`, `keycloak`, `zitadel`, `google`, `okta`, `jumpcloud` + + + OAuth2 issuer URL. + + + OAuth2 token endpoint URL. + + + Client ID for machine-to-machine authentication. + + + Client secret for machine-to-machine authentication. + + + OAuth2 grant type. Usually `client_credentials`. + + + Provider-specific additional configuration. + + + +### DeviceAuthorizationFlow Section + +Configures device authorization flow for CLI authentication. + +```json +"DeviceAuthorizationFlow": { + "Provider": "none", + "ProviderConfig": { + "Audience": "netbird-dashboard", + "ClientID": "netbird-client", + "TokenEndpoint": "https://netbird.example.com/oauth2/token", + "DeviceAuthEndpoint": "https://netbird.example.com/oauth2/device/authorize", + "Scope": "openid", + "UseIDToken": false + } +} +``` + + + + Device auth provider. Options: `none`, `hosted`, `auth0`, `azure`, `keycloak`, `zitadel`, `okta` + + + OAuth2 audience for device tokens. + + + Client ID for device authorization. + + + Token exchange endpoint. + + + Device authorization initiation endpoint. + + + OAuth2 scopes to request. + + + Use ID token instead of access token. Default: `false` + + + +### PKCEAuthorizationFlow Section + +Configures PKCE authorization flow for browser-based authentication. + +```json +"PKCEAuthorizationFlow": { + "ProviderConfig": { + "Audience": "netbird-dashboard", + "ClientID": "netbird-dashboard", + "ClientSecret": "", + "AuthorizationEndpoint": "https://netbird.example.com/oauth2/authorize", + "TokenEndpoint": "https://netbird.example.com/oauth2/token", + "Scope": "openid profile email groups", + "RedirectURLs": ["http://localhost:53000"], + "UseIDToken": false, + "DisablePromptLogin": false, + "LoginFlag": 0 + } +} +``` + + + + OAuth2 audience for PKCE tokens. + + + Public client ID for PKCE flow. + + + Optional client secret. Usually empty for public clients. + + + Authorization endpoint URL. + + + Token endpoint URL. + + + OAuth2 scopes to request. + + + Allowed redirect URLs for PKCE flow. + + + Use ID token instead of access token. Default: `false` + + + Skip login prompt for returning users. Default: `false` + + + Login behavior flag. `0` = default, `1` = force login. + + + +### Other Top-Level Settings + + + + Disable the default "allow all" access policy for new accounts. Default: `false` + + + Data directory path. Usually set via command line. + + + 32-byte encryption key for sensitive data at rest. Auto-generated by setup scripts. + + + + +Keep `DataStoreEncryptionKey` secure and backed up. Losing this key means losing access to encrypted data in the database. + + +--- + +## relay.env + +Environment configuration for the relay service. This file is mounted into the relay container. + +```bash +# Log level: debug, info, warn, error +NB_LOG_LEVEL=info + +# Address to listen on +NB_LISTEN_ADDRESS=:33080 + +# Public address for peers to connect +NB_EXPOSED_ADDRESS=rel://netbird.example.com:33080 + +# Authentication secret (must match management.json Relay.Secret) +NB_AUTH_SECRET=your-secret-here +``` + +### All Relay Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `NB_LOG_LEVEL` | `info` | Log verbosity | +| `NB_LISTEN_ADDRESS` | `:33080` | Listen address | +| `NB_EXPOSED_ADDRESS` | - | Public relay address for peers | +| `NB_AUTH_SECRET` | - | Shared authentication secret | +| `NB_METRICS_PORT` | - | Prometheus metrics port (optional) | +| `NB_TLS_CERT_FILE` | - | TLS certificate file path | +| `NB_TLS_KEY_FILE` | - | TLS key file path | +| `NB_LETSENCRYPT_DATA_DIR` | - | Let's Encrypt data directory | +| `NB_LETSENCRYPT_DOMAINS` | - | Domains for Let's Encrypt | +| `NB_LETSENCRYPT_EMAIL` | - | Let's Encrypt email | +| `NB_HEALTH_LISTEN_ADDRESS` | - | Health check endpoint address | + +--- + +## dashboard.env + +Environment configuration for the dashboard service. + +```bash +# Endpoints +NETBIRD_MGMT_API_ENDPOINT=https://netbird.example.com +NETBIRD_MGMT_GRPC_API_ENDPOINT=https://netbird.example.com + +# OIDC - using embedded IdP +AUTH_AUDIENCE=netbird-dashboard +AUTH_CLIENT_ID=netbird-dashboard +AUTH_CLIENT_SECRET= +AUTH_AUTHORITY=https://netbird.example.com/oauth2 +USE_AUTH0=false +AUTH_SUPPORTED_SCOPES=openid profile email groups +AUTH_REDIRECT_URI=/nb-auth +AUTH_SILENT_REDIRECT_URI=/nb-silent-auth + +# SSL +NGINX_SSL_PORT=443 + +# Letsencrypt +LETSENCRYPT_DOMAIN=netbird.example.com +LETSENCRYPT_EMAIL=admin@example.com +``` + +### Endpoint Configuration + +| Variable | Description | +|----------|-------------| +| `NETBIRD_MGMT_API_ENDPOINT` | Management REST API endpoint URL | +| `NETBIRD_MGMT_GRPC_API_ENDPOINT` | Management gRPC endpoint URL | + +### Authentication Configuration + +| Variable | Description | +|----------|-------------| +| `AUTH_AUDIENCE` | OAuth2 audience claim | +| `AUTH_CLIENT_ID` | OAuth2 client ID | +| `AUTH_CLIENT_SECRET` | OAuth2 client secret (empty for public clients) | +| `AUTH_AUTHORITY` | OAuth2 issuer URL | +| `USE_AUTH0` | Set to `true` when using Auth0 | +| `AUTH_SUPPORTED_SCOPES` | Space-separated OAuth2 scopes | +| `AUTH_REDIRECT_URI` | OAuth2 redirect path | +| `AUTH_SILENT_REDIRECT_URI` | Silent auth redirect path | + +### SSL/TLS Configuration + +| Variable | Default | Description | +|----------|---------|-------------| +| `NGINX_SSL_PORT` | `443` | HTTPS port | +| `LETSENCRYPT_DOMAIN` | - | Domain for Let's Encrypt (set to `none` to disable) | +| `LETSENCRYPT_EMAIL` | - | Email for Let's Encrypt | + +--- + +## turnserver.conf + +Coturn TURN server configuration. + +```ini +# Listening ports +listening-port=3478 +tls-listening-port=5349 + +# TURN relay port range +min-port=49152 +max-port=65535 + +# Authentication +lt-cred-mech +user=netbird:your-turn-password + +# Domain/Realm +realm=wiretrustee.com + +# Logging +log-file=stdout + +# Fingerprinting +fingerprint + +# Disable TCP relay (optional, saves resources) +# no-tcp-relay +``` + +### Key Settings + +| Setting | Default | Description | +|---------|---------|-------------| +| `listening-port` | `3478` | UDP/TCP STUN/TURN port | +| `tls-listening-port` | `5349` | TLS TURN port | +| `min-port` | `49152` | Minimum relay port | +| `max-port` | `65535` | Maximum relay port | +| `lt-cred-mech` | - | Enable long-term credential mechanism | +| `user` | - | TURN credentials in format `username:password` | +| `realm` | `wiretrustee.com` | TURN realm | +| `external-ip` | - | External IP for NAT (if behind NAT) | +| `fingerprint` | - | Enable STUN fingerprinting | + + +If your server is behind NAT, you must configure `external-ip` with your public IP address for TURN to work correctly. + + +--- + +## Common Configuration Scenarios + +### Using an External Database + +To use PostgreSQL instead of SQLite: + +1. Update `management.json`: +```json +"StoreConfig": { + "Engine": "postgres" +} +``` + +2. Set the connection string in `docker-compose.yml`: +```yaml +management: + environment: + - NETBIRD_STORE_ENGINE_POSTGRES_DSN=postgres://user:password@host:5432/netbird?sslmode=disable +``` + +See [Management Postgres Store](/selfhosted/postgres-store) for detailed setup. + +### Disabling Anonymous Metrics + +In `docker-compose.yml`, update the management command: + +```yaml +management: + command: [ + "--port", "443", + "--disable-anonymous-metrics=true", + # ... other flags + ] +``` + +### Custom Relay Configuration + +To use multiple relay servers, update `management.json`: + +```json +"Relay": { + "Addresses": [ + "rel://relay1.example.com:33080", + "rel://relay2.example.com:33080" + ], + "CredentialsTTL": "24h", + "Secret": "shared-secret" +} +``` + +Each relay server must use the same `NB_AUTH_SECRET`. + +### Behind a Reverse Proxy + +When running behind your own reverse proxy (Traefik, Nginx, etc.): + +1. Set `LETSENCRYPT_DOMAIN=none` in `dashboard.env` +2. Configure trusted proxies in `management.json`: +```json +"ReverseProxy": { + "TrustedHTTPProxies": ["10.0.0.1"], + "TrustedHTTPProxiesCount": 1, + "TrustedPeers": ["10.0.0.0/8"] +} +``` + +See [Reverse Proxy Configuration](/selfhosted/reverse-proxy) for detailed templates. + +### Configuring External TURN Servers + +To use external TURN servers (e.g., for geographically distributed deployments): + +```json +"TURNConfig": { + "Turns": [ + { + "Proto": "udp", + "URI": "turn:turn-us.example.com:3478", + "Username": "netbird", + "Password": "password1" + }, + { + "Proto": "udp", + "URI": "turn:turn-eu.example.com:3478", + "Username": "netbird", + "Password": "password2" + } + ], + "CredentialsTTL": "12h", + "TimeBasedCredentials": false +} +``` + +--- + +## See Also + +- [Self-hosting Quickstart Guide](/selfhosted/selfhosted-quickstart) - Get started quickly with default settings +- [Advanced Self-hosting Guide](/selfhosted/selfhosted-guide) - Custom IdP integration +- [Environment Variables](/selfhosted/environment-variables) - Runtime environment configuration +- [Reverse Proxy Configuration](/selfhosted/reverse-proxy) - Traefik, Nginx, Caddy setup +- [Management SQLite Store](/selfhosted/sqlite-store) - SQLite database details +- [Management Postgres Store](/selfhosted/postgres-store) - PostgreSQL setup diff --git a/src/pages/selfhosted/environment-variables.mdx b/src/pages/selfhosted/environment-variables.mdx index 8dedcc12..6528227c 100644 --- a/src/pages/selfhosted/environment-variables.mdx +++ b/src/pages/selfhosted/environment-variables.mdx @@ -268,5 +268,6 @@ Configuration values are applied in the following order (later values override e - [Self-hosting Quickstart Guide](/selfhosted/selfhosted-quickstart) - [Advanced Self-hosting Guide](/selfhosted/selfhosted-guide) +- [Configuration Files Reference](/selfhosted/configuration-files) - Detailed documentation for docker-compose.yml, management.json, and other config files - [Management SQLite Store](/selfhosted/sqlite-store) - [Management Postgres Store](/selfhosted/postgres-store) diff --git a/src/pages/selfhosted/selfhosted-guide.mdx b/src/pages/selfhosted/selfhosted-guide.mdx index eab48e41..05ab4664 100644 --- a/src/pages/selfhosted/selfhosted-guide.mdx +++ b/src/pages/selfhosted/selfhosted-guide.mdx @@ -178,6 +178,10 @@ This will export all the properties as environment variables and generate ```art The changes made to `setup.env` will not take any effect until you run `configure.sh` again + +For detailed documentation of all configuration file options, see the [Configuration Files Reference](/selfhosted/configuration-files). + + ### Step 6: Run docker compose: ```bash diff --git a/src/pages/selfhosted/selfhosted-quickstart.mdx b/src/pages/selfhosted/selfhosted-quickstart.mdx index 38a47bc4..accfc2ef 100644 --- a/src/pages/selfhosted/selfhosted-quickstart.mdx +++ b/src/pages/selfhosted/selfhosted-quickstart.mdx @@ -141,6 +141,10 @@ The configuration files are located in the folder where you ran the installation mkdir backup cp docker-compose.yml Caddyfile dashboard.env turnserver.conf management.json relay.env backup/ ``` + + +For detailed information about each configuration file and its options, see the [Configuration Files Reference](/selfhosted/configuration-files). + To save the Management service databases, stop the Management service and copy the files from the store directory: ```bash docker compose stop management From 6b8da418b8e9ffba3d0e18cb721828f4be9d4bd0 Mon Sep 17 00:00:00 2001 From: Ashley Mensah Date: Wed, 21 Jan 2026 12:54:09 +0100 Subject: [PATCH 2/7] Added clarifications for options not required for embedded IdP setup, more context for certain files and values --- src/pages/selfhosted/configuration-files.mdx | 373 +++++++++++++----- .../selfhosted/environment-variables.mdx | 27 +- .../selfhosted/selfhosted-quickstart.mdx | 11 +- 3 files changed, 297 insertions(+), 114 deletions(-) diff --git a/src/pages/selfhosted/configuration-files.mdx b/src/pages/selfhosted/configuration-files.mdx index 51bb3931..9a37d5d7 100644 --- a/src/pages/selfhosted/configuration-files.mdx +++ b/src/pages/selfhosted/configuration-files.mdx @@ -17,9 +17,8 @@ A standard NetBird self-hosted deployment uses the following configuration files |------|---------|--------------| | `docker-compose.yml` | Service definitions and orchestration | `getting-started.sh` / `configure.sh` | | `management.json` | Core management server configuration | `getting-started.sh` / `configure.sh` | -| `relay.env` | Relay server environment variables | `getting-started.sh` | +| `relay.env` | Relay server environment variables (includes STUN configuration) | `getting-started.sh` | | `dashboard.env` | Dashboard UI configuration | `getting-started.sh` | -| `turnserver.conf` | Coturn STUN/TURN server configuration | `getting-started.sh` / `configure.sh` | | `Caddyfile` | Reverse proxy configuration (when using built-in Caddy) | `getting-started.sh` | ### File Locations @@ -32,7 +31,6 @@ After running the installation script, configuration files are located in the di ├── management.json ├── relay.env ├── dashboard.env -├── turnserver.conf └── Caddyfile # Only when using built-in Caddy ``` @@ -47,12 +45,15 @@ The Docker Compose file defines all NetBird services, their dependencies, networ | Service | Image | Default Port | Description | |---------|-------|--------------|-------------| | `dashboard` | `netbirdio/dashboard` | 80, 443 | Web UI for managing NetBird | -| `management` | `netbirdio/management` | 33073 | Core API and peer coordination | -| `signal` | `netbirdio/signal` | 10000 | WebRTC signaling for peer connections | -| `relay` | `netbirdio/relay` | 33080 | Relay server for NAT traversal | -| `coturn` | `coturn/coturn` | 3478 | STUN/TURN server for connectivity | +| `management` | `netbirdio/management` | 80 | Core API, peer coordination, and embedded IdP | +| `signal` | `netbirdio/signal` | 80, 10000 | WebRTC signaling for peer connections | +| `relay` | `netbirdio/relay` | 80, 3478/udp | Relay server for NAT traversal with embedded STUN | | `caddy` | `caddy` | 80, 443 | Reverse proxy (optional, built-in setup) | + +The relay service includes an embedded STUN server, eliminating the need for a separate coturn container. STUN functionality is enabled via the `NB_ENABLE_STUN` environment variable in `relay.env`. + + ### Default Settings The compose file includes these defaults applied to all services: @@ -196,53 +197,53 @@ signal: ### Relay Service -The relay service provides NAT traversal when direct peer-to-peer connections are not possible. +The relay service provides NAT traversal when direct peer-to-peer connections are not possible. It also includes an embedded STUN server for NAT detection and traversal. ```yaml relay: image: netbirdio/relay:latest - environment: - - NB_LOG_LEVEL=info - - NB_LISTEN_ADDRESS=:33080 - - NB_EXPOSED_ADDRESS=rel://netbird.example.com:33080 - - NB_AUTH_SECRET=your-secret-here + env_file: + - ./relay.env ports: - - 33080:33080 + - '80:80' # Relay WebSocket + - '3478:3478/udp' # Embedded STUN server ``` +The relay service is configured via the `relay.env` file. See the [relay.env section](#relayenv) for detailed configuration options. + Log verbosity level. Options: `debug`, `info`, `warn`, `error`. Default: `info` - Address and port to listen on. Format: `:port`. Default: `:33080` + Address and port to listen on. Format: `:port`. Default: `:80` - Public address for peers to connect. Format: `rel://hostname:port` + Public address for peers to connect. Format: `rel://hostname:port` or `rels://hostname:port` for TLS. Shared secret for relay authentication. Must match `management.json` Relay.Secret. + + Enable the embedded STUN server. Default: `false` + + + Comma-separated list of UDP ports for the STUN server. Default: `3478` + -### Coturn Service - -Coturn provides STUN/TURN services for NAT traversal. - -```yaml -coturn: - image: coturn/coturn:latest - volumes: - - ./turnserver.conf:/etc/turnserver.conf:ro - network_mode: host - command: - - -c /etc/turnserver.conf -``` +### STUN Server (Embedded in Relay) -Coturn uses `network_mode: host` for optimal TURN relay performance. This means it binds directly to the host's network interfaces. +Starting with the current quickstart installation, STUN functionality is **embedded directly in the relay service**. The separate coturn container is no longer used in the default deployment. This simplifies the architecture and reduces the number of containers to manage. +The embedded STUN server is enabled by setting `NB_ENABLE_STUN=true` in `relay.env`. The STUN server listens on UDP port 3478 by default. + +#### Legacy Coturn Configuration + +If you have an existing installation using coturn, or need advanced TURN functionality (such as time-based credentials or TCP relay), you can still use a separate coturn container. See the [advanced self-hosting guide](/selfhosted/selfhosted-guide) for coturn configuration details. + ### Volume Configuration | Volume | Mount Point | Purpose | @@ -257,8 +258,99 @@ Coturn uses `network_mode: host` for optimal TURN relay performance. This means The management configuration file controls the core behavior of the NetBird Management service. This is the most complex configuration file. +### Embedded IdP vs External IdP Configuration + +The structure of `management.json` varies significantly depending on whether you use the **embedded IdP** (quickstart deployment) or configure identity providers at the **infrastructure level** (advanced deployment). + + +**Most users following the [Quickstart Guide](/selfhosted/selfhosted-quickstart) will have a much simpler `management.json`**. The embedded IdP handles authentication automatically, and many of the sections documented below are not needed. + + +#### Understanding "Embedded IdP" + +The term "embedded IdP" refers to NetBird's built-in identity provider system based on DEX. This is **not** a limitation - it is actually the modern, recommended approach that offers several advantages: + +**You CAN connect external identity providers with the embedded IdP:** +- **Google Workspace** - Use Google accounts for authentication +- **Microsoft Entra ID (Azure AD)** - Integrate with Microsoft 365 organizations +- **Okta** - Connect your Okta workforce identity +- **Self-hosted Authentik** - Use your own Authentik instance for authentication +- **Any OIDC provider** - Any provider supporting OpenID Connect works with NetBird + +**How to add external IdPs with the embedded system:** +1. Go to **Settings → Identity Providers** in the NetBird Dashboard +2. Click **Add Identity Provider** +3. Follow the guided setup for your chosen provider (Google, Okta, self-hosted Authentik, or any other OIDC provider) +4. Users can then authenticate using their existing corporate credentials + +This Dashboard-based configuration is simpler, more maintainable, and does not require editing `management.json`. + +#### When to use infrastructure-level IdP configuration + +The `HttpConfig`, `IdpManagerConfig`, `DeviceAuthorizationFlow`, and `PKCEAuthorizationFlow` sections documented below are for the **legacy advanced deployment method** where: +- You configure the IdP connection directly in `management.json` +- The embedded IdP is disabled +- You manage OAuth2/OIDC settings at the infrastructure level rather than through the UI + +This approach is typically only needed for: +- Organizations with specific compliance requirements mandating infrastructure-as-code IdP configuration +- Complex multi-tenant scenarios +- Migrations from older NetBird deployments that predate the Dashboard IdP management feature + +**Quickstart deployment (embedded IdP - recommended):** +- Uses the `EmbeddedIdP` section to enable the built-in identity provider +- External IdPs (Google, Okta, self-hosted Authentik, or any other OIDC provider) are added via **Settings → Identity Providers** in the Dashboard +- Sections like `HttpConfig`, `IdpManagerConfig`, `DeviceAuthorizationFlow`, and `PKCEAuthorizationFlow` are **not required** and typically omitted +- Authentication endpoints are automatically configured at `https://your-domain/oauth2/` +- User management is done through the Dashboard UI + +**Advanced deployment (infrastructure-level IdP):** +- Does **not** use the `EmbeddedIdP` section +- Requires full configuration of `HttpConfig`, `IdpManagerConfig`, `DeviceAuthorizationFlow`, and `PKCEAuthorizationFlow` +- You must configure your external IdP (Okta, Keycloak, Auth0, etc.) and populate these sections with the appropriate values +- See the [Advanced Self-hosting Guide](/selfhosted/selfhosted-guide) for setup instructions + +### Configuration Section Summary + +| Section | Quickstart (Embedded IdP) | Advanced (Infrastructure-level IdP) | +|---------|---------------------------|-------------------------------------| +| `Stuns` | Required | Required | +| `TURNConfig` | Optional | Optional | +| `Relay` | Required | Required | +| `Signal` | Required | Required | +| `ReverseProxy` | Optional | Optional | +| `StoreConfig` | Optional | Optional | +| `EmbeddedIdP` | **Required** | Not used | +| `HttpConfig` | Not used (auto-configured) | **Required** | +| `IdpManagerConfig` | Not used | **Required** | +| `DeviceAuthorizationFlow` | Not used (auto-configured) | **Required** | +| `PKCEAuthorizationFlow` | Not used (auto-configured) | **Required** | + + +**Remember:** The "Quickstart (Embedded IdP)" column applies even if you want to use external providers like Google, Okta, self-hosted Authentik, or any other OIDC provider. You can add these through **Settings → Identity Providers** in the Dashboard without changing your `management.json` configuration. + + ### Complete Structure +The structure differs based on your deployment type: + +**Quickstart deployment (embedded IdP):** +```json +{ + "Stuns": [...], + "Relay": {...}, + "Signal": {...}, + "Datadir": "/var/lib/netbird", + "DataStoreEncryptionKey": "...", + "EmbeddedIdP": { + "Enabled": true, + "Issuer": "https://your-domain/oauth2", + "DashboardRedirectURIs": [...] + } +} +``` + +**Advanced deployment (external IdP):** ```json { "Stuns": [...], @@ -278,7 +370,17 @@ The management configuration file controls the core behavior of the NetBird Mana ### Stuns Section -Configures STUN servers used for NAT detection. +Configures STUN servers used for NAT detection and traversal. + +**What does STUN do?** + +STUN (Session Traversal Utilities for NAT) helps NetBird peers discover their public IP address and the type of NAT they are behind. This information is essential for establishing direct peer-to-peer connections: + +- **NAT type detection** - Determines if peers can connect directly or need relay assistance +- **Public address discovery** - Peers learn their external IP and port, which they share via the signal server +- **Connection optimization** - Enables direct connections when possible, reducing latency and relay load + +The embedded STUN server in the relay service (enabled via `NB_ENABLE_STUN=true` in `relay.env`) is typically sufficient for most deployments. ```json "Stuns": [ @@ -355,7 +457,15 @@ Configures TURN servers for relay when direct connections fail. ### Relay Section -Configures the NetBird relay server connection. +Configures the NetBird relay server connection for NAT traversal. + +**What does the relay service do?** + +When two NetBird peers cannot establish a direct WireGuard connection (due to restrictive NATs, firewalls, or network topology), traffic is routed through the relay server. The relay acts as an encrypted intermediary, ensuring connectivity even in challenging network environments. + +- **Automatic fallback** - Peers attempt direct connections first; relay is used only when needed +- **End-to-end encryption** - Traffic remains WireGuard-encrypted; the relay cannot read packet contents +- **Credential-based authentication** - The shared secret ensures only authorized peers can use your relay ```json "Relay": { @@ -383,7 +493,15 @@ The relay secret must be identical in both `management.json` and the relay servi ### Signal Section -Configures the connection to the Signal service. +Configures the connection to the Signal service for peer-to-peer connection establishment. + +**What does the signal service do?** + +The signal service facilitates WebRTC signaling between NetBird peers. When two peers want to establish a direct connection, they exchange connection offers, answers, and ICE candidates through the signal server. This coordination enables peers to discover each other and negotiate the optimal connection path. + +- **Connection coordination** - Peers exchange network information to establish direct WireGuard tunnels +- **No traffic routing** - Unlike the relay, the signal server only handles connection setup metadata, not actual traffic +- **Persistent connections** - Peers maintain a connection to the signal server to receive incoming connection requests ```json "Signal": { @@ -439,7 +557,29 @@ When running behind a reverse proxy, configure `TrustedHTTPProxies` with your pr ### StoreConfig Section -Configures the database backend. +Configures the database backend for storing all NetBird management data. + +**What data is stored in the database?** + +The management database contains all persistent state for your NetBird deployment: + +- **Accounts and users** - User accounts, roles, and permissions +- **Peers** - Registered devices, their WireGuard keys, IP assignments, and metadata +- **Groups** - Peer groupings used for access control and network organization +- **Access policies** - Network access rules defining which peers can communicate +- **Routes** - Network routes for accessing external subnets through NetBird peers +- **DNS configuration** - Custom DNS settings and nameserver groups +- **Setup keys** - Keys used for automated peer enrollment +- **Activity logs** - Audit trail of user and system actions +- **Posture checks** - Device security compliance policies + +**Where is the data stored?** + +| Engine | Storage Location | Notes | +|--------|------------------|-------| +| SQLite (default) | `/var/lib/netbird/` volume | File-based, stored in the `netbird-mgmt` Docker volume. Simple but limited to single-instance deployments. | +| PostgreSQL | External database server | Recommended for production. Supports high availability and backups. | +| MySQL | External database server | Alternative to PostgreSQL for organizations standardized on MySQL. | ```json "StoreConfig": { @@ -457,11 +597,61 @@ For PostgreSQL or MySQL, set the connection string via environment variables: - `NETBIRD_STORE_ENGINE_POSTGRES_DSN` for PostgreSQL - `NETBIRD_STORE_ENGINE_MYSQL_DSN` for MySQL + +For production deployments with multiple users or high availability requirements, consider using PostgreSQL. SQLite is convenient for testing and small deployments but does not support concurrent writes or easy backups while the service is running. + + See [Management Postgres Store](/selfhosted/postgres-store) for PostgreSQL setup. +### EmbeddedIdP Section + + +This section is used by the **quickstart deployment** with the embedded identity provider. If you see this section in your `management.json`, you are using the embedded IdP and do **not** need to configure `HttpConfig`, `IdpManagerConfig`, `DeviceAuthorizationFlow`, or `PKCEAuthorizationFlow` manually. + +**Want to use Google, Okta, self-hosted Authentik, or any other OIDC provider?** You do not need to disable the embedded IdP or edit this file. Instead, add your external IdP through **Settings → Identity Providers** in the Dashboard. The embedded IdP system supports connecting external providers through the UI. + + +Configures the built-in identity provider that handles user authentication and management. The embedded IdP is based on DEX and supports both local user management and connections to external identity providers configured through the Dashboard. + +```json +"EmbeddedIdP": { + "Enabled": true, + "Issuer": "https://netbird.example.com/oauth2", + "DashboardRedirectURIs": [ + "https://netbird.example.com/nb-auth", + "https://netbird.example.com/nb-silent-auth" + ] +} +``` + + + + Enable the embedded identity provider. When `true`, the management server hosts OAuth2/OIDC endpoints at `/oauth2/`. Default: `true` for quickstart deployments. + + + The issuer URL for tokens. Should be `https://your-domain/oauth2`. This URL is used to validate JWT tokens and must be accessible to clients. + + + Allowed redirect URIs for OAuth2 authorization flow. Must include the dashboard authentication callbacks, typically `/nb-auth` and `/nb-silent-auth` on your domain. + + + +When `EmbeddedIdP.Enabled` is `true`, the management server automatically: +- Hosts OIDC discovery at `https://your-domain/oauth2/.well-known/openid-configuration` +- Provides JWKS (signing keys) at `https://your-domain/oauth2/keys` +- Handles token issuance at `https://your-domain/oauth2/token` +- Manages device authorization at `https://your-domain/oauth2/device/authorize` +- Provides user management through the Dashboard UI + ### HttpConfig Section -Configures the HTTP API server and authentication. + +**Quickstart users:** If your `management.json` contains an `EmbeddedIdP` section with `Enabled: true`, you do **not** need this section. The embedded IdP automatically configures HTTP authentication. + +**Want to connect Google, Okta, self-hosted Authentik, or any other OIDC provider?** You do not need this section. The embedded IdP supports adding external identity providers through **Settings → Identity Providers** in the Dashboard. This section is only required for the [legacy advanced deployment method](/selfhosted/selfhosted-guide) where IdP configuration is done at the infrastructure level rather than through the Dashboard UI. + + +Configures the HTTP API server and authentication. This section defines how the management server validates JWT tokens from your identity provider. ```json "HttpConfig": { @@ -509,7 +699,15 @@ Configures the HTTP API server and authentication. ### IdpManagerConfig Section -Configures the Identity Provider manager for user information retrieval. + +**Quickstart users:** This section is **not required** when using the embedded IdP. The embedded IdP manages user information internally and synchronizes with external identity providers added through the Dashboard. + +**Want to connect Google, Okta, self-hosted Authentik, or any other OIDC provider?** You do not need this section. Add your external IdP through **Settings → Identity Providers** in the Dashboard - user details (names, emails, group memberships) will be synchronized automatically. + +This section is only needed for the [legacy advanced deployment method](/selfhosted/selfhosted-guide) where the embedded IdP is disabled and NetBird needs to query an external IdP's management API directly for user details. + + +Configures the Identity Provider manager for user information retrieval. When configured, NetBird uses the IdP's management API to fetch user details like display names, emails, and group memberships. ```json "IdpManagerConfig": { @@ -551,7 +749,15 @@ Configures the Identity Provider manager for user information retrieval. ### DeviceAuthorizationFlow Section -Configures device authorization flow for CLI authentication. + +**Quickstart users:** This section is **not required** when using the embedded IdP. The embedded IdP automatically handles device authorization flow at `https://your-domain/oauth2/device/authorize`. + +**Using external IdPs like Google, Okta, self-hosted Authentik, or any other OIDC provider?** If you added them through **Settings → Identity Providers** in the Dashboard, the device authorization flow works automatically - no configuration needed here. + +This section is only needed for the [legacy advanced deployment method](/selfhosted/selfhosted-guide) where the embedded IdP is disabled and you need to configure device authorization directly with an external identity provider. + + +Configures device authorization flow for CLI authentication. This flow enables users to authenticate NetBird clients via `netbird login` by visiting a URL and entering a code. It is particularly useful for headless devices or environments where browser-based login is impractical. ```json "DeviceAuthorizationFlow": { @@ -593,7 +799,15 @@ Configures device authorization flow for CLI authentication. ### PKCEAuthorizationFlow Section -Configures PKCE authorization flow for browser-based authentication. + +**Quickstart users:** This section is **not required** when using the embedded IdP. The embedded IdP automatically handles PKCE authorization flow for desktop clients that launch a browser for authentication. + +**Using external IdPs like Google, Okta, self-hosted Authentik, or any other OIDC provider?** If you added them through **Settings → Identity Providers** in the Dashboard, PKCE authentication works automatically - no configuration needed here. + +This section is only needed for the [legacy advanced deployment method](/selfhosted/selfhosted-guide) where the embedded IdP is disabled and you need to configure PKCE flow directly with an external identity provider. + + +Configures PKCE (Proof Key for Code Exchange) authorization flow for browser-based authentication. This flow is used by desktop clients that can launch a local web server to receive the OAuth callback, providing a more seamless authentication experience than the device flow. ```json "PKCEAuthorizationFlow": { @@ -649,38 +863,44 @@ Configures PKCE authorization flow for browser-based authentication. - Disable the default "allow all" access policy for new accounts. Default: `false` + Disable the default "allow all" access policy for new accounts. When `true`, new accounts start with no access rules, requiring explicit policy creation before peers can communicate. Default: `false` - Data directory path. Usually set via command line. + Data directory path where the management service stores its database and state files. Usually set via command line (`--datadir`). Default: `/var/lib/netbird` - 32-byte encryption key for sensitive data at rest. Auto-generated by setup scripts. + 32-byte (256-bit) encryption key for sensitive data at rest. Used to encrypt setup keys, API tokens, and other secrets stored in the database. Auto-generated by setup scripts. -Keep `DataStoreEncryptionKey` secure and backed up. Losing this key means losing access to encrypted data in the database. +Keep `DataStoreEncryptionKey` secure and backed up. This key encrypts sensitive data in your database, including setup keys and API tokens. Losing this key means losing access to encrypted data, and you will need to regenerate all setup keys and API tokens. --- ## relay.env -Environment configuration for the relay service. This file is mounted into the relay container. +Environment configuration for the relay service. This file is mounted into the relay container and configures both the relay and the embedded STUN server. ```bash # Log level: debug, info, warn, error NB_LOG_LEVEL=info -# Address to listen on -NB_LISTEN_ADDRESS=:33080 +# Address to listen on for relay connections +NB_LISTEN_ADDRESS=:80 # Public address for peers to connect -NB_EXPOSED_ADDRESS=rel://netbird.example.com:33080 +# Use rel:// for unencrypted or rels:// for TLS +NB_EXPOSED_ADDRESS=rels://netbird.example.com:443 # Authentication secret (must match management.json Relay.Secret) NB_AUTH_SECRET=your-secret-here + +# Embedded STUN server configuration +NB_ENABLE_STUN=true +NB_STUN_LOG_LEVEL=info +NB_STUN_PORTS=3478 ``` ### All Relay Variables @@ -688,9 +908,12 @@ NB_AUTH_SECRET=your-secret-here | Variable | Default | Description | |----------|---------|-------------| | `NB_LOG_LEVEL` | `info` | Log verbosity | -| `NB_LISTEN_ADDRESS` | `:33080` | Listen address | +| `NB_LISTEN_ADDRESS` | `:80` | Listen address for relay connections | | `NB_EXPOSED_ADDRESS` | - | Public relay address for peers | | `NB_AUTH_SECRET` | - | Shared authentication secret | +| `NB_ENABLE_STUN` | `false` | Enable embedded STUN server | +| `NB_STUN_PORTS` | `3478` | STUN server UDP ports (comma-separated) | +| `NB_STUN_LOG_LEVEL` | `info` | STUN server log level | | `NB_METRICS_PORT` | - | Prometheus metrics port (optional) | | `NB_TLS_CERT_FILE` | - | TLS certificate file path | | `NB_TLS_KEY_FILE` | - | TLS key file path | @@ -758,56 +981,6 @@ LETSENCRYPT_EMAIL=admin@example.com --- -## turnserver.conf - -Coturn TURN server configuration. - -```ini -# Listening ports -listening-port=3478 -tls-listening-port=5349 - -# TURN relay port range -min-port=49152 -max-port=65535 - -# Authentication -lt-cred-mech -user=netbird:your-turn-password - -# Domain/Realm -realm=wiretrustee.com - -# Logging -log-file=stdout - -# Fingerprinting -fingerprint - -# Disable TCP relay (optional, saves resources) -# no-tcp-relay -``` - -### Key Settings - -| Setting | Default | Description | -|---------|---------|-------------| -| `listening-port` | `3478` | UDP/TCP STUN/TURN port | -| `tls-listening-port` | `5349` | TLS TURN port | -| `min-port` | `49152` | Minimum relay port | -| `max-port` | `65535` | Maximum relay port | -| `lt-cred-mech` | - | Enable long-term credential mechanism | -| `user` | - | TURN credentials in format `username:password` | -| `realm` | `wiretrustee.com` | TURN realm | -| `external-ip` | - | External IP for NAT (if behind NAT) | -| `fingerprint` | - | Enable STUN fingerprinting | - - -If your server is behind NAT, you must configure `external-ip` with your public IP address for TURN to work correctly. - - ---- - ## Common Configuration Scenarios ### Using an External Database @@ -878,7 +1051,11 @@ See [Reverse Proxy Configuration](/selfhosted/reverse-proxy) for detailed templa ### Configuring External TURN Servers -To use external TURN servers (e.g., for geographically distributed deployments): + +The default NetBird deployment uses the relay service for NAT traversal, which handles most connectivity scenarios. External TURN servers are only needed for advanced use cases like geographically distributed deployments or environments with restrictive firewalls that block the relay protocol. + + +To use external TURN servers (e.g., coturn deployed separately): ```json "TURNConfig": { diff --git a/src/pages/selfhosted/environment-variables.mdx b/src/pages/selfhosted/environment-variables.mdx index 6528227c..a0be3c61 100644 --- a/src/pages/selfhosted/environment-variables.mdx +++ b/src/pages/selfhosted/environment-variables.mdx @@ -2,7 +2,7 @@ import {Note} from "@/components/mdx"; # Environment Variables Configuration -This page provides a comprehensive reference for all environment variables available when self-hosting NetBird. Environment variables allow you to configure the Management Server, Signal Server, Relay Server, Dashboard, and Coturn (TURN) services. +This page provides a comprehensive reference for all environment variables available when self-hosting NetBird. Environment variables allow you to configure the Management Server, Signal Server, Relay Server (including the embedded STUN server), and Dashboard services. Environment variables set in your `setup.env` file are used by the `configure.sh` script to generate the final configuration files. Changes to `setup.env` require re-running `./configure.sh` to take effect. @@ -36,15 +36,17 @@ These variables are set in your `setup.env` file before running the configuratio | `NETBIRD_RELAY_PORT` | `33080` | Relay server port | | `NGINX_SSL_PORT` | `443` | Dashboard HTTPS port | -### TURN Server +### STUN Configuration + + +The default quickstart deployment uses the relay service's embedded STUN server. The variables below configure STUN functionality within the relay container via `relay.env`. + | Variable | Default | Description | |----------|---------|-------------| -| `TURN_DOMAIN` | Same as `NETBIRD_DOMAIN` | TURN server domain | -| `TURN_USER` | Auto-generated | TURN authentication username | -| `TURN_PASSWORD` | Auto-generated | TURN authentication password | -| `TURN_MIN_PORT` | `49152` | Minimum TURN relay port | -| `TURN_MAX_PORT` | `65535` | Maximum TURN relay port | +| `NB_ENABLE_STUN` | `true` | Enable embedded STUN server in relay | +| `NB_STUN_PORTS` | `3478` | STUN server UDP ports | +| `NB_STUN_LOG_LEVEL` | `info` | STUN server log level | ## Management Server Variables @@ -178,6 +180,9 @@ These variables can override CLI flags at runtime. The naming convention is `NB_ | `NB_LETSENCRYPT_DOMAINS` | - | Let's Encrypt domains | | `NB_LETSENCRYPT_EMAIL` | - | Let's Encrypt email | | `NB_HEALTH_LISTEN_ADDRESS` | - | Health check listen address | +| `NB_ENABLE_STUN` | `false` | Enable embedded STUN server | +| `NB_STUN_PORTS` | `3478` | STUN server UDP ports (comma-separated) | +| `NB_STUN_LOG_LEVEL` | `info` | STUN server log level | ## Dashboard Variables @@ -192,7 +197,11 @@ These variables can override CLI flags at runtime. The naming convention is `NB_ Dashboard authentication is automatically configured when using the embedded identity provider. The dashboard connects to the management server's built-in OAuth2 endpoints. -## Coturn (TURN Server) Variables +## Coturn (TURN Server) Variables (Legacy) + + +The default quickstart deployment no longer uses a separate Coturn container. STUN functionality is now embedded in the relay service. The variables below are only relevant for legacy deployments or advanced configurations that still use Coturn. + Coturn configuration is generated from templates using these variables: @@ -205,9 +214,7 @@ Coturn configuration is generated from templates using these variables: | `TURN_MAX_PORT` | `65535` | Maximum relay port | | `TURN_EXTERNAL_IP_CONFIG` | - | External IP configuration | - The Coturn service uses static ports: `3478` (STUN/TURN) and `5349` (TLS TURN). - ## Configuration Examples diff --git a/src/pages/selfhosted/selfhosted-quickstart.mdx b/src/pages/selfhosted/selfhosted-quickstart.mdx index accfc2ef..35bb17da 100644 --- a/src/pages/selfhosted/selfhosted-quickstart.mdx +++ b/src/pages/selfhosted/selfhosted-quickstart.mdx @@ -72,12 +72,11 @@ Rendering initial files... Starting NetBird services -[+] Running 6/6 +[+] Running 5/5 ✔ Network netbird Created ✔ Container netbird-dashboard Started ✔ Container netbird-management Started ✔ Container netbird-relay Started - ✔ Container netbird-coturn Started ✔ Container netbird-signal Started ✔ Container netbird-caddy Started Waiting for Management server to become ready . . done @@ -139,7 +138,7 @@ To back up your NetBird installation, you need to copy the configuration files a The configuration files are located in the folder where you ran the installation script. To back up, copy the files to a backup location: ```bash mkdir backup -cp docker-compose.yml Caddyfile dashboard.env turnserver.conf management.json relay.env backup/ +cp docker-compose.yml Caddyfile dashboard.env management.json relay.env backup/ ``` @@ -160,11 +159,11 @@ To upgrade NetBird to the latest version: 2. Review the [release notes](https://github.com/netbirdio/netbird/releases) for any breaking changes. 3. Pull the latest NetBird docker images: ```bash - docker compose pull management dashboard signal relay coturn + docker compose pull management dashboard signal relay ``` 4. Restart the NetBird containers with the new images: ```bash - docker compose up -d --force-recreate management dashboard signal relay coturn + docker compose up -d --force-recreate management dashboard signal relay ``` @@ -177,7 +176,7 @@ To remove the NetBird installation and all related data from your server, run th # remove all NetBird-related containers and volumes (data) docker compose down --volumes # remove downloaded and generated config files -rm -f docker-compose.yml Caddyfile dashboard.env turnserver.conf management.json relay.env +rm -f docker-compose.yml Caddyfile dashboard.env management.json relay.env ``` ## Troubleshoot From e63099d004005e342477ad6666e126073008f80c Mon Sep 17 00:00:00 2001 From: Ashley Mensah Date: Wed, 21 Jan 2026 20:56:40 +0100 Subject: [PATCH 3/7] added more detailed file value descriptions, clarifications on dashboard built-in nginx, signal legacy port 10000 --- src/pages/selfhosted/configuration-files.mdx | 753 +++++++----------- .../selfhosted/selfhosted-quickstart.mdx | 3 +- 2 files changed, 305 insertions(+), 451 deletions(-) diff --git a/src/pages/selfhosted/configuration-files.mdx b/src/pages/selfhosted/configuration-files.mdx index 9a37d5d7..ef764ef1 100644 --- a/src/pages/selfhosted/configuration-files.mdx +++ b/src/pages/selfhosted/configuration-files.mdx @@ -3,23 +3,23 @@ import {Properties, Property} from "@/components/mdx"; # Configuration Files Reference -This page provides a comprehensive reference for all configuration files used when self-hosting NetBird. Understanding these files helps you customize your deployment, troubleshoot issues, and integrate with existing infrastructure. +This page provides a comprehensive reference for all configuration files used when self-hosting NetBird with the `getting-started.sh` deployment method. Understanding these files helps you customize your deployment, troubleshoot issues, and integrate with existing infrastructure. -Most configuration files are **generated automatically** by the `getting-started.sh` or `configure.sh` scripts. Modifying files directly is only necessary for advanced customization. Changes to `setup.env` require re-running the configuration script to take effect. +Configuration files are **generated automatically** by the `getting-started.sh` script. Modifying files directly is only necessary for advanced customization after initial setup. ## Overview A standard NetBird self-hosted deployment uses the following configuration files: -| File | Purpose | Generated By | -|------|---------|--------------| -| `docker-compose.yml` | Service definitions and orchestration | `getting-started.sh` / `configure.sh` | -| `management.json` | Core management server configuration | `getting-started.sh` / `configure.sh` | -| `relay.env` | Relay server environment variables (includes STUN configuration) | `getting-started.sh` | -| `dashboard.env` | Dashboard UI configuration | `getting-started.sh` | -| `Caddyfile` | Reverse proxy configuration (when using built-in Caddy) | `getting-started.sh` | +| File | Purpose | +|------|---------| +| `docker-compose.yml` | Defines all NetBird services (dashboard, management, signal, relay), their Docker images, port mappings, volumes, and startup order. Modify this to change resource limits, add services, or adjust networking. | +| `management.json` | Central configuration for the management server including STUN/relay server addresses, authentication settings, and database configuration. Changes here affect how peers connect and authenticate. | +| `relay.env` | Environment variables for the relay service including the authentication secret, public address, and embedded STUN server settings. The relay secret here must match `management.json`. | +| `dashboard.env` | Configures the web dashboard including API endpoints, OAuth2/OIDC settings, and optional SSL settings for standalone deployments without a reverse proxy. | +| `Caddyfile` | Configures the built-in Caddy reverse proxy for SSL termination and routing requests to NetBird services. Only present when using the default `getting-started.sh` deployment with Caddy. | ### File Locations @@ -42,13 +42,17 @@ The Docker Compose file defines all NetBird services, their dependencies, networ ### Services Overview -| Service | Image | Default Port | Description | -|---------|-------|--------------|-------------| -| `dashboard` | `netbirdio/dashboard` | 80, 443 | Web UI for managing NetBird | -| `management` | `netbirdio/management` | 80 | Core API, peer coordination, and embedded IdP | -| `signal` | `netbirdio/signal` | 80, 10000 | WebRTC signaling for peer connections | -| `relay` | `netbirdio/relay` | 80, 3478/udp | Relay server for NAT traversal with embedded STUN | -| `caddy` | `caddy` | 80, 443 | Reverse proxy (optional, built-in setup) | +| Service | Image | Internal Port | External (Exposed) | Description | +|---------|-------|---------------|-------------------|-------------| +| `dashboard` | `netbirdio/dashboard` | 80 | 8080:80 | The web-based management console where administrators configure networks, manage peers, create access policies, and view activity logs. Includes an embedded nginx server for serving the UI. | +| `management` | `netbirdio/management` | 80 | 8081:80 | The central control plane that handles peer registration, distributes network configurations, manages access policies, and hosts the embedded identity provider. All peers connect to this service on startup. | +| `signal` | `netbirdio/signal` | 80, 10000 | 8083:80, 10000:10000 | Facilitates WebRTC signaling so peers can exchange connection offers and establish direct WireGuard tunnels. Handles only connection setup metadata, not actual traffic. Port 80 is for modern HTTP/2 connections; port 10000 is for legacy gRPC (see note below). | +| `relay` | `netbirdio/relay` | 80, 3478/udp | 8084:80, 3478:3478/udp | Routes encrypted traffic between peers when direct connections fail due to restrictive NATs or firewalls. Also provides embedded STUN on UDP 3478 for NAT type detection. | +| `caddy` | `caddy` | 80, 443 | 80:80, 443:443 | Handles TLS termination and routes incoming HTTPS requests to the appropriate NetBird services. Only included in default `getting-started.sh` deployments; can be replaced with your own reverse proxy. | + + +**Internal vs External ports**: Internal ports are what services listen on inside their containers. External (Exposed) ports show the host-to-container mapping used when running without the built-in Caddy (e.g., with Nginx, Traefik, or other reverse proxies). When using the default Caddy deployment, only Caddy exposes ports externally. + The relay service includes an embedded STUN server, eliminating the need for a separate coturn container. STUN functionality is enabled via the `NB_ENABLE_STUN` environment variable in `relay.env`. @@ -72,143 +76,221 @@ x-default: &default The dashboard provides the web interface for NetBird management. +**With built-in Caddy (default):** ```yaml dashboard: image: netbirdio/dashboard:latest + container_name: netbird-dashboard + restart: unless-stopped + networks: [netbird] + env_file: + - ./dashboard.env + logging: + driver: "json-file" + options: + max-size: "500m" + max-file: "2" +``` + +**With external reverse proxy (exposed ports):** +```yaml +dashboard: + image: netbirdio/dashboard:latest + container_name: netbird-dashboard + restart: unless-stopped + networks: [netbird] ports: - - 80:80 - - 443:443 - environment: - - NETBIRD_MGMT_API_ENDPOINT=https://netbird.example.com - - NETBIRD_MGMT_GRPC_API_ENDPOINT=https://netbird.example.com - - AUTH_AUDIENCE=netbird-dashboard - - AUTH_CLIENT_ID=netbird-dashboard - - AUTH_AUTHORITY=https://netbird.example.com/oauth2 - - USE_AUTH0=false - - AUTH_SUPPORTED_SCOPES=openid profile email groups - - AUTH_REDIRECT_URI=/nb-auth - - AUTH_SILENT_REDIRECT_URI=/nb-silent-auth - - NGINX_SSL_PORT=443 - - LETSENCRYPT_DOMAIN=netbird.example.com - - LETSENCRYPT_EMAIL=admin@example.com - volumes: - - netbird-letsencrypt:/etc/letsencrypt/ + - '127.0.0.1:8080:80' + env_file: + - ./dashboard.env + logging: + driver: "json-file" + options: + max-size: "500m" + max-file: "2" ``` - - - Full URL to the Management API endpoint. Used for REST API calls from the dashboard. - - - Full URL to the Management gRPC endpoint. Usually the same as the API endpoint. - - - OAuth2 audience for token validation. Default: `netbird-dashboard` - - - OAuth2 client ID for the dashboard application. - - - OAuth2 issuer URL. For embedded IdP: `https://your-domain/oauth2` - - - Set to `true` if using Auth0 as the identity provider. Default: `false` - - - Space-separated OAuth2 scopes. Default: `openid profile email groups` - - - OAuth2 redirect URI path. Default: `/nb-auth` - - - Silent authentication redirect URI. Default: `/nb-silent-auth` - - - HTTPS port for the dashboard. Default: `443` - - - Domain for Let's Encrypt certificate. Set to `none` to disable. - - - Email for Let's Encrypt registration and renewal notices. - - + +The dashboard service is configured via the `dashboard.env` file. See the [dashboard.env section](#dashboardenv) for the full list of environment variables. When using the built-in Caddy, no ports are exposed directly from the dashboard container; Caddy routes traffic to it internally. + ### Management Service The management service is the core of NetBird, handling peer registration, authentication, and network coordination. +**With built-in Caddy (default):** ```yaml management: image: netbirdio/management:latest - depends_on: - - dashboard + container_name: netbird-management + restart: unless-stopped + networks: [netbird] volumes: - - netbird-mgmt:/var/lib/netbird - - netbird-letsencrypt:/etc/letsencrypt:ro + - netbird_management:/var/lib/netbird - ./management.json:/etc/netbird/management.json + command: [ + "--port", "80", + "--log-file", "console", + "--log-level", "info", + "--disable-anonymous-metrics=false", + "--single-account-mode-domain=netbird.selfhosted", + "--dns-domain=netbird.selfhosted", + "--idp-sign-key-refresh-enabled", + ] + logging: + driver: "json-file" + options: + max-size: "500m" + max-file: "2" +``` + +**With external reverse proxy (exposed ports):** +```yaml +management: + image: netbirdio/management:latest + container_name: netbird-management + restart: unless-stopped + networks: [netbird] ports: - - 33073:443 + - '127.0.0.1:8081:80' + volumes: + - netbird_management:/var/lib/netbird + - ./management.json:/etc/netbird/management.json command: [ - "--port", "443", + "--port", "80", "--log-file", "console", "--log-level", "info", "--disable-anonymous-metrics=false", - "--single-account-mode-domain=netbird.example.com", - "--dns-domain=netbird.selfhosted" + "--single-account-mode-domain=netbird.selfhosted", + "--dns-domain=netbird.selfhosted", + "--idp-sign-key-refresh-enabled", ] + logging: + driver: "json-file" + options: + max-size: "500m" + max-file: "2" +``` + +To use an external database, add environment variables: +```yaml environment: - - NETBIRD_STORE_ENGINE_POSTGRES_DSN= - - NETBIRD_STORE_ENGINE_MYSQL_DSN= + - NETBIRD_STORE_ENGINE_POSTGRES_DSN=postgres://user:password@host:5432/netbird + # Or for MySQL: + # - NETBIRD_STORE_ENGINE_MYSQL_DSN=user:password@tcp(host:3306)/netbird ``` #### Command-Line Flags | Flag | Default | Description | |------|---------|-------------| -| `--port` | `443` | Internal listening port | -| `--log-file` | `console` | Log output destination | -| `--log-level` | `info` | Log verbosity: `debug`, `info`, `warn`, `error` | -| `--disable-anonymous-metrics` | `false` | Disable anonymous usage metrics | -| `--single-account-mode-domain` | - | Domain for single account mode | -| `--dns-domain` | `netbird.selfhosted` | DNS domain for peer resolution | +| `--port` | `80` | The port the management server listens on inside the container. The default deployment uses port 80 internally; TLS is handled by the reverse proxy. | +| `--log-file` | `console` | Where to write log output. Use `console` for Docker logging (recommended) or specify a file path. Logs to console are captured by Docker's logging driver. | +| `--log-level` | `info` | Controls log verbosity. Use `debug` for troubleshooting connection issues, `info` for normal operation, `warn` or `error` for quieter logs in production. | +| `--disable-anonymous-metrics` | `false` | When `true`, stops sending anonymous usage statistics to NetBird. Set to `true` for air-gapped environments or if your security policy prohibits telemetry. | +| `--single-account-mode-domain` | `netbird.selfhosted` | Restricts all users to a single NetBird account associated with this domain. Required for most self-hosted deployments to prevent users from creating separate accounts. | +| `--dns-domain` | `netbird.selfhosted` | The DNS suffix used for peer name resolution within NetBird (e.g., `peer-name.netbird.selfhosted`). Must not conflict with your existing DNS domains. | +| `--idp-sign-key-refresh-enabled` | `false` | Enables automatic refresh of IdP signing keys. Recommended for the embedded IdP to ensure tokens remain valid. | ### Signal Service The signal service handles WebRTC signaling for establishing peer-to-peer connections. +**With built-in Caddy (default):** ```yaml signal: image: netbirdio/signal:latest - depends_on: - - dashboard - volumes: - - netbird-signal:/var/lib/netbird - - netbird-letsencrypt:/etc/letsencrypt:ro + container_name: netbird-signal + restart: unless-stopped + networks: [netbird] + logging: + driver: "json-file" + options: + max-size: "500m" + max-file: "2" +``` + +**With external reverse proxy (exposed ports):** +```yaml +signal: + image: netbirdio/signal:latest + container_name: netbird-signal + restart: unless-stopped + networks: [netbird] ports: - - 10000:80 - command: [ - "--cert-file", "/etc/letsencrypt/live/netbird.example.com/fullchain.pem", - "--cert-key", "/etc/letsencrypt/live/netbird.example.com/privkey.pem", - "--log-file", "console", - "--port", "80" - ] + - '127.0.0.1:8083:80' + - '127.0.0.1:10000:10000' + logging: + driver: "json-file" + options: + max-size: "500m" + max-file: "2" ``` +#### Signal Service Ports + +The signal service exposes two ports with different purposes: + +| Port | Protocol | Purpose | Clients | +|------|----------|---------|---------| +| 80 | HTTP/2 (h2c) | Modern signal connections via reverse proxy | NetBird v0.10.0+ (July 2022 and later) | +| 10000 | gRPC | Legacy backward compatibility server | NetBird clients older than v0.10.0 | + + +**About port 10000 (Legacy gRPC):** Starting with NetBird v0.10.0, the signal service moved to standard HTTP ports (443/80) with HTTP/2 support, allowing connections through reverse proxies. Port 10000 is maintained as a **backward compatibility server** for older clients that still use the original gRPC protocol. + +**When can you close port 10000?** If all your NetBird clients are running v0.10.0 or later (released July 2022), you can safely remove the port 10000 mapping from your `docker-compose.yml`. Modern clients connect via the reverse proxy on ports 443/80 using HTTP/2. However, if you have any older clients or are unsure, keep port 10000 open to ensure connectivity. + + + +When using the built-in Caddy reverse proxy, port 10000 is not exposed externally by default since Caddy routes modern signal traffic internally. If you need to support legacy clients with the built-in Caddy deployment, you would need to add the port mapping manually. + + ### Relay Service The relay service provides NAT traversal when direct peer-to-peer connections are not possible. It also includes an embedded STUN server for NAT detection and traversal. +**With built-in Caddy (default):** ```yaml relay: image: netbirdio/relay:latest + container_name: netbird-relay + restart: unless-stopped + networks: [netbird] + ports: + - '3478:3478/udp' # Embedded STUN server (must be exposed publicly) env_file: - ./relay.env + logging: + driver: "json-file" + options: + max-size: "500m" + max-file: "2" +``` + +**With external reverse proxy (exposed ports):** +```yaml +relay: + image: netbirdio/relay:latest + container_name: netbird-relay + restart: unless-stopped + networks: [netbird] ports: - - '80:80' # Relay WebSocket - - '3478:3478/udp' # Embedded STUN server + - '127.0.0.1:8084:80' # Relay WebSocket (for reverse proxy) + - '3478:3478/udp' # Embedded STUN server (must be exposed publicly) + env_file: + - ./relay.env + logging: + driver: "json-file" + options: + max-size: "500m" + max-file: "2" ``` + +The STUN port (3478/udp) must always be exposed publicly, regardless of reverse proxy configuration. STUN uses UDP for NAT detection and cannot be proxied through HTTP reverse proxies. + + The relay service is configured via the `relay.env` file. See the [relay.env section](#relayenv) for detailed configuration options. @@ -248,9 +330,12 @@ If you have an existing installation using coturn, or need advanced TURN functio | Volume | Mount Point | Purpose | |--------|-------------|---------| -| `netbird-mgmt` | `/var/lib/netbird` | Management database and state | -| `netbird-signal` | `/var/lib/netbird` | Signal service data | -| `netbird-letsencrypt` | `/etc/letsencrypt` | TLS certificates | +| `netbird_management` | `/var/lib/netbird` | Stores the management database (SQLite by default), encryption keys, and persistent state. Back up this volume regularly to preserve your accounts, peers, policies, and setup keys. | +| `netbird_caddy_data` | `/data` | Stores Caddy's TLS certificates and other persistent data. Only used when deploying with the built-in Caddy reverse proxy. Preserve this volume to maintain TLS certificates across restarts. | + + +The `getting-started.sh` deployment uses only two volumes: `netbird_management` for the management database and `netbird_caddy_data` for Caddy's certificate storage. The signal and relay services do not require persistent volumes in the default configuration. + --- @@ -258,17 +343,9 @@ If you have an existing installation using coturn, or need advanced TURN functio The management configuration file controls the core behavior of the NetBird Management service. This is the most complex configuration file. -### Embedded IdP vs External IdP Configuration - -The structure of `management.json` varies significantly depending on whether you use the **embedded IdP** (quickstart deployment) or configure identity providers at the **infrastructure level** (advanced deployment). +### About the Embedded IdP - -**Most users following the [Quickstart Guide](/selfhosted/selfhosted-quickstart) will have a much simpler `management.json`**. The embedded IdP handles authentication automatically, and many of the sections documented below are not needed. - - -#### Understanding "Embedded IdP" - -The term "embedded IdP" refers to NetBird's built-in identity provider system based on DEX. This is **not** a limitation - it is actually the modern, recommended approach that offers several advantages: +The `getting-started.sh` deployment uses NetBird's **embedded identity provider (IdP)**, which is based on DEX. This is the standard, recommended approach that handles authentication automatically. **You CAN connect external identity providers with the embedded IdP:** - **Google Workspace** - Use Google accounts for authentication @@ -277,64 +354,34 @@ The term "embedded IdP" refers to NetBird's built-in identity provider system ba - **Self-hosted Authentik** - Use your own Authentik instance for authentication - **Any OIDC provider** - Any provider supporting OpenID Connect works with NetBird -**How to add external IdPs with the embedded system:** +**How to add external IdPs:** 1. Go to **Settings → Identity Providers** in the NetBird Dashboard 2. Click **Add Identity Provider** -3. Follow the guided setup for your chosen provider (Google, Okta, self-hosted Authentik, or any other OIDC provider) +3. Follow the guided setup for your chosen provider 4. Users can then authenticate using their existing corporate credentials This Dashboard-based configuration is simpler, more maintainable, and does not require editing `management.json`. -#### When to use infrastructure-level IdP configuration - -The `HttpConfig`, `IdpManagerConfig`, `DeviceAuthorizationFlow`, and `PKCEAuthorizationFlow` sections documented below are for the **legacy advanced deployment method** where: -- You configure the IdP connection directly in `management.json` -- The embedded IdP is disabled -- You manage OAuth2/OIDC settings at the infrastructure level rather than through the UI - -This approach is typically only needed for: -- Organizations with specific compliance requirements mandating infrastructure-as-code IdP configuration -- Complex multi-tenant scenarios -- Migrations from older NetBird deployments that predate the Dashboard IdP management feature - -**Quickstart deployment (embedded IdP - recommended):** -- Uses the `EmbeddedIdP` section to enable the built-in identity provider -- External IdPs (Google, Okta, self-hosted Authentik, or any other OIDC provider) are added via **Settings → Identity Providers** in the Dashboard -- Sections like `HttpConfig`, `IdpManagerConfig`, `DeviceAuthorizationFlow`, and `PKCEAuthorizationFlow` are **not required** and typically omitted -- Authentication endpoints are automatically configured at `https://your-domain/oauth2/` -- User management is done through the Dashboard UI - -**Advanced deployment (infrastructure-level IdP):** -- Does **not** use the `EmbeddedIdP` section -- Requires full configuration of `HttpConfig`, `IdpManagerConfig`, `DeviceAuthorizationFlow`, and `PKCEAuthorizationFlow` -- You must configure your external IdP (Okta, Keycloak, Auth0, etc.) and populate these sections with the appropriate values -- See the [Advanced Self-hosting Guide](/selfhosted/selfhosted-guide) for setup instructions - -### Configuration Section Summary - -| Section | Quickstart (Embedded IdP) | Advanced (Infrastructure-level IdP) | -|---------|---------------------------|-------------------------------------| -| `Stuns` | Required | Required | -| `TURNConfig` | Optional | Optional | -| `Relay` | Required | Required | -| `Signal` | Required | Required | -| `ReverseProxy` | Optional | Optional | -| `StoreConfig` | Optional | Optional | -| `EmbeddedIdP` | **Required** | Not used | -| `HttpConfig` | Not used (auto-configured) | **Required** | -| `IdpManagerConfig` | Not used | **Required** | -| `DeviceAuthorizationFlow` | Not used (auto-configured) | **Required** | -| `PKCEAuthorizationFlow` | Not used (auto-configured) | **Required** | - -**Remember:** The "Quickstart (Embedded IdP)" column applies even if you want to use external providers like Google, Okta, self-hosted Authentik, or any other OIDC provider. You can add these through **Settings → Identity Providers** in the Dashboard without changing your `management.json` configuration. +If you need to configure identity providers at the infrastructure level (directly in configuration files rather than through the Dashboard), see the [Advanced Self-hosting Guide](/selfhosted/selfhosted-guide). -### Complete Structure +### Configuration Sections -The structure differs based on your deployment type: +The `management.json` file for `getting-started.sh` deployments uses these sections: + +| Section | Required | Description | +|---------|----------|-------------| +| `Stuns` | Yes | Lists STUN servers that peers use to discover their public IP address and NAT type. Without working STUN, peers cannot establish direct connections and will always use the relay. | +| `Relay` | Yes | Configures relay server addresses and authentication. Peers use relay servers when direct connections fail. The secret here must match `NB_AUTH_SECRET` in `relay.env`. | +| `Signal` | Yes | Specifies how the management server connects to the signal service. Peers receive this address and use it to exchange connection offers with other peers. | +| `EmbeddedIdP` | Yes | Enables and configures the built-in identity provider (based on DEX). Handles user authentication, token issuance, and OIDC endpoints. Required for `getting-started.sh` deployments. | +| `ReverseProxy` | No | Defines trusted proxy IP ranges for accurate client IP detection. Configure this when running behind a load balancer or reverse proxy to ensure correct IP logging and rate limiting. | +| `StoreConfig` | No | Specifies the database engine (SQLite, PostgreSQL, or MySQL). Defaults to SQLite. Use PostgreSQL for production deployments requiring high availability or concurrent access. | +| `TURNConfig` | No | Legacy configuration for external TURN servers like coturn. Not used in standard deployments since the relay service handles NAT traversal. Only needed for advanced scenarios. | + +### Complete Structure -**Quickstart deployment (embedded IdP):** ```json { "Stuns": [...], @@ -350,24 +397,6 @@ The structure differs based on your deployment type: } ``` -**Advanced deployment (external IdP):** -```json -{ - "Stuns": [...], - "TURNConfig": {...}, - "Relay": {...}, - "Signal": {...}, - "ReverseProxy": {...}, - "DisableDefaultPolicy": false, - "DataStoreEncryptionKey": "...", - "StoreConfig": {...}, - "HttpConfig": {...}, - "IdpManagerConfig": {...}, - "DeviceAuthorizationFlow": {...}, - "PKCEAuthorizationFlow": {...} -} -``` - ### Stuns Section Configures STUN servers used for NAT detection and traversal. @@ -408,9 +437,13 @@ The embedded STUN server in the relay service (enabled via `NB_ENABLE_STUN=true` -### TURNConfig Section +### TURNConfig Section (Legacy) -Configures TURN servers for relay when direct connections fail. + +The `TURNConfig` section is a **legacy configuration** for deployments using external TURN servers (such as coturn). The `getting-started.sh` deployment uses the **Relay service** instead, which provides similar NAT traversal functionality with simpler configuration. This section is not included in standard `getting-started.sh` deployments. + + +If you have an existing deployment using TURN servers or need specific TURN features (such as TCP relay or time-based credentials), you can configure them here: ```json "TURNConfig": { @@ -469,15 +502,19 @@ When two NetBird peers cannot establish a direct WireGuard connection (due to re ```json "Relay": { - "Addresses": ["rel://netbird.example.com:33080"], + "Addresses": ["rels://netbird.example.com:443"], "CredentialsTTL": "24h", "Secret": "your-relay-secret" } ``` + +The relay address uses the same port as HTTPS (443) when using TLS (`rels://`), or port 80 when not using TLS (`rel://`). The reverse proxy routes `/relay*` paths to the relay service internally. + + - Array of relay server addresses. Format: `rel://hostname:port` + Array of relay server addresses. Format: `rels://hostname:port` for TLS or `rel://hostname:port` for unencrypted. Default uses the public HTTPS port (443). Time-to-live for relay credentials. Default: `24h` @@ -505,19 +542,23 @@ The signal service facilitates WebRTC signaling between NetBird peers. When two ```json "Signal": { - "Proto": "http", - "URI": "netbird.example.com:10000", + "Proto": "https", + "URI": "netbird.example.com:443", "Username": "", "Password": null } ``` + +The signal URI uses the same public HTTPS port (443) as other services. The reverse proxy routes signal traffic (`/signalexchange.SignalExchange/*` and `/ws-proxy/signal*`) to the signal service internally. + + - Protocol for signal communication. Options: `http`, `https`. Default: `http` (internal), `https` (external). + Protocol for signal communication. Options: `http`, `https`. Use `https` for production deployments with TLS, or `http` for non-TLS setups. - Signal server address. Format: `hostname:port` + Signal server address. Format: `hostname:port`. Uses the public port (443 for HTTPS, 80 for HTTP). Optional authentication username. Usually empty. @@ -577,9 +618,9 @@ The management database contains all persistent state for your NetBird deploymen | Engine | Storage Location | Notes | |--------|------------------|-------| -| SQLite (default) | `/var/lib/netbird/` volume | File-based, stored in the `netbird-mgmt` Docker volume. Simple but limited to single-instance deployments. | -| PostgreSQL | External database server | Recommended for production. Supports high availability and backups. | -| MySQL | External database server | Alternative to PostgreSQL for organizations standardized on MySQL. | +| SQLite (default) | `/var/lib/netbird/` volume | File-based database stored in the `netbird-mgmt` Docker volume. Zero configuration required, but does not support concurrent writes or running multiple management instances. Best for testing or small deployments with fewer than 100 peers. | +| PostgreSQL | External database server | Recommended for production deployments. Supports concurrent access, enabling multiple management instances for high availability. Requires managing a separate PostgreSQL server but offers standard backup tools and replication options. | +| MySQL | External database server | Alternative to PostgreSQL for organizations that have standardized on MySQL/MariaDB. Provides similar benefits to PostgreSQL including concurrent access and standard backup procedures. | ```json "StoreConfig": { @@ -605,12 +646,6 @@ See [Management Postgres Store](/selfhosted/postgres-store) for PostgreSQL setup ### EmbeddedIdP Section - -This section is used by the **quickstart deployment** with the embedded identity provider. If you see this section in your `management.json`, you are using the embedded IdP and do **not** need to configure `HttpConfig`, `IdpManagerConfig`, `DeviceAuthorizationFlow`, or `PKCEAuthorizationFlow` manually. - -**Want to use Google, Okta, self-hosted Authentik, or any other OIDC provider?** You do not need to disable the embedded IdP or edit this file. Instead, add your external IdP through **Settings → Identity Providers** in the Dashboard. The embedded IdP system supports connecting external providers through the UI. - - Configures the built-in identity provider that handles user authentication and management. The embedded IdP is based on DEX and supports both local user management and connections to external identity providers configured through the Dashboard. ```json @@ -626,7 +661,7 @@ Configures the built-in identity provider that handles user authentication and m - Enable the embedded identity provider. When `true`, the management server hosts OAuth2/OIDC endpoints at `/oauth2/`. Default: `true` for quickstart deployments. + Enable the embedded identity provider. When `true`, the management server hosts OAuth2/OIDC endpoints at `/oauth2/`. The issuer URL for tokens. Should be `https://your-domain/oauth2`. This URL is used to validate JWT tokens and must be accessible to clients. @@ -643,222 +678,6 @@ When `EmbeddedIdP.Enabled` is `true`, the management server automatically: - Manages device authorization at `https://your-domain/oauth2/device/authorize` - Provides user management through the Dashboard UI -### HttpConfig Section - - -**Quickstart users:** If your `management.json` contains an `EmbeddedIdP` section with `Enabled: true`, you do **not** need this section. The embedded IdP automatically configures HTTP authentication. - -**Want to connect Google, Okta, self-hosted Authentik, or any other OIDC provider?** You do not need this section. The embedded IdP supports adding external identity providers through **Settings → Identity Providers** in the Dashboard. This section is only required for the [legacy advanced deployment method](/selfhosted/selfhosted-guide) where IdP configuration is done at the infrastructure level rather than through the Dashboard UI. - - -Configures the HTTP API server and authentication. This section defines how the management server validates JWT tokens from your identity provider. - -```json -"HttpConfig": { - "Address": "0.0.0.0:33073", - "AuthIssuer": "https://netbird.example.com/oauth2", - "AuthAudience": "netbird-dashboard", - "AuthKeysLocation": "https://netbird.example.com/oauth2/keys", - "AuthUserIDClaim": "", - "CertFile": "/etc/letsencrypt/live/netbird.example.com/fullchain.pem", - "CertKey": "/etc/letsencrypt/live/netbird.example.com/privkey.pem", - "IdpSignKeyRefreshEnabled": false, - "OIDCConfigEndpoint": "https://netbird.example.com/oauth2/.well-known/openid-configuration" -} -``` - - - - Listen address for HTTP API. Format: `host:port`. Default: `0.0.0.0:33073` - - - OAuth2 token issuer URL for validation. - - - Expected audience claim in JWT tokens. - - - URL to fetch JWT signing keys (JWKS endpoint). - - - JWT claim to use as user ID. Empty uses `sub` claim. - - - Path to TLS certificate file. - - - Path to TLS certificate key file. - - - Enable automatic JWKS key refresh. Default: `false` - - - OIDC discovery endpoint URL. - - - -### IdpManagerConfig Section - - -**Quickstart users:** This section is **not required** when using the embedded IdP. The embedded IdP manages user information internally and synchronizes with external identity providers added through the Dashboard. - -**Want to connect Google, Okta, self-hosted Authentik, or any other OIDC provider?** You do not need this section. Add your external IdP through **Settings → Identity Providers** in the Dashboard - user details (names, emails, group memberships) will be synchronized automatically. - -This section is only needed for the [legacy advanced deployment method](/selfhosted/selfhosted-guide) where the embedded IdP is disabled and NetBird needs to query an external IdP's management API directly for user details. - - -Configures the Identity Provider manager for user information retrieval. When configured, NetBird uses the IdP's management API to fetch user details like display names, emails, and group memberships. - -```json -"IdpManagerConfig": { - "ManagerType": "none", - "ClientConfig": { - "Issuer": "https://netbird.example.com/oauth2", - "TokenEndpoint": "https://netbird.example.com/oauth2/token", - "ClientID": "netbird-mgmt", - "ClientSecret": "your-client-secret", - "GrantType": "client_credentials" - }, - "ExtraConfig": {} -} -``` - - - - IdP type. Options: `none`, `auth0`, `azure`, `keycloak`, `zitadel`, `google`, `okta`, `jumpcloud` - - - OAuth2 issuer URL. - - - OAuth2 token endpoint URL. - - - Client ID for machine-to-machine authentication. - - - Client secret for machine-to-machine authentication. - - - OAuth2 grant type. Usually `client_credentials`. - - - Provider-specific additional configuration. - - - -### DeviceAuthorizationFlow Section - - -**Quickstart users:** This section is **not required** when using the embedded IdP. The embedded IdP automatically handles device authorization flow at `https://your-domain/oauth2/device/authorize`. - -**Using external IdPs like Google, Okta, self-hosted Authentik, or any other OIDC provider?** If you added them through **Settings → Identity Providers** in the Dashboard, the device authorization flow works automatically - no configuration needed here. - -This section is only needed for the [legacy advanced deployment method](/selfhosted/selfhosted-guide) where the embedded IdP is disabled and you need to configure device authorization directly with an external identity provider. - - -Configures device authorization flow for CLI authentication. This flow enables users to authenticate NetBird clients via `netbird login` by visiting a URL and entering a code. It is particularly useful for headless devices or environments where browser-based login is impractical. - -```json -"DeviceAuthorizationFlow": { - "Provider": "none", - "ProviderConfig": { - "Audience": "netbird-dashboard", - "ClientID": "netbird-client", - "TokenEndpoint": "https://netbird.example.com/oauth2/token", - "DeviceAuthEndpoint": "https://netbird.example.com/oauth2/device/authorize", - "Scope": "openid", - "UseIDToken": false - } -} -``` - - - - Device auth provider. Options: `none`, `hosted`, `auth0`, `azure`, `keycloak`, `zitadel`, `okta` - - - OAuth2 audience for device tokens. - - - Client ID for device authorization. - - - Token exchange endpoint. - - - Device authorization initiation endpoint. - - - OAuth2 scopes to request. - - - Use ID token instead of access token. Default: `false` - - - -### PKCEAuthorizationFlow Section - - -**Quickstart users:** This section is **not required** when using the embedded IdP. The embedded IdP automatically handles PKCE authorization flow for desktop clients that launch a browser for authentication. - -**Using external IdPs like Google, Okta, self-hosted Authentik, or any other OIDC provider?** If you added them through **Settings → Identity Providers** in the Dashboard, PKCE authentication works automatically - no configuration needed here. - -This section is only needed for the [legacy advanced deployment method](/selfhosted/selfhosted-guide) where the embedded IdP is disabled and you need to configure PKCE flow directly with an external identity provider. - - -Configures PKCE (Proof Key for Code Exchange) authorization flow for browser-based authentication. This flow is used by desktop clients that can launch a local web server to receive the OAuth callback, providing a more seamless authentication experience than the device flow. - -```json -"PKCEAuthorizationFlow": { - "ProviderConfig": { - "Audience": "netbird-dashboard", - "ClientID": "netbird-dashboard", - "ClientSecret": "", - "AuthorizationEndpoint": "https://netbird.example.com/oauth2/authorize", - "TokenEndpoint": "https://netbird.example.com/oauth2/token", - "Scope": "openid profile email groups", - "RedirectURLs": ["http://localhost:53000"], - "UseIDToken": false, - "DisablePromptLogin": false, - "LoginFlag": 0 - } -} -``` - - - - OAuth2 audience for PKCE tokens. - - - Public client ID for PKCE flow. - - - Optional client secret. Usually empty for public clients. - - - Authorization endpoint URL. - - - Token endpoint URL. - - - OAuth2 scopes to request. - - - Allowed redirect URLs for PKCE flow. - - - Use ID token instead of access token. Default: `false` - - - Skip login prompt for returning users. Default: `false` - - - Login behavior flag. `0` = default, `1` = force login. - - - ### Other Top-Level Settings @@ -907,20 +726,20 @@ NB_STUN_PORTS=3478 | Variable | Default | Description | |----------|---------|-------------| -| `NB_LOG_LEVEL` | `info` | Log verbosity | -| `NB_LISTEN_ADDRESS` | `:80` | Listen address for relay connections | -| `NB_EXPOSED_ADDRESS` | - | Public relay address for peers | -| `NB_AUTH_SECRET` | - | Shared authentication secret | -| `NB_ENABLE_STUN` | `false` | Enable embedded STUN server | -| `NB_STUN_PORTS` | `3478` | STUN server UDP ports (comma-separated) | -| `NB_STUN_LOG_LEVEL` | `info` | STUN server log level | -| `NB_METRICS_PORT` | - | Prometheus metrics port (optional) | -| `NB_TLS_CERT_FILE` | - | TLS certificate file path | -| `NB_TLS_KEY_FILE` | - | TLS key file path | -| `NB_LETSENCRYPT_DATA_DIR` | - | Let's Encrypt data directory | -| `NB_LETSENCRYPT_DOMAINS` | - | Domains for Let's Encrypt | -| `NB_LETSENCRYPT_EMAIL` | - | Let's Encrypt email | -| `NB_HEALTH_LISTEN_ADDRESS` | - | Health check endpoint address | +| `NB_LOG_LEVEL` | `info` | Controls relay log verbosity. Use `debug` when troubleshooting connection issues to see detailed peer connection attempts and failures. | +| `NB_LISTEN_ADDRESS` | `:80` | The address and port the relay listens on inside the container. Format: `:port` or `address:port`. Usually left as `:80` since the container port is mapped externally. | +| `NB_EXPOSED_ADDRESS` | - | The public address peers use to connect to this relay. Use `rel://` for unencrypted or `rels://` for TLS. Must be reachable from all peers. | +| `NB_AUTH_SECRET` | - | Shared secret used to authenticate peers connecting to the relay. Must exactly match the `Relay.Secret` value in `management.json` or relay connections will fail. | +| `NB_ENABLE_STUN` | `false` | When `true`, the relay also runs an embedded STUN server. This eliminates the need for a separate coturn container for NAT detection. | +| `NB_STUN_PORTS` | `3478` | UDP port(s) for the embedded STUN server. Comma-separated for multiple ports. Must be exposed in `docker-compose.yml` and reachable through firewalls. | +| `NB_STUN_LOG_LEVEL` | `info` | Separate log level for the embedded STUN server. Use `debug` to troubleshoot NAT detection issues without increasing relay log verbosity. | +| `NB_METRICS_PORT` | - | Port to expose Prometheus metrics endpoint. When set, the relay exposes metrics at `/metrics` for monitoring connection counts and performance. | +| `NB_TLS_CERT_FILE` | - | Path to TLS certificate file for relay-terminated HTTPS. Only needed when the relay handles TLS directly instead of using a reverse proxy. | +| `NB_TLS_KEY_FILE` | - | Path to TLS private key file. Must be provided together with `NB_TLS_CERT_FILE` for direct TLS termination. | +| `NB_LETSENCRYPT_DATA_DIR` | - | Directory to store Let's Encrypt certificates when the relay obtains certificates automatically. Not needed when using an external reverse proxy for TLS. | +| `NB_LETSENCRYPT_DOMAINS` | - | Comma-separated domains for automatic Let's Encrypt certificate provisioning. The relay must be reachable on port 443 for ACME challenges. | +| `NB_LETSENCRYPT_EMAIL` | - | Email address for Let's Encrypt registration. Required for certificate expiry notifications if using automatic provisioning. | +| `NB_HEALTH_LISTEN_ADDRESS` | - | Address for health check endpoint (e.g., `:8080`). When set, exposes `/health` for container orchestration and load balancer health probes. | --- @@ -928,6 +747,24 @@ NB_STUN_PORTS=3478 Environment configuration for the dashboard service. +### Dashboard Architecture + +The NetBird dashboard container includes an **embedded nginx server** that serves the dashboard web pages. This nginx instance is built into the container image and handles serving the static web UI files. + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ Dashboard Container │ +│ ┌──────────────────────────────────────────────────────────┐ │ +│ │ Embedded Nginx │ │ +│ │ - Serves dashboard web UI │ │ +│ │ - Can handle SSL/TLS termination (standalone mode) │ │ +│ │ - Configurable via NGINX_* environment variables │ │ +│ └──────────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +The `NGINX_SSL_PORT` and other `NGINX_*` environment variables control this embedded nginx server, not an external reverse proxy. + ```bash # Endpoints NETBIRD_MGMT_API_ENDPOINT=https://netbird.example.com @@ -943,41 +780,57 @@ AUTH_SUPPORTED_SCOPES=openid profile email groups AUTH_REDIRECT_URI=/nb-auth AUTH_SILENT_REDIRECT_URI=/nb-silent-auth -# SSL +# SSL - disabled when behind reverse proxy (Caddy handles TLS) NGINX_SSL_PORT=443 - -# Letsencrypt -LETSENCRYPT_DOMAIN=netbird.example.com -LETSENCRYPT_EMAIL=admin@example.com +LETSENCRYPT_DOMAIN=none ``` + +When using the built-in Caddy or an external reverse proxy, set `LETSENCRYPT_DOMAIN=none` because the reverse proxy handles TLS termination. Only set a domain here if running the dashboard standalone without a reverse proxy. + + ### Endpoint Configuration | Variable | Description | |----------|-------------| -| `NETBIRD_MGMT_API_ENDPOINT` | Management REST API endpoint URL | -| `NETBIRD_MGMT_GRPC_API_ENDPOINT` | Management gRPC endpoint URL | +| `NETBIRD_MGMT_API_ENDPOINT` | The URL where the dashboard makes REST API calls to the management server (e.g., `https://netbird.example.com`). Must be accessible from users' browsers since API calls are made client-side. | +| `NETBIRD_MGMT_GRPC_API_ENDPOINT` | The URL for gRPC communication with the management server. Usually the same as the REST endpoint. Used for real-time updates and streaming data to the dashboard. | ### Authentication Configuration | Variable | Description | |----------|-------------| -| `AUTH_AUDIENCE` | OAuth2 audience claim | -| `AUTH_CLIENT_ID` | OAuth2 client ID | -| `AUTH_CLIENT_SECRET` | OAuth2 client secret (empty for public clients) | -| `AUTH_AUTHORITY` | OAuth2 issuer URL | -| `USE_AUTH0` | Set to `true` when using Auth0 | -| `AUTH_SUPPORTED_SCOPES` | Space-separated OAuth2 scopes | -| `AUTH_REDIRECT_URI` | OAuth2 redirect path | -| `AUTH_SILENT_REDIRECT_URI` | Silent auth redirect path | +| `AUTH_AUDIENCE` | The expected audience claim in OAuth2 tokens. Must match the audience configured in your IdP. For embedded IdP, use `netbird-dashboard`. Incorrect values cause authentication failures. | +| `AUTH_CLIENT_ID` | The OAuth2 client identifier for the dashboard application. For embedded IdP deployments, this is `netbird-dashboard`. Must match the client ID registered with your identity provider. | +| `AUTH_CLIENT_SECRET` | OAuth2 client secret for confidential clients. Leave empty for public clients (the default for browser-based apps like the dashboard). Only set this if your IdP requires a confidential client. | +| `AUTH_AUTHORITY` | The OAuth2/OIDC issuer URL (e.g., `https://netbird.example.com/oauth2` for embedded IdP). The dashboard fetches OIDC discovery metadata from `{AUTH_AUTHORITY}/.well-known/openid-configuration`. | +| `USE_AUTH0` | Set to `true` only when using Auth0 as your identity provider. Enables Auth0-specific authentication behavior. Leave as `false` for embedded IdP or other OIDC providers. | +| `AUTH_SUPPORTED_SCOPES` | Space-separated list of OAuth2 scopes to request during login. Standard value is `openid profile email groups`. The `groups` scope enables group-based access control if supported by your IdP. | +| `AUTH_REDIRECT_URI` | The path where the IdP redirects after authentication (e.g., `/nb-auth`). Must match a redirect URI registered with your identity provider. Incorrect values cause OAuth2 callback errors. | +| `AUTH_SILENT_REDIRECT_URI` | The path for silent token refresh (e.g., `/nb-silent-auth`). Used by the dashboard to refresh tokens in the background without user interaction. Must also be registered with your IdP. | -### SSL/TLS Configuration +### Embedded Nginx Configuration + +The dashboard container's embedded nginx server can be configured using these environment variables. These settings control how the dashboard serves its web UI. | Variable | Default | Description | |----------|---------|-------------| -| `NGINX_SSL_PORT` | `443` | HTTPS port | -| `LETSENCRYPT_DOMAIN` | - | Domain for Let's Encrypt (set to `none` to disable) | -| `LETSENCRYPT_EMAIL` | - | Email for Let's Encrypt | +| `NGINX_SSL_PORT` | `443` | The HTTPS port for the dashboard's embedded nginx server. Only relevant in standalone mode without an external reverse proxy. When behind a reverse proxy, the dashboard serves HTTP internally. | +| `LETSENCRYPT_DOMAIN` | - | The domain name for automatic Let's Encrypt certificate provisioning. Set to `none` when using an external reverse proxy that handles TLS. The domain must resolve to this server for ACME challenges to succeed. | +| `LETSENCRYPT_EMAIL` | - | Email address for Let's Encrypt account registration and certificate expiry notifications. Required when `LETSENCRYPT_DOMAIN` is set. Let's Encrypt sends renewal reminders to this address. | + + +**When do you need these nginx variables?** + +The `NGINX_SSL_PORT` and Let's Encrypt variables are **only necessary when running the dashboard standalone** without an external reverse proxy. In standalone mode, the dashboard's embedded nginx handles SSL/TLS termination directly. + +**For most installations** that use the built-in Caddy reverse proxy (the default `getting-started.sh` deployment) or an external reverse proxy like Traefik or Nginx, **you do not need to configure these nginx variables**. The reverse proxy handles SSL termination and routes traffic to the dashboard container, which serves content over HTTP internally. + +When behind a reverse proxy: +- Set `LETSENCRYPT_DOMAIN=none` to disable the dashboard's internal Let's Encrypt +- The embedded nginx will serve on HTTP (port 80) internally +- Your reverse proxy handles HTTPS and forwards requests to the dashboard + --- @@ -1010,7 +863,7 @@ In `docker-compose.yml`, update the management command: ```yaml management: command: [ - "--port", "443", + "--port", "80", "--disable-anonymous-metrics=true", # ... other flags ] @@ -1023,15 +876,15 @@ To use multiple relay servers, update `management.json`: ```json "Relay": { "Addresses": [ - "rel://relay1.example.com:33080", - "rel://relay2.example.com:33080" + "rels://relay1.example.com:443", + "rels://relay2.example.com:443" ], "CredentialsTTL": "24h", "Secret": "shared-secret" } ``` -Each relay server must use the same `NB_AUTH_SECRET`. +Each relay server must use the same `NB_AUTH_SECRET`. Use `rels://` for TLS (port 443) or `rel://` for unencrypted (port 80). ### Behind a Reverse Proxy diff --git a/src/pages/selfhosted/selfhosted-quickstart.mdx b/src/pages/selfhosted/selfhosted-quickstart.mdx index 35bb17da..4396a819 100644 --- a/src/pages/selfhosted/selfhosted-quickstart.mdx +++ b/src/pages/selfhosted/selfhosted-quickstart.mdx @@ -30,7 +30,8 @@ Download and run the installation script: curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh | bash ``` -Once finished, you can manage the resources via `docker compose`. +Once finished, you can manage the resources via `docker compose`. The quick start script generates a full, production-ready NetBird installtion. If you'd customize the install or gain a better understanding of the files +generated by the script, including the docker compose file, please refer to our [Configuration files](/selfhosted/configuration-files) guide. ### Reverse Proxy Selection From 84b8776581f85f86b584daaaf365430bef0e93d1 Mon Sep 17 00:00:00 2001 From: Ashley Mensah Date: Thu, 22 Jan 2026 10:19:14 +0100 Subject: [PATCH 4/7] clarified endpoint protocols --- src/pages/selfhosted/configuration-files.mdx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pages/selfhosted/configuration-files.mdx b/src/pages/selfhosted/configuration-files.mdx index ef764ef1..19a81c46 100644 --- a/src/pages/selfhosted/configuration-files.mdx +++ b/src/pages/selfhosted/configuration-files.mdx @@ -46,7 +46,7 @@ The Docker Compose file defines all NetBird services, their dependencies, networ |---------|-------|---------------|-------------------|-------------| | `dashboard` | `netbirdio/dashboard` | 80 | 8080:80 | The web-based management console where administrators configure networks, manage peers, create access policies, and view activity logs. Includes an embedded nginx server for serving the UI. | | `management` | `netbirdio/management` | 80 | 8081:80 | The central control plane that handles peer registration, distributes network configurations, manages access policies, and hosts the embedded identity provider. All peers connect to this service on startup. | -| `signal` | `netbirdio/signal` | 80, 10000 | 8083:80, 10000:10000 | Facilitates WebRTC signaling so peers can exchange connection offers and establish direct WireGuard tunnels. Handles only connection setup metadata, not actual traffic. Port 80 is for modern HTTP/2 connections; port 10000 is for legacy gRPC (see note below). | +| `signal` | `netbirdio/signal` | 80, 10000 | 8083:80, 10000:10000 | Rendezvous service that facilitates peer connections by enabling peers to exchange connection offers and establish direct WireGuard tunnels. Handles only connection setup metadata, not actual traffic. Port 80 is for modern HTTP/2 connections; port 10000 is for legacy gRPC (see note below). | | `relay` | `netbirdio/relay` | 80, 3478/udp | 8084:80, 3478:3478/udp | Routes encrypted traffic between peers when direct connections fail due to restrictive NATs or firewalls. Also provides embedded STUN on UDP 3478 for NAT type detection. | | `caddy` | `caddy` | 80, 443 | 80:80, 443:443 | Handles TLS termination and routes incoming HTTPS requests to the appropriate NetBird services. Only included in default `getting-started.sh` deployments; can be replaced with your own reverse proxy. | @@ -194,7 +194,7 @@ To use an external database, add environment variables: ### Signal Service -The signal service handles WebRTC signaling for establishing peer-to-peer connections. +The signal service acts as a rendezvous service for facilitating peer-to-peer connections. It enables peers to discover each other and exchange connection information needed to establish direct WireGuard tunnels. The service supports HTTP/2 for modern clients and gRPC for legacy compatibility. **With built-in Caddy (default):** ```yaml @@ -534,11 +534,12 @@ Configures the connection to the Signal service for peer-to-peer connection esta **What does the signal service do?** -The signal service facilitates WebRTC signaling between NetBird peers. When two peers want to establish a direct connection, they exchange connection offers, answers, and ICE candidates through the signal server. This coordination enables peers to discover each other and negotiate the optimal connection path. +The signal service acts as a rendezvous service that facilitates peer connections. When two peers want to establish a direct connection, they exchange connection offers, answers, and network candidates through the signal server. This coordination enables peers to discover each other and negotiate the optimal connection path. -- **Connection coordination** - Peers exchange network information to establish direct WireGuard tunnels +- **Rendezvous service** - Enables peers to find each other and exchange the information needed to establish direct WireGuard tunnels - **No traffic routing** - Unlike the relay, the signal server only handles connection setup metadata, not actual traffic - **Persistent connections** - Peers maintain a connection to the signal server to receive incoming connection requests +- **Protocol support** - Modern clients use HTTP/2 (port 443/80 via reverse proxy); legacy clients use gRPC (port 10000) ```json "Signal": { From a261d68e1259b403f0442606effe09dbe3bc2b9e Mon Sep 17 00:00:00 2001 From: Ashley Mensah Date: Thu, 22 Jan 2026 15:06:59 +0100 Subject: [PATCH 5/7] suggested amendments from review --- src/pages/selfhosted/configuration-files.mdx | 104 ++----------------- 1 file changed, 9 insertions(+), 95 deletions(-) diff --git a/src/pages/selfhosted/configuration-files.mdx b/src/pages/selfhosted/configuration-files.mdx index 19a81c46..9302a834 100644 --- a/src/pages/selfhosted/configuration-files.mdx +++ b/src/pages/selfhosted/configuration-files.mdx @@ -46,7 +46,7 @@ The Docker Compose file defines all NetBird services, their dependencies, networ |---------|-------|---------------|-------------------|-------------| | `dashboard` | `netbirdio/dashboard` | 80 | 8080:80 | The web-based management console where administrators configure networks, manage peers, create access policies, and view activity logs. Includes an embedded nginx server for serving the UI. | | `management` | `netbirdio/management` | 80 | 8081:80 | The central control plane that handles peer registration, distributes network configurations, manages access policies, and hosts the embedded identity provider. All peers connect to this service on startup. | -| `signal` | `netbirdio/signal` | 80, 10000 | 8083:80, 10000:10000 | Rendezvous service that facilitates peer connections by enabling peers to exchange connection offers and establish direct WireGuard tunnels. Handles only connection setup metadata, not actual traffic. Port 80 is for modern HTTP/2 connections; port 10000 is for legacy gRPC (see note below). | +| `signal` | `netbirdio/signal` | 80 | 8083:80 | Rendezvous service that facilitates peer connections by enabling peers to exchange connection offers and establish direct WireGuard tunnels. Handles only connection setup metadata, not actual traffic. Uses HTTP/2 protocol via the reverse proxy. | | `relay` | `netbirdio/relay` | 80, 3478/udp | 8084:80, 3478:3478/udp | Routes encrypted traffic between peers when direct connections fail due to restrictive NATs or firewalls. Also provides embedded STUN on UDP 3478 for NAT type detection. | | `caddy` | `caddy` | 80, 443 | 80:80, 443:443 | Handles TLS termination and routes incoming HTTPS requests to the appropriate NetBird services. Only included in default `getting-started.sh` deployments; can be replaced with your own reverse proxy. | @@ -111,7 +111,7 @@ dashboard: ``` -The dashboard service is configured via the `dashboard.env` file. See the [dashboard.env section](#dashboardenv) for the full list of environment variables. When using the built-in Caddy, no ports are exposed directly from the dashboard container; Caddy routes traffic to it internally. +The dashboard service is configured via the `dashboard.env` file. See the [dashboard.env section](#dashboard-env) for the full list of environment variables. When using the built-in Caddy, no ports are exposed directly from the dashboard container; Caddy routes traffic to it internally. ### Management Service @@ -194,7 +194,7 @@ To use an external database, add environment variables: ### Signal Service -The signal service acts as a rendezvous service for facilitating peer-to-peer connections. It enables peers to discover each other and exchange connection information needed to establish direct WireGuard tunnels. The service supports HTTP/2 for modern clients and gRPC for legacy compatibility. +The signal service acts as a rendezvous service for facilitating peer-to-peer connections. It enables peers to discover each other and exchange connection information needed to establish direct WireGuard tunnels. **With built-in Caddy (default):** ```yaml @@ -219,7 +219,6 @@ signal: networks: [netbird] ports: - '127.0.0.1:8083:80' - - '127.0.0.1:10000:10000' logging: driver: "json-file" options: @@ -227,28 +226,13 @@ signal: max-file: "2" ``` -#### Signal Service Ports - -The signal service exposes two ports with different purposes: - -| Port | Protocol | Purpose | Clients | -|------|----------|---------|---------| -| 80 | HTTP/2 (h2c) | Modern signal connections via reverse proxy | NetBird v0.10.0+ (July 2022 and later) | -| 10000 | gRPC | Legacy backward compatibility server | NetBird clients older than v0.10.0 | - -**About port 10000 (Legacy gRPC):** Starting with NetBird v0.10.0, the signal service moved to standard HTTP ports (443/80) with HTTP/2 support, allowing connections through reverse proxies. Port 10000 is maintained as a **backward compatibility server** for older clients that still use the original gRPC protocol. - -**When can you close port 10000?** If all your NetBird clients are running v0.10.0 or later (released July 2022), you can safely remove the port 10000 mapping from your `docker-compose.yml`. Modern clients connect via the reverse proxy on ports 443/80 using HTTP/2. However, if you have any older clients or are unsure, keep port 10000 open to ensure connectivity. - - - -When using the built-in Caddy reverse proxy, port 10000 is not exposed externally by default since Caddy routes modern signal traffic internally. If you need to support legacy clients with the built-in Caddy deployment, you would need to add the port mapping manually. +The signal service listens on port 80 internally and uses HTTP/2 protocol. The reverse proxy (Caddy or your own) handles TLS termination and routes signal traffic to this service. ### Relay Service -The relay service provides NAT traversal when direct peer-to-peer connections are not possible. It also includes an embedded STUN server for NAT detection and traversal. +The relay service is a public service that forwards packets when direct peer-to-peer connections are not possible. It also includes an embedded STUN server for NAT detection and traversal. **With built-in Caddy (default):** ```yaml @@ -291,7 +275,7 @@ relay: The STUN port (3478/udp) must always be exposed publicly, regardless of reverse proxy configuration. STUN uses UDP for NAT detection and cannot be proxied through HTTP reverse proxies. -The relay service is configured via the `relay.env` file. See the [relay.env section](#relayenv) for detailed configuration options. +The relay service is configured via the `relay.env` file. See the [relay.env section](#relay-env) for detailed configuration options. @@ -346,21 +330,7 @@ The management configuration file controls the core behavior of the NetBird Mana ### About the Embedded IdP The `getting-started.sh` deployment uses NetBird's **embedded identity provider (IdP)**, which is based on DEX. This is the standard, recommended approach that handles authentication automatically. - -**You CAN connect external identity providers with the embedded IdP:** -- **Google Workspace** - Use Google accounts for authentication -- **Microsoft Entra ID (Azure AD)** - Integrate with Microsoft 365 organizations -- **Okta** - Connect your Okta workforce identity -- **Self-hosted Authentik** - Use your own Authentik instance for authentication -- **Any OIDC provider** - Any provider supporting OpenID Connect works with NetBird - -**How to add external IdPs:** -1. Go to **Settings → Identity Providers** in the NetBird Dashboard -2. Click **Add Identity Provider** -3. Follow the guided setup for your chosen provider -4. Users can then authenticate using their existing corporate credentials - -This Dashboard-based configuration is simpler, more maintainable, and does not require editing `management.json`. +This Dashboard-based configuration is simpler, more maintainable, and does not require editing `management.json`. To configure your external IdP with this method, please refer to our [identity provider documentation](/selfhosted/identity-providers). If you need to configure identity providers at the infrastructure level (directly in configuration files rather than through the Dashboard), see the [Advanced Self-hosting Guide](/selfhosted/selfhosted-guide). @@ -376,9 +346,6 @@ The `management.json` file for `getting-started.sh` deployments uses these secti | `Relay` | Yes | Configures relay server addresses and authentication. Peers use relay servers when direct connections fail. The secret here must match `NB_AUTH_SECRET` in `relay.env`. | | `Signal` | Yes | Specifies how the management server connects to the signal service. Peers receive this address and use it to exchange connection offers with other peers. | | `EmbeddedIdP` | Yes | Enables and configures the built-in identity provider (based on DEX). Handles user authentication, token issuance, and OIDC endpoints. Required for `getting-started.sh` deployments. | -| `ReverseProxy` | No | Defines trusted proxy IP ranges for accurate client IP detection. Configure this when running behind a load balancer or reverse proxy to ensure correct IP logging and rate limiting. | -| `StoreConfig` | No | Specifies the database engine (SQLite, PostgreSQL, or MySQL). Defaults to SQLite. Use PostgreSQL for production deployments requiring high availability or concurrent access. | -| `TURNConfig` | No | Legacy configuration for external TURN servers like coturn. Not used in standard deployments since the relay service handles NAT traversal. Only needed for advanced scenarios. | ### Complete Structure @@ -437,57 +404,6 @@ The embedded STUN server in the relay service (enabled via `NB_ENABLE_STUN=true` -### TURNConfig Section (Legacy) - - -The `TURNConfig` section is a **legacy configuration** for deployments using external TURN servers (such as coturn). The `getting-started.sh` deployment uses the **Relay service** instead, which provides similar NAT traversal functionality with simpler configuration. This section is not included in standard `getting-started.sh` deployments. - - -If you have an existing deployment using TURN servers or need specific TURN features (such as TCP relay or time-based credentials), you can configure them here: - -```json -"TURNConfig": { - "Turns": [ - { - "Proto": "udp", - "URI": "turn:netbird.example.com:3478", - "Username": "netbird", - "Password": "your-turn-password" - } - ], - "CredentialsTTL": "12h", - "Secret": "secret", - "TimeBasedCredentials": false -} -``` - - - - Array of TURN server configurations. - - - Protocol: `udp`, `tcp`, or `tls`. Default: `udp` - - - TURN server URI. Format: `turn:hostname:port` or `turns:hostname:port` for TLS. - - - TURN authentication username. - - - TURN authentication password. - - - Time-to-live for TURN credentials. Format: Go duration (e.g., `12h`, `30m`). Default: `12h` - - - Shared secret for time-based credentials (when enabled). - - - Enable time-based TURN credentials. Default: `false` - - - ### Relay Section Configures the NetBird relay server connection for NAT traversal. @@ -539,7 +455,7 @@ The signal service acts as a rendezvous service that facilitates peer connection - **Rendezvous service** - Enables peers to find each other and exchange the information needed to establish direct WireGuard tunnels - **No traffic routing** - Unlike the relay, the signal server only handles connection setup metadata, not actual traffic - **Persistent connections** - Peers maintain a connection to the signal server to receive incoming connection requests -- **Protocol support** - Modern clients use HTTP/2 (port 443/80 via reverse proxy); legacy clients use gRPC (port 10000) +- **HTTP/2 protocol** - Clients connect via the reverse proxy on port 443 (HTTPS) or 80 (HTTP) ```json "Signal": { @@ -795,7 +711,7 @@ When using the built-in Caddy or an external reverse proxy, set `LETSENCRYPT_DOM | Variable | Description | |----------|-------------| | `NETBIRD_MGMT_API_ENDPOINT` | The URL where the dashboard makes REST API calls to the management server (e.g., `https://netbird.example.com`). Must be accessible from users' browsers since API calls are made client-side. | -| `NETBIRD_MGMT_GRPC_API_ENDPOINT` | The URL for gRPC communication with the management server. Usually the same as the REST endpoint. Used for real-time updates and streaming data to the dashboard. | +| `NETBIRD_MGMT_GRPC_API_ENDPOINT` | The URL for gRPC communication with the management server. Usually the same as the REST endpoint. Used for in-browser SSH and RDP clients, as well as surfacing management links for client config instructions. | ### Authentication Configuration @@ -937,8 +853,6 @@ To use external TURN servers (e.g., coturn deployed separately): ## See Also - [Self-hosting Quickstart Guide](/selfhosted/selfhosted-quickstart) - Get started quickly with default settings -- [Advanced Self-hosting Guide](/selfhosted/selfhosted-guide) - Custom IdP integration -- [Environment Variables](/selfhosted/environment-variables) - Runtime environment configuration - [Reverse Proxy Configuration](/selfhosted/reverse-proxy) - Traefik, Nginx, Caddy setup - [Management SQLite Store](/selfhosted/sqlite-store) - SQLite database details - [Management Postgres Store](/selfhosted/postgres-store) - PostgreSQL setup From 5095398e7953d9d21aa98d772d5c66d9ba45c859 Mon Sep 17 00:00:00 2001 From: braginini Date: Thu, 22 Jan 2026 15:57:14 +0100 Subject: [PATCH 6/7] Change authentication notes --- src/pages/selfhosted/configuration-files.mdx | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/pages/selfhosted/configuration-files.mdx b/src/pages/selfhosted/configuration-files.mdx index 9302a834..2457f91d 100644 --- a/src/pages/selfhosted/configuration-files.mdx +++ b/src/pages/selfhosted/configuration-files.mdx @@ -1,7 +1,7 @@ import {Note, Warning} from "@/components/mdx"; import {Properties, Property} from "@/components/mdx"; -# Configuration Files Reference +# Self-Hosted Deployment Configuration Files Reference This page provides a comprehensive reference for all configuration files used when self-hosting NetBird with the `getting-started.sh` deployment method. Understanding these files helps you customize your deployment, troubleshoot issues, and integrate with existing infrastructure. @@ -327,14 +327,11 @@ The `getting-started.sh` deployment uses only two volumes: `netbird_management` The management configuration file controls the core behavior of the NetBird Management service. This is the most complex configuration file. -### About the Embedded IdP +### Authentication -The `getting-started.sh` deployment uses NetBird's **embedded identity provider (IdP)**, which is based on DEX. This is the standard, recommended approach that handles authentication automatically. -This Dashboard-based configuration is simpler, more maintainable, and does not require editing `management.json`. To configure your external IdP with this method, please refer to our [identity provider documentation](/selfhosted/identity-providers). - - -If you need to configure identity providers at the infrastructure level (directly in configuration files rather than through the Dashboard), see the [Advanced Self-hosting Guide](/selfhosted/selfhosted-guide). - +NetBird comes with built-in local user management and also supports integration with any OIDC-compatible identity provider. +This enables Single Sign-On (SSO), Multi-Factor Authentication (MFA), and centralized user management. +For setup instructions, see the [Authentication & IdPs page](/selfhosted/identity-providers) for configuration details. ### Configuration Sections From 9ff2647a456d8fd86e3d26babb25f9c6ff73f14d Mon Sep 17 00:00:00 2001 From: braginini Date: Thu, 22 Jan 2026 16:36:49 +0100 Subject: [PATCH 7/7] Fix codespell --- src/pages/selfhosted/selfhosted-quickstart.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/selfhosted/selfhosted-quickstart.mdx b/src/pages/selfhosted/selfhosted-quickstart.mdx index 4396a819..649e99b3 100644 --- a/src/pages/selfhosted/selfhosted-quickstart.mdx +++ b/src/pages/selfhosted/selfhosted-quickstart.mdx @@ -30,7 +30,7 @@ Download and run the installation script: curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh | bash ``` -Once finished, you can manage the resources via `docker compose`. The quick start script generates a full, production-ready NetBird installtion. If you'd customize the install or gain a better understanding of the files +Once finished, you can manage the resources via `docker compose`. The quick start script generates a full, production-ready NetBird installation. If you'd like to customize the install or gain a better understanding of the files generated by the script, including the docker compose file, please refer to our [Configuration files](/selfhosted/configuration-files) guide. ### Reverse Proxy Selection