{ config, lib, namespace, ... }: with lib; let cfg = config.${namespace}.services.traefik; # Process reverseProxies into service and router configurations reverseProxyServiceConfigs = let makeService = reverseProxy: nameValuePair reverseProxy.service.name reverseProxy.service.config; in listToAttrs (map makeService cfg.reverseProxies); reverseProxyRouterConfigs = let makeRouter = reverseProxy: nameValuePair reverseProxy.router.subdomain reverseProxy.router.config; in listToAttrs (map makeRouter cfg.reverseProxies); domain = "mjallen.dev"; # Forward services authUrl = "http://localhost:9000/outpost.goauthentik.io"; cacheUrl = "http://localhost:9012"; hassUrl = "http://nuc-nixos.local:8123"; # Plugins traefikPlugins = { bouncer = { moduleName = "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"; version = "v1.4.5"; }; geoblock = { moduleName = "github.com/PascalMinder/geoblock"; version = "v0.2.5"; }; }; # Ports httpPort = 80; httpsPort = 443; traefikPort = 8080; metricsPort = 8082; forwardPorts = [ httpPort httpsPort traefikPort metricsPort ]; # misc letsEncryptEmail = "jalle008@proton.me"; configDir = "/media/nas/main/appdata"; in { imports = [ ./options.nix ./sops.nix ]; config = mkIf cfg.enable { networking.firewall = { allowedTCPPorts = forwardPorts; allowedUDPPorts = forwardPorts; }; # services.traefik = { # enable = true; # dataDir = "${configDir}/traefik"; # group = "jallen-nas"; # group; # environmentFiles = [ config.sops.templates."traefik.env".path ]; # static = { # # dir = "${configDir}/traefik"; # settings = { # entryPoints = { # web = { # address = ":${toString httpPort}"; # asDefault = true; # http.redirections.entrypoint = { # to = "websecure"; # scheme = "https"; # }; # }; # websecure = { # address = ":${toString httpsPort}"; # asDefault = true; # http.tls.certResolver = "letsencrypt"; # }; # metrics = { # address = ":${toString metricsPort}"; # Port for metrics # }; # }; # log = { # level = "INFO"; # }; # metrics = { # prometheus = { # entryPoint = "metrics"; # addEntryPointsLabels = true; # addServicesLabels = true; # buckets = [ # 0.1 # 0.3 # 1.2 # 5.0 # ]; # Response time buckets # }; # }; # certificatesResolvers.letsencrypt.acme = { # email = letsEncryptEmail; # storage = "${config.services.traefik.dataDir}/acme.json"; # dnsChallenge = { # provider = "cloudflare"; # resolvers = [ # "1.1.1.1:53" # "8.8.8.8:53" # ]; # }; # }; # # Access the Traefik dashboard on :8080 # api = { # dashboard = true; # insecure = true; # }; # experimental = { # plugins = traefikPlugins; # }; # }; # }; # dynamic = { # dir = "/run/traefik"; # files = { # "serversTransports".settings.http = { # serversTransports = { # internal-https = { # insecureSkipVerify = true; # }; # http1 = { # serverName = "localhost"; # disableHTTP2 = true; # }; # }; # }; # "middlewares-authentik".settings.http = { # middlewares = { # authentik = { # forwardAuth = { # tls.insecureSkipVerify = true; # address = "${authUrl}/auth/traefik"; # trustForwardHeader = true; # authResponseHeaders = [ # "X-authentik-username" # "X-authentik-groups" # "X-authentik-email" # "X-authentik-name" # "X-authentik-uid" # "X-authentik-jwt" # "X-authentik-meta-jwks" # "X-authentik-meta-outpost" # "X-authentik-meta-provider" # "X-authentik-meta-app" # "X-authentik-meta-version" # ]; # }; # }; # }; # }; # "middlewares-crowdsec".settings.http = { # middlewares = { # crowdsec = { # plugin = { # bouncer = { # enabled = true; # crowdsecLapiKeyFile = config.sops.secrets."jallen-nas/traefik/crowdsec/lapi-key".path; # crowdsecLapiScheme = "http"; # crowdsecLapiHost = "localhost:8181"; # crowdsecLapiPath = "/"; # crowdsecLapiTLSInsecureVerify = false; # crowdsecCapiMachineIdFile = config.sops.secrets."jallen-nas/traefik/crowdsec/capi-machine-id".path; # crowdsecCapiPasswordFile = config.sops.secrets."jallen-nas/traefik/crowdsec/capi-password".path; # crowdsecCapiScenarios = [ ]; # }; # }; # }; # }; # }; # "middlewares-geoblock".settings.http = { # middlewares = { # whitelist-geoblock = { # plugin = { # geoblock = { # silentStartUp = false; # allowLocalRequests = true; # logLocalRequests = false; # logAllowedRequests = false; # logApiRequests = false; # api = "https://get.geojs.io/v1/ip/country/{ip}"; # apiTimeoutMs = 500; # cacheSize = 25; # forceMonthlyUpdate = true; # allowUnknownCountries = false; # unknownCountryApiResponse = "nil"; # blackListMode = false; # countries = [ # "CA" # "US" # ]; # }; # }; # }; # }; # }; # "middlewares-ipallowlist".settings.http = { # middlewares = { # internal-ipallowlist = { # ipAllowList = { # sourceRange = [ # "127.0.0.1/32" # "10.0.1.0/24" # ]; # }; # }; # }; # }; # "services-auth".settings.http = { # services = { # auth.loadBalancer.servers = [ # { # url = authUrl; # } # ]; # }; # }; # "services-cache".settings.http = { # services = { # cache.loadBalancer = { # servers = [ # { # url = cacheUrl; # } # ]; # serversTransport = "http1"; # }; # }; # }; # "services-nginx".settings.http = { # services = { # nginx.loadBalancer.servers = [ # { # url = "http://localhost:8188"; # } # ]; # }; # }; # "services-generated".settings.http = reverseProxyServiceConfigs; # "routers-auth".settings.http = { # routers = { # auth = { # entryPoints = [ "websecure" ]; # rule = "HostRegexp(`{subdomain:[a-z]+}.mjallen.dev`) && PathPrefix(`/outpost.goauthentik.io/`)"; # service = "auth"; # middlewares = [ # "crowdsec" # "whitelist-geoblock" # ]; # priority = 15; # tls.certResolver = "letsencrypt"; # }; # }; # }; # "routers-matrix2".settings.http = { # routers = { # matrix2 = { # entryPoints = [ "websecure" ]; # rule = "Host(`matrix.mjallen.dev`) && PathPrefix(`/.well-known/matrix/`)"; # service = "nginx"; # middlewares = [ # "crowdsec" # "whitelist-geoblock" # ]; # priority = 1; # tls.certResolver = "letsencrypt"; # }; # }; # }; # "routers-matrix3".settings.http = { # routers = { # matrix3 = { # entryPoints = [ "websecure" ]; # rule = "Host(`mjallen.dev`) && PathPrefix(`/.well-known/matrix/`)"; # service = "nginx"; # middlewares = [ # "crowdsec" # "whitelist-geoblock" # ]; # priority = 1; # tls.certResolver = "letsencrypt"; # }; # }; # }; # "routers-cache".settings.http = { # routers = { # cache = { # entryPoints = [ "websecure" ]; # rule = "Host(`cache.${domain}`)"; # service = "cache"; # middlewares = [ ]; # priority = 10; # tls.certResolver = "letsencrypt"; # }; # }; # }; # "home-assistant".settings.http = { # services = { # hass.loadBalancer.servers = [ # { # url = hassUrl; # } # ]; # }; # routers = { # hass = { # entryPoints = [ "websecure" ]; # rule = "Host(`hass.${domain}`)"; # service = "hass"; # middlewares = [ # "crowdsec" # "whitelist-geoblock" # # "authentik" # ]; # priority = 10; # tls.certResolver = "letsencrypt"; # }; # }; # }; # "routers-generated".settings.http = reverseProxyRouterConfigs; # }; # }; # }; }; }