# Netbird Self-Hosted VPN - Zero Trust Network Access # Full deployment: management, signal, relay, dashboard # Chart: netbird/netbird (https://netbirdio.github.io/helms) # Ensure service names are netbird-{component} (not netbird-netbird-{component}) fullnameOverride: netbird management: enabled: true securityContext: capabilities: drop: - ALL resources: limits: memory: 256Mi requests: cpu: 25m memory: 128Mi persistentVolume: enabled: true size: 100Mi storageClass: rook-ceph-block # Management server config (management.json) # Uses Authentik as external OIDC provider for SSO image: tag: 0.66.0 configmap: |- { "Stuns": [ { "Proto": "udp", "URI": "stun:stun.l.google.com:19302" } ], "Relay": { "Addresses": ["rels://netbird.kube.huskypup.net:443"], "CredentialsTTL": "24h", "Secret": "zATjQ+YwNLvSBPD04R2+z7WzUhrwG1rkH3b/4Xsjvz0=" }, "Signal": { "Proto": "https", "URI": "netbird.kube.huskypup.net:443", "AuthenticationEnabled": false }, "Datadir": "/var/lib/netbird/", "HttpConfig": { "AuthIssuer": "https://auth.kube.huskypup.net/application/o/netbird/", "AuthAudience": "{{.NETBIRD_AUTH_AUDIENCE}}", "AuthKeysLocation": "https://auth.kube.huskypup.net/application/o/netbird/jwks/", "OIDCConfigEndpoint": "https://auth.kube.huskypup.net/application/o/netbird/.well-known/openid-configuration", "IdpSignKeyRefreshEnabled": false, "AuthUserIDClaim": "sub", "GroupsClaimName": "groups" }, "IdpManagerConfig": { "ManagerType": "authentik", "ClientConfig": { "Issuer": "https://auth.kube.huskypup.net/application/o/netbird/", "TokenEndpoint": "https://auth.kube.huskypup.net/application/o/token/", "ClientID": "{{.NETBIRD_IDP_MGMT_CLIENT_ID}}", "GrantType": "client_credentials" }, "ExtraConfig": { "Username": "{{.NETBIRD_IDP_MANAGER_EXTRA_CONFIG_USERNAME}}", "Password": "{{.NETBIRD_IDP_MANAGER_EXTRA_CONFIG_PASSWORD}}" } }, "DeviceAuthorizationFlow": { "Provider": "hosted", "ProviderConfig": { "Audience": "{{.NETBIRD_AUTH_AUDIENCE}}", "ClientID": "{{.NETBIRD_AUTH_AUDIENCE}}", "ClientSecret": "", "Domain": "auth.kube.huskypup.net", "TokenEndpoint": "https://auth.kube.huskypup.net/application/o/token/", "DeviceAuthEndpoint": "https://auth.kube.huskypup.net/application/o/device/", "AuthorizationEndpoint": "https://auth.kube.huskypup.net/application/o/authorize/", "Scope": "openid profile email offline_access goauthentik.io/api", "UseIDToken": false, "RedirectURLs": [ "http://localhost:53000", "netbird://auth" ] } }, "PKCEAuthorizationFlow": { "ProviderConfig": { "Audience": "{{.NETBIRD_AUTH_AUDIENCE}}", "ClientID": "{{.NETBIRD_AUTH_AUDIENCE}}", "ClientSecret": "", "TokenEndpoint": "https://auth.kube.huskypup.net/application/o/token/", "DeviceAuthEndpoint": "https://auth.kube.huskypup.net/application/o/device/", "AuthorizationEndpoint": "https://auth.kube.huskypup.net/application/o/authorize/", "Scope": "openid profile email offline_access goauthentik.io/api", "UseIDToken": false, "RedirectURLs": [ "http://localhost:53000" ] } }, "StoreConfig": { "Engine": "postgres" }, "DataStoreEncryptionKey": "X3qwIBAfV5UjYCbPmat0jLSLYAnCOMtLdXdgV34UWMM=", "EncryptionKey": "X3qwIBAfV5UjYCbPmat0jLSLYAnCOMtLdXdgV34UWMM=" } # Simple key-value env vars (override management.json values) env: NETBIRD_STORE_ENGINE: postgres NETBIRD_DOMAIN: netbird.kube.huskypup.net NETBIRD_MGMT_API_ENDPOINT: "https://netbird.kube.huskypup.net:443" NETBIRD_ENCRYPTION_KEY: "X3qwIBAfV5UjYCbPmat0jLSLYAnCOMtLdXdgV34UWMM=" NB_METRICS_PORT: "9090" # OIDC scopes and redirect URIs NETBIRD_AUTH_SUPPORTED_SCOPES: "openid profile email offline_access goauthentik.io/api" NETBIRD_AUTH_REDIRECT_URI: "/auth" NETBIRD_AUTH_SILENT_REDIRECT_URI: "/silent-auth" NETBIRD_AUTH_PKCE_DISABLE_PROMPT_LOGIN: "true" # Complex env vars (valueFrom references) envRaw: - name: NETBIRD_STORE_ENGINE_POSTGRES_DSN valueFrom: secretKeyRef: name: pg-netbird-app key: uri - name: NETBIRD_AUTH_AUDIENCE valueFrom: secretKeyRef: name: netbird-oauth-secret key: client-id - name: NETBIRD_IDP_MGMT_CLIENT_ID valueFrom: secretKeyRef: name: netbird-oauth-secret key: client-id - name: NETBIRD_IDP_MANAGER_EXTRA_CONFIG_USERNAME valueFrom: secretKeyRef: name: netbird-oauth-secret key: service-username - name: NETBIRD_IDP_MANAGER_EXTRA_CONFIG_PASSWORD valueFrom: secretKeyRef: name: netbird-oauth-secret key: service-password ingress: enabled: false signal: enabled: true securityContext: capabilities: drop: - ALL resources: limits: memory: 128Mi requests: cpu: 25m memory: 64Mi env: NB_METRICS_PORT: "9090" ingress: enabled: false dashboard: enabled: true image: tag: v2.33.0 resources: limits: memory: 128Mi requests: cpu: 10m memory: 64Mi # Fix envsubst bug: USE_AUTH0="false" becomes JS string "false" (truthy). # The template wraps $$USE_AUTH0 in quotes, so "false" !== false in JS. # This causes @axa-fr/react-oidc to use Auth0-specific endpoint paths # instead of fetching from .well-known/openid-configuration. # postStart waits for init_react_envs.sh to finish, then patches the JS. lifecycle: postStart: exec: command: - /bin/sh - -c - | sleep 3 # Fix auth0Auth: envsubst wraps "false" in quotes → JS truthy string. # Must be boolean false for @axa-fr/react-oidc to use OIDC discovery. find /usr/share/nginx/html -name '*.js' -exec sed -i 's/auth0Auth:"false"/auth0Auth:false/g' {} + # Fix nginx try_files: SPA fallback to /index.html instead of =404. # Next.js App Router RSC fetches .txt files; the default =404 breaks navigation. sed -i 's|try_files $uri $uri.html $uri/ =404|try_files $uri $uri.html $uri/ /index.html|' /etc/nginx/http.d/default.conf nginx -s reload # Simple key-value env vars env: USE_AUTH0: "false" NETBIRD_MGMT_API_ENDPOINT: "https://netbird.kube.huskypup.net:443" NETBIRD_MGMT_GRPC_API_ENDPOINT: "https://netbird.kube.huskypup.net:443" NETBIRD_TOKEN_SOURCE: "accessToken" # Authentik OIDC (trailing slash must match issuer in OIDC discovery) AUTH_AUTHORITY: "https://auth.kube.huskypup.net/application/o/netbird/" AUTH_SUPPORTED_SCOPES: "openid profile email offline_access goauthentik.io/api" AUTH_REDIRECT_URI: "/auth" AUTH_SILENT_REDIRECT_URI: "/silent-auth" # Complex env vars (valueFrom references) envRaw: - name: AUTH_CLIENT_ID valueFrom: secretKeyRef: name: netbird-oauth-secret key: client-id - name: AUTH_AUDIENCE valueFrom: secretKeyRef: name: netbird-oauth-secret key: client-id # Mount corrected OidcTrustedDomains.js.tmpl that includes AUTH_AUTHORITY # Default template only trusts NETBIRD_MGMT_API_ENDPOINT; @axa-fr/react-oidc # needs the OIDC authority domain to allow discovery/token/userinfo fetches volumes: - name: oidc-trusted-domains configMap: name: netbird-oidc-trusted-domains volumeMounts: - name: oidc-trusted-domains mountPath: /usr/share/nginx/html/OidcTrustedDomains.js.tmpl subPath: OidcTrustedDomains.js.tmpl ingress: enabled: false # Relay (TURN) for NAT traversal relay: enabled: true securityContext: capabilities: drop: - ALL image: tag: 0.66.0 resources: limits: memory: 256Mi requests: cpu: 50m memory: 64Mi env: NB_LISTEN_ADDRESS: ":33080" NB_EXPOSED_ADDRESS: "rels://netbird.kube.huskypup.net:443" NB_AUTH_SECRET: "zATjQ+YwNLvSBPD04R2+z7WzUhrwG1rkH3b/4Xsjvz0=" NB_LOG_LEVEL: info NB_METRICS_PORT: "9090"