diff --git a/lib/default.nix b/lib/default.nix index ef9e36e..1436610 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -5,6 +5,9 @@ { isTailscaleDomain = domain: domain |> lib.hasSuffix ".ts.net"; + isPrivateDomain = + domain: domain |> lib.hasSuffix ".splitleaf.de"; + subdomainOf = domain: domain |> lib.splitString "." |> lib.head; rootDomainOf = domain: domain |> lib.splitString "." |> lib.tail |> lib.concatStringsSep "."; diff --git a/modules/system/services/caddy.nix b/modules/system/services/caddy.nix index 3bdcde1..d137a40 100644 --- a/modules/system/services/caddy.nix +++ b/modules/system/services/caddy.nix @@ -11,8 +11,11 @@ let virtualHosts = cfg.virtualHosts |> lib.attrValues |> lib.filter (value: value.enable); - publicHostsExist = virtualHosts |> lib.any (value: !lib'.isTailscaleDomain value.domain); + publicHostsExist = + virtualHosts + |> lib.any (value: (!lib'.isPrivateDomain value.domain) && (!lib'.isTailscaleDomain value.domain)); tailscaleHostsExist = virtualHosts |> lib.any (value: lib'.isTailscaleDomain value.domain); + privateHostsExist = virtualHosts |> lib.any (value: lib'.isPrivateDomain value.domain); webPorts = [ 80 @@ -30,6 +33,15 @@ let logFormat = "output file ${config.services.caddy.logDir}/${domain}.log { mode 640 }"; extraConfig = lib.concatLines [ (lib.optionalString (lib'.isTailscaleDomain domain) "bind tailscale/${lib'.subdomainOf domain}") + (lib.optionalString (lib'.isPrivateDomain domain) ( + let + certDir = config.security.acme.certs.${domain}.directory; + in + '' + tls ${certDir}/fullchain.pem ${certDir}/key.pem + bind ${config.custom.services.nebula.node.address} + '' + )) (lib.optionalString (port != null) "reverse_proxy localhost:${toString port}") (lib.optionalString (files != null) '' root * ${files} @@ -122,6 +134,52 @@ in ''; }; }) + + (lib.mkIf privateHostsExist { + sops.secrets = { + "porkbun/api-key".owner = config.users.users.acme.name; + "porkbun/secret-api-key".owner = config.users.users.acme.name; + }; + + security.acme = { + acceptTerms = true; + defaults = { + email = "acme@sstork.dev"; + dnsProvider = "porkbun"; + dnsResolver = "1.1.1.1:53"; + group = config.users.users.caddy.name; + credentialFiles = { + PORKBUN_API_KEY_FILE = config.sops.secrets."porkbun/api-key".path; + PORKBUN_SECRET_API_KEY_FILE = config.sops.secrets."porkbun/secret-api-key".path; + }; + reloadServices = [ "caddy.service" ]; + }; + + certs = + virtualHosts + |> lib.filter (host: lib'.isPrivateDomain host.domain) + |> lib.map (host: lib.nameValuePair host.domain { }) + |> lib.listToAttrs; + }; + + services.nebula.networks.mesh.firewall.inbound = [ + { + port = "80"; + proto = "tcp"; + host = "any"; + } + { + port = "443"; + proto = "tcp"; + host = "any"; + } + ]; + + systemd.services.caddy = { + requires = [ "nebula@mesh.service" ]; + after = [ "nebula@mesh.service" ]; + }; + }) ] ); } diff --git a/modules/system/services/nebula/dns.nix b/modules/system/services/nebula/dns.nix index 51b04fa..7d58b57 100644 --- a/modules/system/services/nebula/dns.nix +++ b/modules/system/services/nebula/dns.nix @@ -1,4 +1,10 @@ -{ config, lib, ... }: +{ + config, + self, + lib, + lib', + ... +}: let nebulaCfg = config.custom.services.nebula; cfg = nebulaCfg.node; @@ -25,8 +31,21 @@ in local-zone = "\"${nebulaCfg.network.domain}.\" static"; local-data = - nebulaCfg.nodes - |> lib.map (node: "\"${node.name}.${nebulaCfg.network.domain}. A ${node.address}\""); + let + nodeRecords = + nebulaCfg.nodes + |> lib.map (node: "\"${node.name}.${nebulaCfg.network.domain}. A ${node.address}\""); + serviceRecords = + self.nixosConfigurations + |> lib.attrValues + |> lib.concatMap ( + host: + host.config.meta.domains.local + |> lib.filter (domain: lib'.isPrivateDomain domain) + |> lib.map (domain: "\"${domain}. A ${host.config.custom.services.nebula.node.address}\"") + ); + in + nodeRecords ++ serviceRecords; }; forward-zone =