diff --git a/hosts/m3-atlas/services/containers/default.nix b/hosts/m3-atlas/services/containers/default.nix index 6b38c84..f3399fd 100644 --- a/hosts/m3-atlas/services/containers/default.nix +++ b/hosts/m3-atlas/services/containers/default.nix @@ -5,6 +5,7 @@ ./kestra.nix ./littlelink.nix ./matomo.nix + ./netbird.nix # ./n8n.nix # ./pangolin.nix ./restreamer.nix diff --git a/hosts/m3-atlas/services/containers/netbird.nix b/hosts/m3-atlas/services/containers/netbird.nix index ab23af2..605cc70 100644 --- a/hosts/m3-atlas/services/containers/netbird.nix +++ b/hosts/m3-atlas/services/containers/netbird.nix @@ -6,7 +6,12 @@ }: let serviceName = "netbird"; - servicePort = config.m3ta.ports.get "netbird"; + stunPort = config.m3ta.ports.get "netbird-stun"; + proxyTlsPort = config.m3ta.ports.get "netbird-proxy"; + metricsPort = config.m3ta.ports.get "netbird-metrics"; + healthPort = config.m3ta.ports.get "netbird-health"; + postgresPort = config.m3ta.ports.get "postgres"; + wireguardPort = config.m3ta.ports.get "wireguard"; domain = "v.m3ta.dev"; proxyDomain = "p.m3ta.dev"; @@ -14,26 +19,30 @@ ipBase = "10.89.0"; ipOffset = 50; + dashboardIp = "${ipBase}.${toString ipOffset}"; + serverIp = "${ipBase}.${toString (ipOffset + 1)}"; + proxyIp = "${ipBase}.${toString (ipOffset + 2)}"; + # Database configuration dbName = "netbird"; dbUser = "netbird"; dbHost = "${ipBase}.1"; - # NetBird config als Nix attribute set + # NetBird config as Nix attribute set netbirdConfig = { server = { listenAddress = ":80"; exposedAddress = "https://${domain}:443"; - stunPorts = [3478]; - metricsPort = 9090; - healthcheckAddress = ":9000"; + stunPorts = [stunPort]; + metricsPort = metricsPort; + healthcheckAddress = ":${toString healthPort}"; logLevel = "info"; logFile = "console"; dataDir = "/var/lib/netbird"; auth = { issuer = "https://${domain}/oauth2"; - localAuthDisabled = true; + # localAuthDisabled = true; signKeyRefreshEnabled = true; dashboardRedirectURIs = [ "https://${domain}/nb-auth" @@ -46,7 +55,7 @@ trustedHTTPProxies = ["${ipBase}.1/32"]; }; - # Proxy Feature + # Proxy feature proxy = { enabled = true; domain = proxyDomain; @@ -56,7 +65,7 @@ engine = "postgres"; postgres = { host = dbHost; - port = 5432; + port = postgresPort; database = dbName; username = dbUser; }; @@ -64,11 +73,11 @@ }; }; - # YAML generieren + # Generate YAML from Nix attribute set yamlFormat = pkgs.formats.yaml {}; configYamlBase = yamlFormat.generate "netbird-config-base.yaml" netbirdConfig; - # Script das Secrets zur Runtime injiziert + # Script that injects secrets at runtime configGenScript = pkgs.writeShellScript "netbird-gen-config" '' set -euo pipefail @@ -89,7 +98,7 @@ in { age.secrets."${serviceName}-dashboard-env".file = ../../../../secrets/${serviceName}-dashboard-env.age; age.secrets."${serviceName}-server-env".file = ../../../../secrets/${serviceName}-server-env.age; age.secrets."${serviceName}-proxy-env".file = ../../../../secrets/${serviceName}-proxy-env.age; - # Systemd oneshot Service der die Config generiert + # Oneshot systemd service that generates the config with injected secrets systemd.services."${serviceName}-config" = { description = "Generate NetBird config with secrets"; wantedBy = ["multi-user.target"]; @@ -117,7 +126,7 @@ in { autoStart = true; environmentFiles = [config.age.secrets."${serviceName}-dashboard-env".path]; extraOptions = [ - "--ip=${ipBase}.${toString ipOffset}" + "--ip=${dashboardIp}" "--network=web" ]; }; @@ -125,7 +134,7 @@ in { "${serviceName}-server" = { image = "netbirdio/netbird-server:latest"; autoStart = true; - ports = ["3478:3478/udp"]; + ports = ["${toString stunPort}:${toString stunPort}/udp"]; environmentFiles = [config.age.secrets."${serviceName}-server-env".path]; volumes = [ "${serviceName}_data:/var/lib/netbird" @@ -133,7 +142,7 @@ in { ]; cmd = ["--config" "/etc/netbird/config.yaml"]; extraOptions = [ - "--ip=${ipBase}.${toString (ipOffset + 1)}" + "--ip=${serverIp}" "--network=web" ]; }; @@ -141,41 +150,41 @@ in { "${serviceName}-proxy" = { image = "netbirdio/reverse-proxy:latest"; autoStart = true; - ports = ["51820:51820/udp"]; + ports = ["${toString wireguardPort}:${toString wireguardPort}/udp"]; volumes = [ "${serviceName}_proxy_certs:/certs" ]; environmentFiles = [config.age.secrets."${serviceName}-proxy-env".path]; cmd = [ - "--domain=p.m3ta.dev" + "--domain=${proxyDomain}" "--mgmt=https://${domain}:443" - "--addr=:8443" + "--addr=:${toString proxyTlsPort}" "--cert-dir=/certs" "--acme-certs" "--trusted-proxies=${ipBase}.1/32" ]; dependsOn = ["${serviceName}-server"]; extraOptions = [ - "--ip=${ipBase}.${toString (ipOffset + 2)}" + "--ip=${proxyIp}" "--network=web" ]; }; }; services.traefik.dynamicConfigOptions = { - # HTTP Services und Routers + # HTTP services and routers http = { services = { "${serviceName}-dashboard".loadBalancer.servers = [ - {url = "http://${ipBase}.${toString ipOffset}:80/";} + {url = "http://${dashboardIp}:80/";} ]; "${serviceName}-server".loadBalancer.servers = [ - {url = "http://${ipBase}.${toString (ipOffset + 1)}:80/";} + {url = "http://${serverIp}:80/";} ]; "${serviceName}-server-h2c".loadBalancer.servers = [ - {url = "h2c://${ipBase}.${toString (ipOffset + 1)}:80";} + {url = "h2c://${serverIp}:80";} ]; }; @@ -197,7 +206,7 @@ in { priority = 100; }; - # Dashboard (catch-all, niedrigste Priorität) + # Dashboard (catch-all, lowest priority) "${serviceName}-dashboard" = { rule = "Host(`${domain}`)"; entrypoints = "websecure"; @@ -208,10 +217,10 @@ in { }; }; - # TCP für Proxy TLS Passthrough + # TCP for proxy TLS passthrough tcp = { services."${serviceName}-proxy-tls".loadBalancer.servers = [ - {address = "${ipBase}.${toString (ipOffset + 2)}:8443";} + {address = "${proxyIp}:${toString proxyTlsPort}";} ]; routers."${serviceName}-proxy-passthrough" = { @@ -223,14 +232,14 @@ in { }; }; - # ServersTransport für Proxy Protocol v2 (optional) + # ServersTransport for Proxy Protocol v2 (optional) serversTransports."pp-v2" = { proxyProtocol.version = 2; }; }; networking.firewall.allowedUDPPorts = [ - 3478 # STUN - 51820 # WireGuard für Proxy + stunPort # STUN + wireguardPort # WireGuard for proxy ]; } diff --git a/hosts/m3-atlas/services/default.nix b/hosts/m3-atlas/services/default.nix index 4769978..6a49f8d 100644 --- a/hosts/m3-atlas/services/default.nix +++ b/hosts/m3-atlas/services/default.nix @@ -6,7 +6,6 @@ ./minio.nix ./mysql.nix ./n8n.nix - ./netbird.nix ./paperless.nix ./postgres.nix ./searx.nix diff --git a/secrets/netbird-dashboard-env.age b/secrets/netbird-dashboard-env.age index 62f8497..bcba6fb 100644 Binary files a/secrets/netbird-dashboard-env.age and b/secrets/netbird-dashboard-env.age differ diff --git a/secrets/netbird-proxy-env.age b/secrets/netbird-proxy-env.age index 0f63728..247555d 100644 --- a/secrets/netbird-proxy-env.age +++ b/secrets/netbird-proxy-env.age @@ -1,21 +1,21 @@ age-encryption.org/v1 --> ssh-ed25519 4NLKrw z/cBQjeEEhzQCSOweODXfH1+u0x4fPFzMmuJ60sT6Vk -7fA+XIqnsXFHlCD5w8s0ttHRYijt0/97PtJrx/xNVeA --> ssh-ed25519 5kwcsA p/tSvBiYUFw1CEypUFkZkan6Fg4cTpy4vT7weDAtZQI -zcphfvNyNUa0XYmVrIA7qTJ4btWD/LwZoGv8i3pWktU --> ssh-ed25519 9d4YIQ Xjyuwljm4+dJn/CUP4NgFl4fK1ah4z71rHAVrJ9ggTw -2ae/e/rdDNqt40E29E4qxvkEIC0GWAKX0pMbY7guHn4 --> ssh-ed25519 3Bcr1w Cra9xUKcyk5e0+VrdtCZUuGo/tRhicxlSNHheDfFslw -+AQBO1F8Yk/u0KuQ8uG168m1xOczr+I4kvNIyeHu11o +-> ssh-ed25519 4NLKrw SsQNRQTJVF4hcSVRmnYd7dHK+SCuMIPOIzFWyZp9WBg +sZz8th/4uY3T2UOs5C5exXhLmFo7AGrj+QxQwnuJ/ng +-> ssh-ed25519 5kwcsA uxdOaVZDDQLyV+vUJhG4mv16zfn3eOZWx9PpwoQje2M +gk7vrd7V9mwVXzh987C8A8QeQTxDfPBNT75QPMACnoE +-> ssh-ed25519 9d4YIQ G1OGiK+CYjXs3DPb2OHLoKAA2T5tNm/0ciFR3mZmmFA +qHW4cvm29OdKpt5Ia5boWx479z2vGKDwddTKeMc57Hc +-> ssh-ed25519 3Bcr1w lef+8thtDVWKeydqHku+8BzSxLCOyQ5o91RfwJU8Lyk +mWaQo4uxW1X+freu16rUPYWgZtt0P1L7lHuXJ32DXx8 -> ssh-rsa DQlE7w -qvtWc6kq/Q8W5aBlfj3o0/GFZC2pnyw58rggC//ciWvacz8lVUWSqYbP9JdRg8eK -04UnbS6FyUYRVJuD8hZYF5RRbPFOMzZE69jb2N/B3OnrtCr21ohXluPP3+rH8Egz -pC4ETTJYPuNPG+clEGcEcilLrgrI3ZvajJbDGhAx2kOTN1g3u4SnkSA6b1c5otsX -UAJsDzCOr4eKAdnf2ZGtuhzcrwDb8lCJ0rKz/ZQtWhWXRhYzalrWZHyH5KdMkOTq -ZTrPMLyzAaL3Civv9uZ6cveQp8TGSZHnA5hmz/4lwfMrRcJzJUgjjDdgiNwK34pw -IkInu6D6k5x7kRcFvKcOu8zJUELtXV6/uzswy3uJn9CiQsMC5GSri65iuARIi3JC -nUNxx8yVfUFk+PMoAWLXZ2A3Gd3GQ5tlQNrfcLubnpwHuD7bYMdskkSTktIW+RDj -p4ckgCxRFG4K5sYQEtM5j4mQg+hEKCjQTFzcgRY74AFZepXoWYuQ+d/ExMANPUMi +mdrcYIsmXXPsHXSyAZ9RJtBuKMxHphbuPhagAq2A8/w7hgEQLDLCaSh939uBiIX/ +YsRtVwN/YuvPoWCyl3Dns02gzaAEsxwfvA7dMbxR1ErHhlFLL/71zJMtA6gbDjZB +vzkUGHmkCp1M54je8GH7Tn3RxoE9ylqWX8Ja8xmw8xpgaqTc1eTOmiX056IyXsGi +kn/f3C/qBZO46CdjlTQL83Ntw+4yKMozUndwakxkMV/nQTbv+sX/vNiz6mYLItgI +LkD18niPLO2rjLNBOo2MAHBZqMB5PJze3ZxN4LOgnqHiv64sGPE2JA0LcnWSkp/O +LFzPlH01Bqmy9Wi8x0SIsKt7z5vJRuoUmlJ5D+QVwOmxO6KVs+BrUZE6KzrJsXZJ +12oqsiDyz4fJ+XJuDC4sYcl3bXnjIGEMD7sZIR+8F4RjK+IZJzRh/rX7YeFfVYAq +xJXAmXSPA9lBK4fkBHSi2X9QhSoOgXzHpK6I2ny5tgl2dYHHTvikuure1D646xVq ---- HfrVJutjDYDbddvlCyZ9RNEmgp/dTcjR3y1U+OLZ7Wg -8k\,vW/=|:jDfd#gxIwo~U4ٶ԰ \ No newline at end of file +--- 6IeZk49jY+uLeHciC2dG1d/joRo4DnVPpgytWzPJjus +T@]F |0\OC|@"0Ɯ?4D]+@Iz*({bB^ٴ