From a7a16378b2c3e874da8af36069924f774c97a55c Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Tue, 23 Dec 2025 14:42:26 +0100 Subject: [PATCH] nebula: Init module --- modules/system/services/nebula/ca.crt | 5 ++ modules/system/services/nebula/default.nix | 100 +++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 modules/system/services/nebula/ca.crt create mode 100644 modules/system/services/nebula/default.nix diff --git a/modules/system/services/nebula/ca.crt b/modules/system/services/nebula/ca.crt new file mode 100644 index 0000000..7059b2c --- /dev/null +++ b/modules/system/services/nebula/ca.crt @@ -0,0 +1,5 @@ +-----BEGIN NEBULA CERTIFICATE V2----- +MHugFYAEbWFpboQB/4UEaUdKdYYEayh99YIg5FsAhFthpvA/ELlR7NVFGvuIB5Zv +66n1h1qg0vumHY+DQHGky+1qxbGswdyDZBYfqctktyfJUMKk0TZIn6cqYLbydSZJ +J9HxMj2JWu/d/2nsh11uhRwquBH733AmXZ2DDgE= +-----END NEBULA CERTIFICATE V2----- diff --git a/modules/system/services/nebula/default.nix b/modules/system/services/nebula/default.nix new file mode 100644 index 0000000..106328e --- /dev/null +++ b/modules/system/services/nebula/default.nix @@ -0,0 +1,100 @@ +{ + config, + self, + lib, + ... +}: +let + cfg = config.custom.services.nebula.node; + + hostname = config.networking.hostName; + + lighthouses = + self.nixosConfigurations + |> lib.filterAttrs (name: _: name != hostname) + |> lib.attrValues + |> lib.map (value: value.config.custom.services.nebula.node) + |> lib.filter (nebula: nebula.enable) + |> lib.filter (nebula: nebula.isLighthouse); +in +{ + options.custom.services.nebula.node = { + enable = lib.mkEnableOption ""; + name = lib.mkOption { + type = lib.types.nonEmptyStr; + default = config.networking.hostName; + }; + address = lib.mkOption { + type = lib.types.nonEmptyStr; + default = ""; + }; + + isLighthouse = lib.mkEnableOption ""; + routableAddress = lib.mkOption { + type = lib.types.nullOr lib.types.nonEmptyStr; + default = null; + }; + routablePort = lib.mkOption { + type = lib.types.nullOr lib.types.port; + default = if cfg.isLighthouse then 47141 else null; + }; + + pubPath = lib.mkOption { + type = lib.types.path; + default = "${self}/hosts/${hostname}/keys/nebula.pub"; + }; + certPath = lib.mkOption { + type = lib.types.path; + default = "${self}/hosts/${hostname}/keys/nebula.crt"; + }; + }; + + config = lib.mkIf cfg.enable { + meta.ports.udp = lib.optional (cfg.routablePort != 0) cfg.routablePort; + + sops.secrets."nebula/host-key" = { + owner = config.users.users.nebula-main.name; + restartUnits = [ "nebula@main.service" ]; + }; + + services.nebula.networks.main = { + enable = true; + + ca = ./ca.crt; + cert = cfg.certPath; + key = config.sops.secrets."nebula/host-key".path; + + listen.port = cfg.routablePort; + + isLighthouse = cfg.isLighthouse; + lighthouses = lib.mkIf (!cfg.isLighthouse) ( + lighthouses |> lib.map (lighthouse: lighthouse.address) + ); + staticHostMap = + lighthouses + |> lib.map (lighthouse: { + name = lighthouse.address; + value = lib.singleton "${lighthouse.routableAddress}:${toString lighthouse.routablePort}"; + }) + |> lib.listToAttrs; + + firewall = { + outbound = lib.singleton { + host = "any"; + port = "any"; + proto = "any"; + }; + inbound = lib.singleton { + host = "any"; + port = "any"; + proto = "any"; + }; + }; + + settings = { + pki.disconnect_invalid = true; + cipher = "aes"; + }; + }; + }; +}