about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--modules/expose.nix62
1 files changed, 46 insertions, 16 deletions
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}";