From 82844a3bb43156fbf0f7af3b5c59874029822c78 Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Thu, 15 Jan 2026 21:05:40 +0100 Subject: [PATCH 1/5] networking: Set overlay options in nebula module --- modules/system/networking.nix | 15 ++++++--------- modules/system/services/nebula/default.nix | 8 ++++++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/modules/system/networking.nix b/modules/system/networking.nix index bf52aec..2284e56 100644 --- a/modules/system/networking.nix +++ b/modules/system/networking.nix @@ -21,18 +21,15 @@ in overlay = { networkAddress = lib.mkOption { type = lib.types.nonEmptyStr; - default = "10.254.250.0"; - readOnly = true; + default = ""; }; prefixLength = lib.mkOption { - type = lib.types.ints.between 0 32; - default = 24; - readOnly = true; + type = lib.types.nullOr (lib.types.ints.between 0 32); + default = null; }; domain = lib.mkOption { type = lib.types.nonEmptyStr; - default = "splitleaf.de"; - readOnly = true; + default = ""; }; address = lib.mkOption { @@ -41,11 +38,11 @@ in }; interface = lib.mkOption { type = lib.types.nonEmptyStr; - default = "nebula"; + default = ""; }; systemdUnit = lib.mkOption { type = lib.types.nonEmptyStr; - default = "nebula@mesh.service"; + default = ""; }; dnsServers = lib.mkOption { diff --git a/modules/system/services/nebula/default.nix b/modules/system/services/nebula/default.nix index 330c6a3..423f5f6 100644 --- a/modules/system/services/nebula/default.nix +++ b/modules/system/services/nebula/default.nix @@ -30,6 +30,14 @@ in message = "'${netCfg.hostname}' is a Nebula lighthouse, but underlay.isPublic is not set. Lighthouses must be publicly reachable."; }; + custom.networking.overlay = { + networkAddress = "10.254.250.0"; + prefixLength = 24; + domain = "splitleaf.de"; + interface = "nebula"; + systemdUnit = "nebula@mesh.service"; + }; + meta.ports.udp = lib.optional netCfg.underlay.isPublic publicPort; sops.secrets."nebula/host-key" = { From 2f246153d4704de3752362a21f46775b56f0bfda Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Thu, 15 Jan 2026 22:18:22 +0100 Subject: [PATCH 2/5] caddy: Add `extraConfig` option --- modules/system/services/caddy.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/system/services/caddy.nix b/modules/system/services/caddy.nix index 6be5904..99f0200 100644 --- a/modules/system/services/caddy.nix +++ b/modules/system/services/caddy.nix @@ -23,6 +23,7 @@ let domain, port, files, + extraConfig, ... }: lib.nameValuePair domain { @@ -43,6 +44,7 @@ let encode file_server '') + (lib.optionalString (extraConfig != null) extraConfig) ]; }; in @@ -73,6 +75,10 @@ in type = lib.types.nullOr lib.types.path; default = null; }; + extraConfig = lib.mkOption { + type = lib.types.nullOr lib.types.lines; + default = null; + }; }; } ) From d73e3744a8213e1c39c1122ef75b750f53e691a6 Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Thu, 15 Jan 2026 22:20:48 +0100 Subject: [PATCH 3/5] vps-public: Only allow access to radicale's login page over vpn --- hosts/vps-public/default.nix | 149 +++++++++++++++++++---------------- 1 file changed, 81 insertions(+), 68 deletions(-) diff --git a/hosts/vps-public/default.nix b/hosts/vps-public/default.nix index 329e0e3..bbbfa13 100644 --- a/hosts/vps-public/default.nix +++ b/hosts/vps-public/default.nix @@ -13,77 +13,90 @@ ports.validate = true; }; - custom = { - persistence.enable = true; + custom = + let + sproutedDomain = "sprouted.cloud"; + in + { + persistence.enable = true; - sops.enable = true; + sops.enable = true; - boot.loader.systemd-boot.enable = true; + boot.loader.systemd-boot.enable = true; - networking = { - overlay.address = "10.254.250.4"; - underlay = { - interface = "enp1s0"; - address = "167.235.73.246"; - isPublic = true; + networking = { + overlay.address = "10.254.250.4"; + underlay = { + interface = "enp1s0"; + address = "167.235.73.246"; + isPublic = true; + }; + isServer = true; }; - isServer = true; + + services = { + gc = { + enable = true; + onlyCleanRoots = true; + }; + + nebula.enable = true; + sshd.enable = true; + + caddy.virtualHosts."dav.${sproutedDomain}" = { + inherit (config.custom.web-services.radicale) port; + extraConfig = '' + respond /.web/ "Access denied" 403 { + close + } + ''; + }; + }; + + web-services = + let + privateDomain = config.custom.networking.overlay.domain; + sstorkDomain = "sstork.dev"; + in + { + personal-blog = { + enable = true; + domain = sstorkDomain; + }; + + forgejo = { + enable = true; + domain = "git.${sstorkDomain}"; + doBackups = true; + }; + + outline = { + enable = true; + domain = "wiki.${sproutedDomain}"; + doBackups = true; + }; + + it-tools = { + enable = true; + domain = "tools.${sproutedDomain}"; + }; + + privatebin = { + enable = true; + domain = "pastebin.${sproutedDomain}"; + branding.name = "SproutedBin"; + }; + + radicale = { + enable = true; + domain = "dav.${privateDomain}"; + doBackups = true; + }; + + alloy = { + enable = true; + domain = "alloy.${config.networking.hostName}.${privateDomain}"; + }; + }; }; - - services = { - gc = { - enable = true; - onlyCleanRoots = true; - }; - - nebula.enable = true; - sshd.enable = true; - }; - - web-services = - let - sstorkDomain = "sstork.dev"; - sproutedDomain = "sprouted.cloud"; - in - { - personal-blog = { - enable = true; - domain = sstorkDomain; - }; - - forgejo = { - enable = true; - domain = "git.${sstorkDomain}"; - doBackups = true; - }; - - outline = { - enable = true; - domain = "wiki.${sproutedDomain}"; - doBackups = true; - }; - - it-tools = { - enable = true; - domain = "tools.${sproutedDomain}"; - }; - - privatebin = { - enable = true; - domain = "pastebin.${sproutedDomain}"; - branding.name = "SproutedBin"; - }; - - radicale = { - enable = true; - domain = "dav.${sproutedDomain}"; - doBackups = true; - }; - - alloy = { - enable = true; - domain = "alloy.${config.networking.hostName}.${config.custom.networking.overlay.domain}"; - }; - }; - }; } From 9299842ce092c07bbe1d17e2eb27c149f8e7dcf6 Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Thu, 15 Jan 2026 22:21:25 +0100 Subject: [PATCH 4/5] vps-monitor: Only allow writes to ntfy over vpn --- hosts/vps-monitor/default.nix | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/hosts/vps-monitor/default.nix b/hosts/vps-monitor/default.nix index a86ae4f..f4d95e4 100644 --- a/hosts/vps-monitor/default.nix +++ b/hosts/vps-monitor/default.nix @@ -40,6 +40,14 @@ nebula.enable = true; sshd.enable = true; dns.enable = true; + + caddy.virtualHosts."alerts.sprouted.cloud" = { + inherit (config.custom.web-services.ntfy) port; + extraConfig = '' + @putpost method PUT POST + respond @putpost "Access denied" 403 { close } + ''; + }; }; web-services = @@ -59,7 +67,7 @@ ntfy = { enable = true; - domain = "alerts.sprouted.cloud"; + domain = "alerts.${privateDomain}"; }; grafana = { From 92d61afc401500944a81385dcdb4a7ba2e45f1c2 Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Thu, 15 Jan 2026 22:39:28 +0100 Subject: [PATCH 5/5] gatus: Fix ntfy url --- modules/system/web-services/gatus.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/web-services/gatus.nix b/modules/system/web-services/gatus.nix index 12105c6..d8dd96b 100644 --- a/modules/system/web-services/gatus.nix +++ b/modules/system/web-services/gatus.nix @@ -113,7 +113,7 @@ in connectivity.checker.target = "1.1.1.1:53"; # Cloudflare DNS alerting.ntfy = { topic = "uptime"; - url = "https://alerts.sprouted.cloud"; + url = "https://alerts.${config.custom.networking.overlay.domain}"; click = "https://${cfg.domain}"; default-alert = { enable = true;