refactor(netbird): use port registry and named IP variables

This commit is contained in:
m3tm3re
2026-02-27 16:03:12 +01:00
parent fa9747f3e9
commit a9022a4f55
5 changed files with 56 additions and 47 deletions

View File

@@ -5,6 +5,7 @@
./kestra.nix
./littlelink.nix
./matomo.nix
./netbird.nix
# ./n8n.nix
# ./pangolin.nix
./restreamer.nix

View File

@@ -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
];
}

View File

@@ -6,7 +6,6 @@
./minio.nix
./mysql.nix
./n8n.nix
./netbird.nix
./paperless.nix
./postgres.nix
./searx.nix

Binary file not shown.

View File

@@ -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
×8<EFBFBD>‰k\í…ß,³vW/²=|:jDœfd#¤ê‰gxIwoïæ~UÛüíé4Ù¶ê…í¨Ô°
--- 6IeZk49jY+uLeHciC2dG1d/joRo4DnVPpgytWzPJjus
T¼@™]F­ äŠÍ½|¤¶0„\O“ì²C|•@"å¡0­ÄÆœ?ýÙú˜ÿ4¯D]+Ò@±Iz*({±b“B^šÃÙ´Ëñ<t¦³ÙR-?Ò³)