aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/expose.nix67
1 files changed, 67 insertions, 0 deletions
diff --git a/modules/expose.nix b/modules/expose.nix
new file mode 100644
index 0000000..29531c5
--- /dev/null
+++ b/modules/expose.nix
@@ -0,0 +1,67 @@
+{ config, lib, ... }:
+
+with lib;
+let
+ cfg = config.modules.expose;
+in
+{
+ options.modules.expose = {
+ enable = mkEnableOption "expose services to network";
+
+ routes = mkOption {
+ type = types.attrsOf types.str;
+ };
+
+ ssl = {
+ enable = mkEnableOption "SSL on all routes";
+ acmeHost = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = "ACMEHost for the certificate";
+ };
+ };
+
+ 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"; };
+ 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"; };
+ cloudflare-credentials = mkOption { type = types.path; description = "Path to the cloudflare tunnel credentials"; };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ assertions = [
+ {
+ assertion = cfg.ssl.enable -> cfg.ssl.acmeHost != null;
+ message = "ssl.acmeHost must be set when enabling SSL";
+ }
+ ];
+
+ 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);
+
+ # Discard non-localhost mappings, and replace destination with tailscale IP
+ services.blocky.settings.customDNS.mapping = mapAttrs
+ (_: v: cfg.tailscaleIp)
+ (filterAttrs
+ (_: v: hasInfix "localhost" v)
+ cfg.routes);
+
+ services.cloudflared.tunnels."${cfg.cloudflareUUID}" = {
+ credentialsFile = cfg.secrets.cloudflare-credentials;
+ ingress = cfg.routes;
+ } // optionalAttrs (cfg.ssl.enable) {
+ # TODO: This seems to have no effect. Remove?
+ originRequest.originServerName = "*.${cfg.ssl.acmeHost}";
+ originRequest.caPool = config.security.acme.certs.${cfg.ssl.acmeHost}.directory;
+ };
+ };
+}