From fa9747f3e9f44855e916b63357b5226963059afd Mon Sep 17 00:00:00 2001 From: m3tm3re
Date: Fri, 27 Feb 2026 16:03:08 +0100
Subject: [PATCH] refactor(ports): add netbird port definitions
---
flake.lock | 70 +++---
home/features/desktop/hyprland.nix | 1 +
home/features/desktop/media.nix | 6 +-
hosts/common/ports.nix | 4 +
hosts/m3-ares/services/default.nix | 1 -
hosts/m3-ares/services/tailscale.nix | 12 -
hosts/m3-atlas/secrets.nix | 18 ++
.../m3-atlas/services/containers/netbird.nix | 236 ++++++++++++++++++
hosts/m3-atlas/services/default.nix | 4 +-
hosts/m3-atlas/services/headscale.nix | 118 ---------
hosts/m3-atlas/services/n8n.nix | 10 +-
hosts/m3-atlas/services/outline.nix | 33 ---
hosts/m3-atlas/services/postgres.nix | 1 +
hosts/m3-atlas/services/tailscale.nix | 28 ---
hosts/m3-kratos/services/default.nix | 8 +-
hosts/m3-kratos/services/n8n.nix | 7 +-
hosts/m3-kratos/services/tailscale.nix | 13 -
secrets.nix | 6 +
secrets/netbird-auth-secret.age | 22 ++
secrets/netbird-dashboard-env.age | Bin 0 -> 1583 bytes
secrets/netbird-db-password.age | Bin 0 -> 1096 bytes
secrets/netbird-encryption-key.age | 21 ++
secrets/netbird-proxy-env.age | 21 ++
secrets/netbird-server-env.age | 24 ++
24 files changed, 411 insertions(+), 253 deletions(-)
delete mode 100644 hosts/m3-ares/services/tailscale.nix
create mode 100644 hosts/m3-atlas/services/containers/netbird.nix
delete mode 100644 hosts/m3-atlas/services/headscale.nix
delete mode 100644 hosts/m3-atlas/services/outline.nix
delete mode 100644 hosts/m3-atlas/services/tailscale.nix
delete mode 100644 hosts/m3-kratos/services/tailscale.nix
create mode 100644 secrets/netbird-auth-secret.age
create mode 100644 secrets/netbird-dashboard-env.age
create mode 100644 secrets/netbird-db-password.age
create mode 100644 secrets/netbird-encryption-key.age
create mode 100644 secrets/netbird-proxy-env.age
create mode 100644 secrets/netbird-server-env.age
diff --git a/flake.lock b/flake.lock
index 769a5e6..27c44d9 100644
--- a/flake.lock
+++ b/flake.lock
@@ -82,11 +82,11 @@
]
},
"locked": {
- "lastModified": 1771355198,
- "narHash": "sha256-89m5VKxIs8QNiIvLsxHu5NpyhDsoXTtoN801IAurnW4=",
+ "lastModified": 1771881364,
+ "narHash": "sha256-A5uE/hMium5of/QGC6JwF5TGoDAfpNtW00T0s9u/PN8=",
"owner": "nix-community",
"repo": "disko",
- "rev": "92fceb111901a6f13e81199be4fab95fce86a5c9",
+ "rev": "a4cb7bf73f264d40560ba527f9280469f1f081c6",
"type": "github"
},
"original": {
@@ -162,11 +162,11 @@
]
},
"locked": {
- "lastModified": 1771422582,
- "narHash": "sha256-xK5kl3OBZaF1VwziVMX+SZ2LT9Fbu5o8vRDt78uR7no=",
+ "lastModified": 1772164835,
+ "narHash": "sha256-zRcwrZDeBfYipqv/7K7TqsfPb87LFU6b7JhoNUGSnvQ=",
"owner": "nix-community",
"repo": "home-manager",
- "rev": "b3ccd4bb262f4e6d3248b46cede92b90c4a42094",
+ "rev": "2a39b0828bbffce0d73769a61e46e780488d098b",
"type": "github"
},
"original": {
@@ -246,11 +246,11 @@
"openspec": "openspec"
},
"locked": {
- "lastModified": 1771433707,
- "narHash": "sha256-O6S4YB16lN9ACb2Z6lEWxE22IyUhb+Z3mJgQJw3hpA4=",
+ "lastModified": 1772041931,
+ "narHash": "sha256-NQOQrGtR1EXM33JSVUt5Sz5MburSxWU7t9iZrJk9gQo=",
"ref": "refs/heads/master",
- "rev": "58312b2ca2fdf5e0f753e496b4902a523cbb96aa",
- "revCount": 120,
+ "rev": "e22774539ac26071b1bc0e6e8272df3c3ec732f2",
+ "revCount": 132,
"type": "git",
"url": "https://code.m3ta.dev/m3tam3re/nixpkgs"
},
@@ -393,11 +393,11 @@
},
"nixpkgs-master": {
"locked": {
- "lastModified": 1770917518,
- "narHash": "sha256-XSwv/tVrNo/L8SPH8Lx9xZH1PrZd/3Z3J/0SH7Xertg=",
+ "lastModified": 1771574031,
+ "narHash": "sha256-yKeO6auxI8PrBZOdt/LVRDm+bh939E60l4iZKo1ExeA=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "3f4a3c08f2f318ee29fc8a2689f390071a94aaf0",
+ "rev": "ab43bb60c7d266a4a285e863d89c1e69cd124dd5",
"type": "github"
},
"original": {
@@ -409,11 +409,11 @@
},
"nixpkgs-master_2": {
"locked": {
- "lastModified": 1771426280,
- "narHash": "sha256-EJOpj/ha/y7cLBHqPWCbYh4fFM83mO/c9bYm8zVVRkY=",
+ "lastModified": 1772174770,
+ "narHash": "sha256-/9F05YcHccOaI4dIsWk4G9oKEK07Oc3TeK5O7S3Mu8Q=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "85680c67a23fe3cc29b85d4568e984185c58e0c9",
+ "rev": "337e35331766eb979303e7639914c8a80cc02649",
"type": "github"
},
"original": {
@@ -425,11 +425,11 @@
},
"nixpkgs-stable": {
"locked": {
- "lastModified": 1771208521,
- "narHash": "sha256-X01Q3DgSpjeBpapoGA4rzKOn25qdKxbPnxHeMLNoHTU=",
+ "lastModified": 1771903837,
+ "narHash": "sha256-sdaqdnsQCv3iifzxwB22tUwN/fSHoN7j2myFW5EIkGk=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "fa56d7d6de78f5a7f997b0ea2bc6efd5868ad9e8",
+ "rev": "e764fc9a405871f1f6ca3d1394fb422e0a0c3951",
"type": "github"
},
"original": {
@@ -457,11 +457,11 @@
},
"nixpkgs_3": {
"locked": {
- "lastModified": 1770562336,
- "narHash": "sha256-ub1gpAONMFsT/GU2hV6ZWJjur8rJ6kKxdm9IlCT0j84=",
+ "lastModified": 1771369470,
+ "narHash": "sha256-0NBlEBKkN3lufyvFegY4TYv5mCNHbi5OmBDrzihbBMQ=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "d6c71932130818840fc8fe9509cf50be8c64634f",
+ "rev": "0182a361324364ae3f436a63005877674cf45efb",
"type": "github"
},
"original": {
@@ -489,11 +489,11 @@
},
"nixpkgs_5": {
"locked": {
- "lastModified": 1771008912,
- "narHash": "sha256-gf2AmWVTs8lEq7z/3ZAsgnZDhWIckkb+ZnAo5RzSxJg=",
+ "lastModified": 1771848320,
+ "narHash": "sha256-0MAd+0mun3K/Ns8JATeHT1sX28faLII5hVLq0L3BdZU=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "a82ccc39b39b621151d6732718e3e250109076fa",
+ "rev": "2fc6539b481e1d2569f25f8799236694180c0993",
"type": "github"
},
"original": {
@@ -527,11 +527,11 @@
]
},
"locked": {
- "lastModified": 1771425294,
- "narHash": "sha256-owiQE9oINf1cgaulbrr2sMjelk2cmR8rkxLRPYYL6Kg=",
+ "lastModified": 1772169824,
+ "narHash": "sha256-KF4t5iagvmzUCT/ukiMbKg+hG+raFm+qs4zRWJouho8=",
"owner": "nix-community",
"repo": "NUR",
- "rev": "242d44cd6af365da2dfa77422263b29d0ac9f39f",
+ "rev": "9d6c360577861a5218dbf453b84483075e6b56d2",
"type": "github"
},
"original": {
@@ -548,16 +548,16 @@
]
},
"locked": {
- "lastModified": 1771271829,
- "narHash": "sha256-43vPMyO7DsAgKrh0Wmt7jLDYCWUsaj30nBITreyYgX8=",
+ "lastModified": 1772031356,
+ "narHash": "sha256-PA3/P5nUDlrKD6xjDXFoNNF8U2Wzz2JeeY4H+CzWWgY=",
"owner": "anomalyco",
"repo": "opencode",
- "rev": "d8c25bfeb44771cc3a3ba17bf8de6ad2add9de2c",
+ "rev": "de2bc25677b419d2af0da8b6a24a05d3f22b67a8",
"type": "github"
},
"original": {
"owner": "anomalyco",
- "ref": "v1.2.6",
+ "ref": "v1.2.14",
"repo": "opencode",
"type": "github"
}
@@ -570,11 +570,11 @@
]
},
"locked": {
- "lastModified": 1771409495,
- "narHash": "sha256-LplnuO/OHSFL8S8iwQ16CZTjlPxRV9XohkKxL3uA5Sc=",
+ "lastModified": 1771554066,
+ "narHash": "sha256-nQPz81Um+4zhEeNz1o55Ix1DoBEM3CxeABAmOJkgIac=",
"owner": "Fission-AI",
"repo": "OpenSpec",
- "rev": "5fd8e9d66c3b6b116e7af814a6013c2d9c4958dd",
+ "rev": "4ba26902dfecf6f54c5a729993e012a57f4e2877",
"type": "github"
},
"original": {
diff --git a/home/features/desktop/hyprland.nix b/home/features/desktop/hyprland.nix
index b1449e1..0f92500 100644
--- a/home/features/desktop/hyprland.nix
+++ b/home/features/desktop/hyprland.nix
@@ -122,6 +122,7 @@ in {
"match:title branchdialog, float on"
"match:class pavucontrol-qt, float on"
"match:class pavucontrol, float on"
+ "match:class class:^(espanso)$, float on"
# wlogout
"match:class wlogout, fullscreen on"
"match:title wlogout, float on"
diff --git a/home/features/desktop/media.nix b/home/features/desktop/media.nix
index c7d1c47..35eb1cc 100644
--- a/home/features/desktop/media.nix
+++ b/home/features/desktop/media.nix
@@ -19,22 +19,22 @@ in {
amf
blueberry
ffmpeg_6-full
+ gimp
gst_all_1.gstreamer
gst_all_1.gst-vaapi
handbrake
inkscape
kdePackages.kdenlive
- krita
libation
#makemkv
pamixer
pavucontrol
qpwgraph
v4l-utils
- #plexamp
+ plexamp
# uxplay
# vlc
- # webcord
+ webcord
# yt-dlp
unimatrix
];
diff --git a/hosts/common/ports.nix b/hosts/common/ports.nix
index 826e7bf..a288156 100644
--- a/hosts/common/ports.nix
+++ b/hosts/common/ports.nix
@@ -18,6 +18,10 @@
wireguard = 51820;
tailscale = 41641;
headscale = 3009;
+ netbird-stun = 3478;
+ netbird-proxy = 8443;
+ netbird-metrics = 9090;
+ netbird-health = 9000;
# Containers & web apps
gitea = 3030;
diff --git a/hosts/m3-ares/services/default.nix b/hosts/m3-ares/services/default.nix
index 72bcd4c..8b9d241 100644
--- a/hosts/m3-ares/services/default.nix
+++ b/hosts/m3-ares/services/default.nix
@@ -6,7 +6,6 @@
./postgres.nix
./restic.nix
./sound.nix
- ./tailscale.nix
./udev.nix
./wireguard.nix
];
diff --git a/hosts/m3-ares/services/tailscale.nix b/hosts/m3-ares/services/tailscale.nix
deleted file mode 100644
index 7af9a9e..0000000
--- a/hosts/m3-ares/services/tailscale.nix
+++ /dev/null
@@ -1,12 +0,0 @@
-{config, ...}: {
- services.tailscale = {
- enable = true;
- authKeyFile = config.age.secrets.tailscale-key.path;
- useRoutingFeatures = "both";
- extraUpFlags = [
- "--login-server=https://va.m3tam3re.com"
- "--accept-routes"
- "--ssh"
- ];
- };
-}
diff --git a/hosts/m3-atlas/secrets.nix b/hosts/m3-atlas/secrets.nix
index 227a497..adaf06d 100644
--- a/hosts/m3-atlas/secrets.nix
+++ b/hosts/m3-atlas/secrets.nix
@@ -11,6 +11,24 @@
littlelink-m3tam3re = {file = ../../secrets/littlelink-m3tam3re.age;};
minio-root-cred = {file = ../../secrets/minio-root-cred.age;};
n8n-env = {file = ../../secrets/n8n-env.age;};
+ netbird-auth-secret = {
+ file = ../../secrets/netbird-auth-secret.age;
+ };
+ netbird-db-password = {
+ file = ../../secrets/netbird-db-password.age;
+ };
+ netbird-encryption-key = {
+ file = ../../secrets/netbird-encryption-key.age;
+ };
+ netbird-dashboard-env = {
+ file = ../../secrets/netbird-dashboard-env.age;
+ };
+ netbird-server-env = {
+ file = ../../secrets/netbird-server-env.age;
+ };
+ netbird-proxy-env = {
+ file = ../../secrets/netbird-proxy-env.age;
+ };
paperless-key = {file = ../../secrets/paperless-key.age;};
restreamer-env = {file = ../../secrets/restreamer-env.age;};
searx = {file = ../../secrets/searx.age;};
diff --git a/hosts/m3-atlas/services/containers/netbird.nix b/hosts/m3-atlas/services/containers/netbird.nix
new file mode 100644
index 0000000..ab23af2
--- /dev/null
+++ b/hosts/m3-atlas/services/containers/netbird.nix
@@ -0,0 +1,236 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ serviceName = "netbird";
+
+ servicePort = config.m3ta.ports.get "netbird";
+
+ domain = "v.m3ta.dev";
+ proxyDomain = "p.m3ta.dev";
+
+ ipBase = "10.89.0";
+ ipOffset = 50;
+
+ # Database configuration
+ dbName = "netbird";
+ dbUser = "netbird";
+ dbHost = "${ipBase}.1";
+
+ # NetBird config als Nix attribute set
+ netbirdConfig = {
+ server = {
+ listenAddress = ":80";
+ exposedAddress = "https://${domain}:443";
+ stunPorts = [3478];
+ metricsPort = 9090;
+ healthcheckAddress = ":9000";
+ logLevel = "info";
+ logFile = "console";
+ dataDir = "/var/lib/netbird";
+
+ auth = {
+ issuer = "https://${domain}/oauth2";
+ localAuthDisabled = true;
+ signKeyRefreshEnabled = true;
+ dashboardRedirectURIs = [
+ "https://${domain}/nb-auth"
+ "https://${domain}/nb-silent-auth"
+ ];
+ cliRedirectURIs = ["http://localhost:53000/"];
+ };
+
+ reverseProxy = {
+ trustedHTTPProxies = ["${ipBase}.1/32"];
+ };
+
+ # Proxy Feature
+ proxy = {
+ enabled = true;
+ domain = proxyDomain;
+ };
+
+ store = {
+ engine = "postgres";
+ postgres = {
+ host = dbHost;
+ port = 5432;
+ database = dbName;
+ username = dbUser;
+ };
+ };
+ };
+ };
+
+ # YAML generieren
+ yamlFormat = pkgs.formats.yaml {};
+ configYamlBase = yamlFormat.generate "netbird-config-base.yaml" netbirdConfig;
+
+ # Script das Secrets zur Runtime injiziert
+ configGenScript = pkgs.writeShellScript "netbird-gen-config" ''
+ set -euo pipefail
+
+ AUTH_SECRET=$(cat "$1")
+ DB_PASSWORD=$(cat "$2")
+ ENCRYPTION_KEY=$(cat "$3")
+
+ ${pkgs.yq-go}/bin/yq eval "
+ .server.authSecret = \"$AUTH_SECRET\" |
+ .server.store.encryptionKey = \"$ENCRYPTION_KEY\" |
+ .server.store.postgres.password = \"$DB_PASSWORD\"
+ " ${configYamlBase}
+ '';
+in {
+ age.secrets."${serviceName}-auth-secret".file = ../../../../secrets/${serviceName}-auth-secret.age;
+ age.secrets."${serviceName}-db-password".file = ../../../../secrets/${serviceName}-db-password.age;
+ age.secrets."${serviceName}-encryption-key".file = ../../../../secrets/${serviceName}-encryption-key.age;
+ 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
+ systemd.services."${serviceName}-config" = {
+ description = "Generate NetBird config with secrets";
+ wantedBy = ["multi-user.target"];
+ before = ["podman-${serviceName}-server.service"];
+ requiredBy = ["podman-${serviceName}-server.service"];
+
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ ExecStart = pkgs.writeShellScript "netbird-write-config" ''
+ mkdir -p /var/lib/${serviceName}
+ ${configGenScript} \
+ ${config.age.secrets."${serviceName}-auth-secret".path} \
+ ${config.age.secrets."${serviceName}-db-password".path} \
+ ${config.age.secrets."${serviceName}-encryption-key".path} \
+ > /var/lib/${serviceName}/config.yaml
+ chmod 600 /var/lib/${serviceName}/config.yaml
+ '';
+ };
+ };
+
+ virtualisation.oci-containers.containers = {
+ "${serviceName}-dashboard" = {
+ image = "netbirdio/dashboard:latest";
+ autoStart = true;
+ environmentFiles = [config.age.secrets."${serviceName}-dashboard-env".path];
+ extraOptions = [
+ "--ip=${ipBase}.${toString ipOffset}"
+ "--network=web"
+ ];
+ };
+
+ "${serviceName}-server" = {
+ image = "netbirdio/netbird-server:latest";
+ autoStart = true;
+ ports = ["3478:3478/udp"];
+ environmentFiles = [config.age.secrets."${serviceName}-server-env".path];
+ volumes = [
+ "${serviceName}_data:/var/lib/netbird"
+ "/var/lib/${serviceName}/config.yaml:/etc/netbird/config.yaml:ro"
+ ];
+ cmd = ["--config" "/etc/netbird/config.yaml"];
+ extraOptions = [
+ "--ip=${ipBase}.${toString (ipOffset + 1)}"
+ "--network=web"
+ ];
+ };
+
+ "${serviceName}-proxy" = {
+ image = "netbirdio/reverse-proxy:latest";
+ autoStart = true;
+ ports = ["51820:51820/udp"];
+ volumes = [
+ "${serviceName}_proxy_certs:/certs"
+ ];
+ environmentFiles = [config.age.secrets."${serviceName}-proxy-env".path];
+ cmd = [
+ "--domain=p.m3ta.dev"
+ "--mgmt=https://${domain}:443"
+ "--addr=:8443"
+ "--cert-dir=/certs"
+ "--acme-certs"
+ "--trusted-proxies=${ipBase}.1/32"
+ ];
+ dependsOn = ["${serviceName}-server"];
+ extraOptions = [
+ "--ip=${ipBase}.${toString (ipOffset + 2)}"
+ "--network=web"
+ ];
+ };
+ };
+
+ services.traefik.dynamicConfigOptions = {
+ # HTTP Services und Routers
+ http = {
+ services = {
+ "${serviceName}-dashboard".loadBalancer.servers = [
+ {url = "http://${ipBase}.${toString ipOffset}:80/";}
+ ];
+
+ "${serviceName}-server".loadBalancer.servers = [
+ {url = "http://${ipBase}.${toString (ipOffset + 1)}:80/";}
+ ];
+
+ "${serviceName}-server-h2c".loadBalancer.servers = [
+ {url = "h2c://${ipBase}.${toString (ipOffset + 1)}:80";}
+ ];
+ };
+
+ routers = {
+ # gRPC (Signal + Management)
+ "${serviceName}-grpc" = {
+ rule = "Host(`${domain}`) && (PathPrefix(`/signalexchange.SignalExchange/`) || PathPrefix(`/management.ManagementService/`) || PathPrefix(`/management.ProxyService/`))";
+ entrypoints = "websecure";
+ tls.certResolver = "godaddy";
+ service = "${serviceName}-server-h2c";
+ priority = 100;
+ };
+ # Backend (relay, WebSocket, API, OAuth2)
+ "${serviceName}-backend" = {
+ rule = "Host(`${domain}`) && (PathPrefix(`/relay`) || PathPrefix(`/ws-proxy/`) || PathPrefix(`/api`) || PathPrefix(`/oauth2`))";
+ entrypoints = "websecure";
+ tls.certResolver = "godaddy";
+ service = "${serviceName}-server";
+ priority = 100;
+ };
+
+ # Dashboard (catch-all, niedrigste Priorität)
+ "${serviceName}-dashboard" = {
+ rule = "Host(`${domain}`)";
+ entrypoints = "websecure";
+ tls.certResolver = "godaddy";
+ service = "${serviceName}-dashboard";
+ priority = 1;
+ };
+ };
+ };
+
+ # TCP für Proxy TLS Passthrough
+ tcp = {
+ services."${serviceName}-proxy-tls".loadBalancer.servers = [
+ {address = "${ipBase}.${toString (ipOffset + 2)}:8443";}
+ ];
+
+ routers."${serviceName}-proxy-passthrough" = {
+ entryPoints = ["websecure"];
+ rule = "HostSNI(`*`)";
+ service = "${serviceName}-proxy-tls";
+ priority = 1;
+ tls.passthrough = true;
+ };
+ };
+
+ # ServersTransport für Proxy Protocol v2 (optional)
+ serversTransports."pp-v2" = {
+ proxyProtocol.version = 2;
+ };
+ };
+
+ networking.firewall.allowedUDPPorts = [
+ 3478 # STUN
+ 51820 # WireGuard für Proxy
+ ];
+}
diff --git a/hosts/m3-atlas/services/default.nix b/hosts/m3-atlas/services/default.nix
index a449aa8..4769978 100644
--- a/hosts/m3-atlas/services/default.nix
+++ b/hosts/m3-atlas/services/default.nix
@@ -3,15 +3,13 @@
./containers
./gitea.nix
./gitea-actions-runner.nix
- ./headscale.nix
./minio.nix
./mysql.nix
./n8n.nix
- ./outline.nix
+ ./netbird.nix
./paperless.nix
./postgres.nix
./searx.nix
- ./tailscale.nix
./traefik.nix
./vaultwarden.nix
./wastebin.nix
diff --git a/hosts/m3-atlas/services/headscale.nix b/hosts/m3-atlas/services/headscale.nix
deleted file mode 100644
index c777103..0000000
--- a/hosts/m3-atlas/services/headscale.nix
+++ /dev/null
@@ -1,118 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}: {
- # Define a new option for the admin user
- options.services.headscale = {
- adminUser = lib.mkOption {
- type = lib.types.str;
- default = "m3tam3re@m3ta.loc";
- description = "Username for the headscale admin user";
- };
- };
-
- config = let
- adminUser = config.services.headscale.adminUser;
-
- aclConfig = {
- # Groups definition
- groups = {
- "group:admins" = ["${adminUser}"];
- };
-
- acls = [
- # Allow all connections within the tailnet
- {
- action = "accept";
- src = ["*"];
- dst = ["*:*"];
- }
- # Allow admin to connect to their own services
- {
- action = "accept";
- src = ["${adminUser}"];
- dst = ["${adminUser}:*"];
- }
- ];
- # Auto-approvers section for routes
- autoApprovers = {
- routes = {
- "0.0.0.0/0" = ["${adminUser}"];
- "10.0.0.0/8" = ["${adminUser}"];
- "192.168.0.0/16" = ["${adminUser}"];
- };
-
- exitNode = ["${adminUser}"];
- };
- };
- # Convert to HuJSON format with comments
- aclHuJson = ''
- // Headscale ACL Policy - Generated by NixOS
- // Admin user: ${adminUser}
-
- ${builtins.toJSON aclConfig}
- '';
- aclFile = pkgs.writeText "acl-policy.hujson" aclHuJson;
- in {
- services = {
- headscale = {
- enable = true;
- adminUser = "m3tam3re@m3ta.loc";
- port = 3009;
- settings = {
- server_url = "https://va.m3tam3re.com";
- dns = {
- base_domain = "m3ta.loc";
- nameservers.global = ["8.8.8.8"];
- };
- logtail.enabled = false;
- policy.path = "${aclFile}";
- };
- };
- };
-
- # Create a systemd service to ensure the admin user exists
- systemd.services.headscale-ensure-admin = lib.mkIf config.services.headscale.enable {
- description = "Ensure Headscale admin user exists";
- after = ["headscale.service"];
- requires = ["headscale.service"];
- wantedBy = ["multi-user.target"];
- serviceConfig = {
- Type = "oneshot";
- RemainAfterExit = true;
- User = "headscale";
- Group = "headscale";
- };
-
- script = ''
- # Check if user exists and create if needed
- if ! ${pkgs.headscale}/bin/headscale users list | grep -q "${adminUser}"; then
- echo "Creating headscale admin user: ${adminUser}"
- ${pkgs.headscale}/bin/headscale users create "${adminUser}"
- else
- echo "Headscale admin user ${adminUser} already exists"
- fi
- '';
- };
-
- # Traefik configuration for headscale
- services.traefik.dynamicConfigOptions.http = {
- services.headscale.loadBalancer.servers = [
- {
- url = "http://localhost:3009/";
- }
- ];
-
- routers.headscale = {
- rule = "Host(`va.m3tam3re.com`)";
- tls = {
- certResolver = "godaddy";
- };
- service = "headscale";
- entrypoints = "websecure";
- };
- };
- };
-}
diff --git a/hosts/m3-atlas/services/n8n.nix b/hosts/m3-atlas/services/n8n.nix
index a7bccc8..2cfacf6 100644
--- a/hosts/m3-atlas/services/n8n.nix
+++ b/hosts/m3-atlas/services/n8n.nix
@@ -1,8 +1,16 @@
-{config, ...}: {
+{
+ config,
+ lib,
+ ...
+}: {
services.n8n = {
enable = true;
environment.WEBHOOK_URL = "https://wf.m3tam3re.com";
};
+ # Temporary fix for upstream module
+ systemd.services.n8n.serviceConfig.LoadCredential = lib.mkForce [];
+ systemd.services.n8n.environment.N8N_RUNNERS_AUTH_TOKEN_FILE = lib.mkForce null;
+
systemd.services.n8n.serviceConfig = {
EnvironmentFile = ["${config.age.secrets.n8n-env.path}"];
};
diff --git a/hosts/m3-atlas/services/outline.nix b/hosts/m3-atlas/services/outline.nix
deleted file mode 100644
index 13646aa..0000000
--- a/hosts/m3-atlas/services/outline.nix
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- services.outline = {
- enable = true;
- port = 3019;
- publicUrl = "https://ol.m3ta.dev";
- databaseUrl = "postgresql://outline:outline@127.0.0.1:5432/outline";
- storage = {
- storageType = "local";
- };
- };
- systemd.services.outline.serviceConfig = {
- Environment = [
- "PGSSLMODE=disable"
- ];
- };
- # Traefik configuration specific to littlelink
- services.traefik.dynamicConfigOptions.http = {
- services.outline.loadBalancer.servers = [
- {
- url = "http://localhost:3019/";
- }
- ];
-
- routers.outline = {
- rule = "Host(`ol.m3ta.dev`)";
- tls = {
- certResolver = "godaddy";
- };
- service = "outline";
- entrypoints = "websecure";
- };
- };
-}
diff --git a/hosts/m3-atlas/services/postgres.nix b/hosts/m3-atlas/services/postgres.nix
index b23bf9d..ee7de06 100644
--- a/hosts/m3-atlas/services/postgres.nix
+++ b/hosts/m3-atlas/services/postgres.nix
@@ -26,6 +26,7 @@
# Podman network connections for Baserow
host baserow baserow 10.89.0.0/24 scram-sha-256
host kestra kestra 10.89.0.0/24 scram-sha-256
+ host netbird netbird 10.89.0.0/24 scram-sha-256
# Deny all other connections
local all all reject
diff --git a/hosts/m3-atlas/services/tailscale.nix b/hosts/m3-atlas/services/tailscale.nix
deleted file mode 100644
index 6c32316..0000000
--- a/hosts/m3-atlas/services/tailscale.nix
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}: {
- services.tailscale = {
- enable = true;
- authKeyFile = config.age.secrets.tailscale-key.path;
- useRoutingFeatures = "both";
- extraUpFlags = [
- "--login-server=${config.services.headscale.settings.server_url}"
- "--advertise-exit-node"
- "--accept-routes"
- "--ssh=true"
- ];
- };
- services.networkd-dispatcher = lib.mkIf config.services.tailscale.enable {
- enable = true;
- rules."50-tailscale" = {
- onState = ["routable"];
- script = ''
- NETDEV=$(ip -o route get 8.8.8.8 | cut -f 5 -d " ")
- ${pkgs.ethtool}/bin/ethtool -K "$NETDEV" rx-udp-gro-forwarding on rx-gro-list off
- '';
- };
- };
-}
diff --git a/hosts/m3-kratos/services/default.nix b/hosts/m3-kratos/services/default.nix
index e144c10..dc1d637 100644
--- a/hosts/m3-kratos/services/default.nix
+++ b/hosts/m3-kratos/services/default.nix
@@ -1,22 +1,24 @@
-{
+{pkgs, ...}: {
imports = [
./containers
./mem0.nix
./n8n.nix
./postgres.nix
./sound.nix
- ./tailscale.nix
./udev.nix
./wireguard.nix
];
services = {
hypridle.enable = true;
+ espanso = {
+ enable = true;
+ package = pkgs.espanso-wayland;
+ };
printing.enable = true;
gvfs.enable = true;
trezord.enable = true;
gnome.gnome-keyring.enable = true;
qdrant.enable = true;
- stirling-pdf.enable = true;
avahi = {
enable = true;
nssmdns4 = true;
diff --git a/hosts/m3-kratos/services/n8n.nix b/hosts/m3-kratos/services/n8n.nix
index be43e06..00c2653 100644
--- a/hosts/m3-kratos/services/n8n.nix
+++ b/hosts/m3-kratos/services/n8n.nix
@@ -1,12 +1,13 @@
-{
+{lib, ...}: {
services.n8n = {
enable = true;
openFirewall = true;
- };
- systemd.services.n8n = {
environment = {
N8N_SECURE_COOKIE = "false";
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS = "false";
};
};
+ # Temporary fix for upstream module
+ systemd.services.n8n.serviceConfig.LoadCredential = lib.mkForce [];
+ systemd.services.n8n.environment.N8N_RUNNERS_AUTH_TOKEN_FILE = lib.mkForce null;
}
diff --git a/hosts/m3-kratos/services/tailscale.nix b/hosts/m3-kratos/services/tailscale.nix
deleted file mode 100644
index 0e60650..0000000
--- a/hosts/m3-kratos/services/tailscale.nix
+++ /dev/null
@@ -1,13 +0,0 @@
-{config, ...}: {
- services.tailscale = {
- enable = true;
- authKeyFile = config.age.secrets.tailscale-key.path;
- useRoutingFeatures = "both";
- extraUpFlags = [
- "--login-server=https://va.m3tam3re.com"
- "--accept-routes"
- "--ssh"
- "--reset"
- ];
- };
-}
diff --git a/secrets.nix b/secrets.nix
index b24186a..4d8e9d2 100644
--- a/secrets.nix
+++ b/secrets.nix
@@ -21,6 +21,12 @@ in {
"secrets/kestra-env.age".publicKeys = systems ++ users;
"secrets/minio-root-cred.age".publicKeys = systems ++ users;
"secrets/n8n-env.age".publicKeys = systems ++ users;
+ "secrets/netbird-auth-secret.age".publicKeys = systems ++ users;
+ "secrets/netbird-db-password.age".publicKeys = systems ++ users;
+ "secrets/netbird-encryption-key.age".publicKeys = systems ++ users;
+ "secrets/netbird-dashboard-env.age".publicKeys = systems ++ users;
+ "secrets/netbird-server-env.age".publicKeys = systems ++ users;
+ "secrets/netbird-proxy-env.age".publicKeys = systems ++ users;
"secrets/paperless-key.age".publicKeys = systems ++ users;
"secrets/ref-key.age".publicKeys = systems ++ users;
"secrets/exa-key.age".publicKeys = systems ++ users;
diff --git a/secrets/netbird-auth-secret.age b/secrets/netbird-auth-secret.age
new file mode 100644
index 0000000..d2c5bcc
--- /dev/null
+++ b/secrets/netbird-auth-secret.age
@@ -0,0 +1,22 @@
+age-encryption.org/v1
+-> ssh-ed25519 4NLKrw 8RHoP6X3KpWlot1bjJ7k2RKYucu6QRB8yvtVyj5sEDA
+mtffN452PGzO4CcyE0GhFcNwI7fr7Aq3bgaohE6PwEQ
+-> ssh-ed25519 5kwcsA 3232LkSUcKzcW+ZMnKL8rqDYK933OA8RqnRxy7lRGAo
+ZexaJBmpEkalgIc0/xCVN/7kF70KcKDXi3jJb+AWR/8
+-> ssh-ed25519 9d4YIQ L1LGlKGk6l5ajdoG0B7vVdO/6rBwRQsK8mV/vz8DLmI
+6lRnaGFyykil752Vctnd8W1qNATuQv069BAiYU0vg6U
+-> ssh-ed25519 3Bcr1w PzlTqlD68Wdxct/8S59FDWPWQPpw0WpIBVYh4eIkP3I
+wM2Y9/kpr+X1Q1b6QdFP2R25FsLl2zEFZltieraOWps
+-> ssh-rsa DQlE7w
+bm/GpjLWe9QONNTgC6U1jPQOkh0in5iOSfl15kYrWPMf1YDdLoM8vMBium8ph61o
+UmgLZ5/vcaZYnxwTA7Bgc8+JJrsWyU9WJZa1eK63Y/ARLyt3FCWSkPl2XJUgYMC1
+feH9f05PkPaK1aIVn4EpUlaoDbBHUEhnzgDRAXAGKpDcKJvthTXMD7iYgeyIuXv5
+jy7mRSlSfp4BddXEghVuI48sBoc9FZKL8FW75vPLkb2NJfGYqwp+ObJG2sSGJPp2
+57/BL/9/Gny5AuKnT1ATU18zZZ+RBCJGllwFpwTM21FQJUlE8mchHURxdARbeRAq
+HvcG+lHbQzpqwdIMY9KuqtuxeIGeXjWDmrzy8ELzbRnawibnVLBPPB1eUecngub6
+qtUYBNgHVDFwEEIKj3+YVAf/Aqn9KJnGpvt2PtEs9vMIgHlDZUl8ZgTned5UT+xi
+sEAHWFO94HfhOSH5FjySQspr3h4Iuq9JG1mO0nJZlTH7F4fV+ORP0yj3ZKgN58Bl
+
+--- OkS1vA83+ysvD8XdKZKhUCJtkidazlyykV3DPx+hHnQ
+ʮRvd,V\\
SnܼG
+^R.2?+mD,,Q}65Y4
\ No newline at end of file
diff --git a/secrets/netbird-dashboard-env.age b/secrets/netbird-dashboard-env.age
new file mode 100644
index 0000000000000000000000000000000000000000..62f84975095923f608cb3c5b9bb7eadcc0085e25
GIT binary patch
literal 1583
zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCSP@$>O6DpxSc2?;83
zNhLt}PpyC&)<#yxO>Aw&=mcl)ESM
z<}%-qT)EirW3uC+>l$jk+!vPGDsC3g{gs}_Gt