From ba90b1541c5c0510dd634df6fb7deae8a48fdf22 Mon Sep 17 00:00:00 2001 From: sefidel Date: Sat, 10 Feb 2024 07:18:22 +0900 Subject: feat(modules/expose)!: rewrite module to be more flexible --- modules/expose.nix | 62 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 16 deletions(-) (limited to 'modules/expose.nix') diff --git a/modules/expose.nix b/modules/expose.nix index 29531c5..8f9357d 100644 --- a/modules/expose.nix +++ b/modules/expose.nix @@ -9,7 +9,31 @@ in enable = mkEnableOption "expose services to network"; routes = mkOption { - type = types.attrsOf types.str; + type = types.attrsOf (types.submodule { + options = { + to = mkOption { + type = types.str; + example = "https://localhost:3000"; + description = "Destination address"; + }; + + ts = mkOption { + type = types.bool; + default = true; + description = "Whether to enable nginx & blocky for Tailscale routing"; + }; + cf = mkOption { + type = types.bool; + default = true; + description = "Whether to enable Cloudflare Tunnel for public routing"; + }; + configureNginx = mkOption { + type = types.bool; + default = true; + description = "Whether to configure nginx virtualHosts for this route"; + }; + }; + }); }; ssl = { @@ -22,7 +46,7 @@ in }; webmasterEmail = mkOption { type = types.str; description = "Email of the webmaster to be contacted for ACME events"; }; - tailscaleIp = mkOption { type = types.str; description = "Tailscale IP for this node"; }; + tailscaleIp = mkOption { type = types.str; description = "Tailscale IP of this node"; }; cloudflareUUID = mkOption { type = types.str; description = "UUID of the Cloudflare Tunnel"; }; secrets = { acme-credentials = mkOption { type = types.path; description = "Path to the acme environment file"; }; @@ -38,26 +62,32 @@ in } ]; - services.nginx.virtualHosts = mapAttrs (_: internal: { - locations."/".proxyPass = internal; - } // optionalAttrs (cfg.ssl.enable) { - forceSSL = true; - useACMEHost = cfg.ssl.acmeHost; - }) (filterAttrs - # Assume that reverse proxy is configured externally - (_: v: (!hasSuffix ":80" v) && (!hasSuffix ":443" v)) - cfg.routes); + services.nginx.virtualHosts = mapAttrs + (_: v: { + locations."/".proxyPass = v.to; + } // optionalAttrs (cfg.ssl.enable) { + forceSSL = true; + useACMEHost = cfg.ssl.acmeHost; + }) + (filterAttrs (_: v: v.configureNginx) cfg.routes); # Discard non-localhost mappings, and replace destination with tailscale IP + # Map localhost routes to tailscaleIp services.blocky.settings.customDNS.mapping = mapAttrs - (_: v: cfg.tailscaleIp) - (filterAttrs - (_: v: hasInfix "localhost" v) - cfg.routes); + (_: v: + if (hasInfix "localhost" v.to) + then cfg.tailscaleIp + else v.to) + (filterAttrs (_: v: v.ts) cfg.routes); services.cloudflared.tunnels."${cfg.cloudflareUUID}" = { credentialsFile = cfg.secrets.cloudflare-credentials; - ingress = cfg.routes; + ingress = mapAttrs + (_: v: + if v.configureNginx + then "https://localhost:443" + else v.to) + (filterAttrs (_: v: v.cf) cfg.routes); } // optionalAttrs (cfg.ssl.enable) { # TODO: This seems to have no effect. Remove? originRequest.originServerName = "*.${cfg.ssl.acmeHost}"; -- cgit 1.4.1