From f9e66ff1a0b5c3e7e96f72cff731c6535bed8e18 Mon Sep 17 00:00:00 2001 From: Nathan Date: Sun, 1 Feb 2026 06:48:12 -0600 Subject: [PATCH] dockerfy netbird --- .../docker/netbird/config/management.json | 27 +++ .../virtualization/docker/netbird/default.nix | 225 ++++++++++++++++-- 2 files changed, 234 insertions(+), 18 deletions(-) create mode 100644 system/virtualization/docker/netbird/config/management.json diff --git a/system/virtualization/docker/netbird/config/management.json b/system/virtualization/docker/netbird/config/management.json new file mode 100644 index 0000000..0ae2ef9 --- /dev/null +++ b/system/virtualization/docker/netbird/config/management.json @@ -0,0 +1,27 @@ +{ + "Stuns": [ + { + "Proto": "udp", + "URI": "stun:vpn.esotericbytes.com:3478" + } + ], + "Relay": { + "Addresses": ["rels://vpn.esotericbytes.com:443"], + "CredentialsTTL": "24h", + "Secret": "0qSIu/S2sXHJbo0SyBNm4SFxAItRoPLKR4wjnW/Zsgc" + }, + "Signal": { + "Proto": "https", + "URI": "vpn.esotericbytes.com:443" + }, + "Datadir": "/var/lib/netbird", + "DataStoreEncryptionKey": "FZnQt+JqAC8GEXUSJwhrgo0vn4PoDetoAhjUx9nSJR0=", + "EmbeddedIdP": { + "Enabled": true, + "Issuer": "https://vpn.esotericbytes.com/oauth2", + "DashboardRedirectURIs": [ + "https://vpn.esotericbytes.com/nb-auth", + "https://vpn.esotericbytes.com/nb-silent-auth" + ] + } +} diff --git a/system/virtualization/docker/netbird/default.nix b/system/virtualization/docker/netbird/default.nix index 7a96c51..aba598c 100644 --- a/system/virtualization/docker/netbird/default.nix +++ b/system/virtualization/docker/netbird/default.nix @@ -1,12 +1,4 @@ -{ config, lib, pkgs, ... }: let - - hostPort = 9006; - - subdomain = "vpn"; - - name = "netbird"; - -in { +{ config, lib, pkgs, ... }: { options.sysconfig.docker.netbird.enable = with lib; mkOption { type = with types; bool; @@ -14,23 +6,220 @@ in { }; config = lib.mkIf (config.sysconfig.docker.netbird.enable && config.sysconfig.docker.enable) { - - networking.firewall.interfaces = { - "ve-traefik" = { - allowedTCPPorts = [ hostPort ]; - }; - }; sops.secrets = { "netbird/pass" = {}; "netbird/secret_key" = {}; }; - sops.templates."netbird.env" = { + sops.templates."netbird-relay.env" = { content = '' - PG_PASS=${config.sops.placeholder."netbird/pass"} - SECRET_KEY=${config.sops.placeholder."netbird/secret_key"} + NB_AUTH_SECRET=${config.sops.placeholder."netbird/secret_key"} + NB_LOG_LEVEL=info + NB_LISTEN_ADDRESS=:80 + NB_EXPOSED_ADDRESS=rels://vpn.esotericbytes.com:443 + NB_ENABLE_STUN=true + NB_STUN_LOG_LEVEL=info + NB_STUN_PORTS=3478 ''; }; + +# Containers + virtualisation.oci-containers.containers."netbird-dashboard" = { + image = "netbirdio/dashboard:latest"; + environment = { + "AUTH_AUDIENCE" = "netbird-dashboard"; + "AUTH_AUTHORITY" = "https://vpn.esotericbytes.com/oauth2"; + "AUTH_CLIENT_ID" = "netbird-dashboard"; + "AUTH_CLIENT_SECRET" = ""; + "AUTH_REDIRECT_URI" = "/nb-auth"; + "AUTH_SILENT_REDIRECT_URI" = "/nb-silent-auth"; + "AUTH_SUPPORTED_SCOPES" = "openid profile email groups"; + "LETSENCRYPT_DOMAIN" = "none"; + "NETBIRD_MGMT_API_ENDPOINT" = "https://vpn.esotericbytes.com"; + "NETBIRD_MGMT_GRPC_API_ENDPOINT" = "https://vpn.esotericbytes.com"; + "NGINX_SSL_PORT" = "443"; + "USE_AUTH0" = "false"; + }; + labels = { + "traefik.enable" = "true"; + "traefik.http.routers.netbird-dashboard.entrypoints" = "websecure"; + "traefik.http.routers.netbird-dashboard.priority" = "1"; + "traefik.http.routers.netbird-dashboard.rule" = "Host(`vpn.esotericbytes.com`)"; + "traefik.http.routers.netbird-dashboard.tls" = "true"; + "traefik.http.services.netbird-dashboard.loadbalancer.server.port" = "80"; + }; + log-driver = "journald"; + extraOptions = [ + "--network-alias=dashboard" + "--network=docker-main" + ]; + }; + systemd.services."docker-netbird-dashboard" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + RestartMaxDelaySec = lib.mkOverride 90 "1m"; + RestartSec = lib.mkOverride 90 "100ms"; + RestartSteps = lib.mkOverride 90 9; + }; + partOf = [ + "docker-compose-netbird-root.target" + ]; + wantedBy = [ + "docker-compose-netbird-root.target" + ]; + }; + virtualisation.oci-containers.containers."netbird-management" = { + image = "netbirdio/management:latest"; + volumes = [ + "/home/nathan/Projects/tests/netbird/management.json:/etc/netbird/management.json:rw" + "netbird_netbird_management:/var/lib/netbird:rw" + ]; + cmd = [ "--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" ]; + labels = { + "traefik.enable" = "true"; + "traefik.http.routers.netbird-api.entrypoints" = "websecure"; + "traefik.http.routers.netbird-api.rule" = "Host(`vpn.esotericbytes.com`) && PathPrefix(`/api`)"; + "traefik.http.routers.netbird-api.service" = "netbird-api"; + "traefik.http.routers.netbird-api.tls" = "true"; + "traefik.http.routers.netbird-mgmt-grpc.entrypoints" = "websecure"; + "traefik.http.routers.netbird-mgmt-grpc.rule" = "Host(`vpn.esotericbytes.com`) && PathPrefix(`/management.ManagementService/`)"; + "traefik.http.routers.netbird-mgmt-grpc.service" = "netbird-mgmt-grpc"; + "traefik.http.routers.netbird-mgmt-grpc.tls" = "true"; + "traefik.http.routers.netbird-mgmt-ws.entrypoints" = "websecure"; + "traefik.http.routers.netbird-mgmt-ws.rule" = "Host(`vpn.esotericbytes.com`) && PathPrefix(`/ws-proxy/management`)"; + "traefik.http.routers.netbird-mgmt-ws.service" = "netbird-mgmt-ws"; + "traefik.http.routers.netbird-mgmt-ws.tls" = "true"; + "traefik.http.routers.netbird-oauth2.entrypoints" = "websecure"; + "traefik.http.routers.netbird-oauth2.rule" = "Host(`vpn.esotericbytes.com`) && PathPrefix(`/oauth2`)"; + "traefik.http.routers.netbird-oauth2.service" = "netbird-oauth2"; + "traefik.http.routers.netbird-oauth2.tls" = "true"; + "traefik.http.services.netbird-api.loadbalancer.server.port" = "80"; + "traefik.http.services.netbird-mgmt-grpc.loadbalancer.server.port" = "80"; + "traefik.http.services.netbird-mgmt-grpc.loadbalancer.server.scheme" = "h2c"; + "traefik.http.services.netbird-mgmt-ws.loadbalancer.server.port" = "80"; + "traefik.http.services.netbird-oauth2.loadbalancer.server.port" = "80"; + }; + log-driver = "journald"; + extraOptions = [ + "--network-alias=management" + "--network=docker-main" + ]; + }; + systemd.services."docker-netbird-management" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + RestartMaxDelaySec = lib.mkOverride 90 "1m"; + RestartSec = lib.mkOverride 90 "100ms"; + RestartSteps = lib.mkOverride 90 9; + }; + after = [ + "docker-volume-netbird_netbird_management.service" + ]; + requires = [ + "docker-volume-netbird_netbird_management.service" + ]; + partOf = [ + "docker-compose-netbird-root.target" + ]; + wantedBy = [ + "docker-compose-netbird-root.target" + ]; + }; + virtualisation.oci-containers.containers."netbird-relay" = { + image = "netbirdio/relay:latest"; + + environmentFiles = [ config.sops.templates."netbird-relay.env".path ]; + + ports = [ + "3478:3478/udp" + ]; + labels = { + "traefik.enable" = "true"; + "traefik.http.routers.netbird-relay.entrypoints" = "websecure"; + "traefik.http.routers.netbird-relay.rule" = "Host(`vpn.esotericbytes.com`) && PathPrefix(`/relay`)"; + "traefik.http.routers.netbird-relay.tls" = "true"; + "traefik.http.services.netbird-relay.loadbalancer.server.port" = "80"; + }; + log-driver = "journald"; + extraOptions = [ + "--network-alias=relay" + "--network=docker-main" + ]; + }; + systemd.services."docker-netbird-relay" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + RestartMaxDelaySec = lib.mkOverride 90 "1m"; + RestartSec = lib.mkOverride 90 "100ms"; + RestartSteps = lib.mkOverride 90 9; + }; + partOf = [ + "docker-compose-netbird-root.target" + ]; + wantedBy = [ + "docker-compose-netbird-root.target" + ]; + }; + virtualisation.oci-containers.containers."netbird-signal" = { + image = "netbirdio/signal:latest"; + labels = { + "traefik.enable" = "true"; + "traefik.http.routers.netbird-signal-grpc.entrypoints" = "websecure"; + "traefik.http.routers.netbird-signal-grpc.rule" = "Host(`vpn.esotericbytes.com`) && PathPrefix(`/signalexchange.SignalExchange/`)"; + "traefik.http.routers.netbird-signal-grpc.service" = "netbird-signal-grpc"; + "traefik.http.routers.netbird-signal-grpc.tls" = "true"; + "traefik.http.routers.netbird-signal-ws.entrypoints" = "websecure"; + "traefik.http.routers.netbird-signal-ws.rule" = "Host(`vpn.esotericbytes.com`) && PathPrefix(`/ws-proxy/signal`)"; + "traefik.http.routers.netbird-signal-ws.service" = "netbird-signal-ws"; + "traefik.http.routers.netbird-signal-ws.tls" = "true"; + "traefik.http.services.netbird-signal-grpc.loadbalancer.server.port" = "10000"; + "traefik.http.services.netbird-signal-grpc.loadbalancer.server.scheme" = "h2c"; + "traefik.http.services.netbird-signal-ws.loadbalancer.server.port" = "80"; + }; + log-driver = "journald"; + extraOptions = [ + "--network-alias=signal" + "--network=docker-main" + ]; + }; + systemd.services."docker-netbird-signal" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + RestartMaxDelaySec = lib.mkOverride 90 "1m"; + RestartSec = lib.mkOverride 90 "100ms"; + RestartSteps = lib.mkOverride 90 9; + }; + partOf = [ + "docker-compose-netbird-root.target" + ]; + wantedBy = [ + "docker-compose-netbird-root.target" + ]; + }; + +# Volumes + systemd.services."docker-volume-netbird_netbird_management" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + docker volume inspect netbird_netbird_management || docker volume create netbird_netbird_management + ''; + partOf = [ "docker-compose-netbird-root.target" ]; + wantedBy = [ "docker-compose-netbird-root.target" ]; + }; + +# Root service +# When started, this will automatically create all resources and start +# the containers. When stopped, this will teardown all resources. + systemd.targets."docker-compose-netbird-root" = { + unitConfig = { + Description = "Root target generated by compose2nix."; + }; + wantedBy = [ "multi-user.target" ]; + }; }; }