diff --git a/hosts/common/ports.nix b/hosts/common/ports.nix index a288156..b8e0715 100644 --- a/hosts/common/ports.nix +++ b/hosts/common/ports.nix @@ -37,9 +37,7 @@ slash-nemoti = 3016; kestra = 3018; outline = 3019; - pangolin = 3020; - pangolin-api = 3021; - pangolin-ws = 3022; + authentik = 3023; # Home automation homarr = 7575; diff --git a/hosts/m3-atlas/secrets.nix b/hosts/m3-atlas/secrets.nix index adaf06d..330fa31 100644 --- a/hosts/m3-atlas/secrets.nix +++ b/hosts/m3-atlas/secrets.nix @@ -56,10 +56,6 @@ file = ../../secrets/exa-key.age; owner = "m3tam3re"; }; - outline-key = { - file = ../../secrets/outline-key.age; - owner = "m3tam3re"; - }; basecamp-client-id = { file = ../../secrets/basecamp-client-id.age; owner = "m3tam3re"; @@ -68,6 +64,7 @@ file = ../../secrets/basecamp-client-secret.age; owner = "m3tam3re"; }; + authentik-env = {file = ../../secrets/authentik-env.age;}; }; }; } diff --git a/hosts/m3-atlas/services/containers/authentik.nix b/hosts/m3-atlas/services/containers/authentik.nix new file mode 100644 index 0000000..6712066 --- /dev/null +++ b/hosts/m3-atlas/services/containers/authentik.nix @@ -0,0 +1,67 @@ +{config, ...}: let + image = "ghcr.io/goauthentik/server:2026.2.0"; + + serverIp = "10.89.0.22"; + workerIp = "10.89.0.23"; + + postgresHost = "10.89.0.1"; + postgresPort = config.m3ta.ports.get "postgres"; + authentikPort = config.m3ta.ports.get "authentik"; + + sharedEnv = { + AUTHENTIK_POSTGRESQL__HOST = postgresHost; + AUTHENTIK_POSTGRESQL__PORT = toString postgresPort; + AUTHENTIK_POSTGRESQL__USER = "authentik"; + AUTHENTIK_POSTGRESQL__NAME = "authentik"; + }; +in { + virtualisation.oci-containers.containers = { + "authentik-server" = { + inherit image; + cmd = ["server"]; + environment = sharedEnv; + environmentFiles = [config.age.secrets.authentik-env.path]; + ports = ["127.0.0.1:${toString authentikPort}:9000"]; + volumes = [ + "authentik_media:/media" + "authentik_templates:/templates" + ]; + extraOptions = [ + "--add-host=postgres:${postgresHost}" + "--ip=${serverIp}" + "--network=web" + ]; + }; + + "authentik-worker" = { + inherit image; + cmd = ["worker"]; + user = "root"; + environment = sharedEnv; + environmentFiles = [config.age.secrets.authentik-env.path]; + volumes = [ + "authentik_media:/media" + "authentik_certs:/certs" + "authentik_templates:/templates" + ]; + extraOptions = [ + "--add-host=postgres:${postgresHost}" + "--ip=${workerIp}" + "--network=web" + ]; + }; + }; + + services.traefik.dynamicConfigOptions.http = { + services.authentik.loadBalancer.servers = [ + {url = "http://localhost:${toString authentikPort}/";} + ]; + + routers.authentik = { + rule = "Host(`auth.m3ta.dev`)"; + tls = {certResolver = "godaddy";}; + service = "authentik"; + entrypoints = "websecure"; + }; + }; +} diff --git a/hosts/m3-atlas/services/containers/default.nix b/hosts/m3-atlas/services/containers/default.nix index f3399fd..2579a67 100644 --- a/hosts/m3-atlas/services/containers/default.nix +++ b/hosts/m3-atlas/services/containers/default.nix @@ -11,6 +11,7 @@ ./restreamer.nix ./slash.nix ./slash-nemoti.nix + ./authentik.nix ]; system.activationScripts.createPodmanNetworkWeb = lib.mkAfter '' if ! /run/current-system/sw/bin/podman network exists web; then diff --git a/hosts/m3-atlas/services/containers/netbird.nix b/hosts/m3-atlas/services/containers/netbird.nix index 605cc70..2b67dba 100644 --- a/hosts/m3-atlas/services/containers/netbird.nix +++ b/hosts/m3-atlas/services/containers/netbird.nix @@ -1,6 +1,5 @@ { config, - lib, pkgs, ... }: let @@ -42,7 +41,7 @@ auth = { issuer = "https://${domain}/oauth2"; - # localAuthDisabled = true; + localAuthDisabled = true; signKeyRefreshEnabled = true; dashboardRedirectURIs = [ "https://${domain}/nb-auth" diff --git a/hosts/m3-atlas/services/containers/pangolin.nix b/hosts/m3-atlas/services/containers/pangolin.nix deleted file mode 100644 index 0bf5a34..0000000 --- a/hosts/m3-atlas/services/containers/pangolin.nix +++ /dev/null @@ -1,211 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: let - # Define the Pangolin configuration as a Nix attribute set - pangolinConfig = { - app = { - dashboard_url = "https://vpn.m3tam3re.com"; - log_level = "info"; - save_logs = false; - }; - - domains = { - vpn = { - base_domain = "m3tam3re.com"; - cert_resolver = "godaddy"; - prefer_wildcard_cert = false; - }; - }; - - server = { - external_port = 3000; - internal_port = 3001; - next_port = 3002; - internal_hostname = "pangolin"; - session_cookie_name = "p_session_token"; - resource_access_token_param = "p_token"; - resource_session_request_param = "p_session_request"; - }; - - traefik = { - cert_resolver = "godaddy"; - http_entrypoint = "web"; - https_entrypoint = "websecure"; - }; - - gerbil = { - start_port = 51820; - base_endpoint = "vpn.m3tam3re.com"; - use_subdomain = false; - block_size = 24; - site_block_size = 30; - subnet_group = "100.89.137.0/20"; - }; - - rate_limits = { - global = { - window_minutes = 1; - max_requests = 100; - }; - }; - - email = { - smtp_host = config.age.secrets.smtp-host.path; - smtp_port = 587; - smtp_user = config.age.secrets.smtp-user.path; - smtp_pass = config.age.secrets.smtp-pass.path; - no_reply = config.age.secrets.smtp-user.path; - }; - - users = { - server_admin = { - email = "admin@m3tam3re.com"; - password = config.age.secrets.pangolin-admin-password.path; - }; - }; - - flags = { - require_email_verification = true; - disable_signup_without_invite = true; - disable_user_create_org = true; - allow_raw_resources = true; - allow_base_domain_resources = true; - }; - }; - - # Convert Nix attribute set to YAML using a simpler approach - pangolinConfigYaml = pkgs.writeTextFile { - name = "config.yml"; - text = lib.generators.toYAML {} pangolinConfig; - }; -in { - # Define the containers - virtualisation.oci-containers.containers = { - "pangolin" = { - image = "fosrl/pangolin:1.1.0"; - autoStart = true; - volumes = [ - "${pangolinConfigYaml}:/app/config/config.yml:ro" # Mount the config file directly - "pangolin_config:/app/config/data" # Volume for persistent data - ]; - ports = [ - "127.0.0.1:3020:3001" # API server - "127.0.0.1:3021:3002" # Next.js server - "127.0.0.1:3022:3000" # API/WebSocket server - ]; - extraOptions = ["--ip=10.89.0.20" "--network=web"]; - }; - - "gerbil" = { - image = "fosrl/gerbil:1.0.0"; - autoStart = true; - volumes = [ - "pangolin_config:/var/config" # Share the volume for persistent data - ]; - cmd = [ - "--reachableAt=http://gerbil:3003" - "--generateAndSaveKeyTo=/var/config/key" - "--remoteConfig=http://pangolin:3001/api/v1/gerbil/get-config" - "--reportBandwidthTo=http://pangolin:3001/api/v1/gerbil/receive-bandwidth" - ]; - ports = [ - "51820:51820/udp" # WireGuard port - ]; - extraOptions = [ - "--ip=10.89.0.21" - "--network=web" - "--cap-add=NET_ADMIN" - "--cap-add=SYS_MODULE" - ]; - }; - }; - - # Secrets for Pangolin - # age.secrets = { - # "smtp-host" = { - # file = ../secrets/smtp-host.age; - # owner = "root"; - # group = "root"; - # mode = "0400"; - # }; - # "smtp-user" = { - # file = ../secrets/smtp-user.age; - # owner = "root"; - # group = "root"; - # mode = "0400"; - # }; - # "smtp-pass" = { - # file = ../secrets/smtp-pass.age; - # owner = "root"; - # group = "root"; - # mode = "0400"; - # }; - # "pangolin-admin-password" = { - # file = ../secrets/pangolin-admin-password.age; - # owner = "root"; - # group = "root"; - # mode = "0400"; - # }; - # }; - - # Traefik configuration for Pangolin - services.traefik.dynamicConfigOptions = { - http = { - # Next.js service (front-end) - services.pangolin-next-service.loadBalancer.servers = [ - {url = "http://localhost:3021";} - ]; - - # API service - services.pangolin-api-service.loadBalancer.servers = [ - {url = "http://localhost:3022";} - ]; - - # Routers - routers = { - # Next.js router (handles everything except API paths) - "pangolin-next" = { - rule = "Host(`vpn.m3tam3re.com`) && !PathPrefix(`/api/v1`)"; - service = "pangolin-next-service"; - entrypoints = ["websecure"]; - tls = { - certResolver = "godaddy"; - }; - }; - - # API router - "pangolin-api" = { - rule = "Host(`vpn.m3tam3re.com`) && PathPrefix(`/api/v1`)"; - service = "pangolin-api-service"; - entrypoints = ["websecure"]; - tls = { - certResolver = "godaddy"; - }; - }; - }; - }; - }; - - # Add HTTP provider to Traefik for dynamic configuration from Pangolin - services.traefik.staticConfigOptions.providers.http = { - endpoint = "http://localhost:3020/api/v1/traefik-config"; - pollInterval = "5s"; - }; - - # Add experimental section for Badger plugin - services.traefik.staticConfigOptions.experimental = { - plugins = { - #TODO create an overlay for the plugin - badger = { - moduleName = "github.com/fosrl/badger"; - version = "v1.0.0"; - }; - }; - }; - - # Firewall configuration for WireGuard - networking.firewall.allowedUDPPorts = [51820]; # WireGuard port -} diff --git a/hosts/m3-atlas/services/default.nix b/hosts/m3-atlas/services/default.nix index 6a49f8d..5a7b668 100644 --- a/hosts/m3-atlas/services/default.nix +++ b/hosts/m3-atlas/services/default.nix @@ -5,6 +5,7 @@ ./gitea-actions-runner.nix ./minio.nix ./mysql.nix + ./netbird.nix ./n8n.nix ./paperless.nix ./postgres.nix diff --git a/hosts/m3-atlas/services/netbird.nix b/hosts/m3-atlas/services/netbird.nix new file mode 100644 index 0000000..580d4fa --- /dev/null +++ b/hosts/m3-atlas/services/netbird.nix @@ -0,0 +1,3 @@ +{ + services.netbird.enable = true; +} diff --git a/hosts/m3-atlas/services/postgres.nix b/hosts/m3-atlas/services/postgres.nix index ee7de06..85658d2 100644 --- a/hosts/m3-atlas/services/postgres.nix +++ b/hosts/m3-atlas/services/postgres.nix @@ -27,6 +27,7 @@ host baserow baserow 10.89.0.0/24 scram-sha-256 host kestra kestra 10.89.0.0/24 scram-sha-256 host netbird netbird 10.89.0.0/24 scram-sha-256 + host authentik authentik 10.89.0.0/24 scram-sha-256 # Deny all other connections local all all reject @@ -37,7 +38,7 @@ services.postgresqlBackup = { enable = true; startAt = "03:10:00"; - databases = ["baserow" "paperless" "kestra"]; + databases = ["baserow" "paperless" "kestra" "authentik" "netbird"]; }; networking.firewall = { extraCommands = '' diff --git a/hosts/m3-kratos/services/default.nix b/hosts/m3-kratos/services/default.nix index dc1d637..f29e14d 100644 --- a/hosts/m3-kratos/services/default.nix +++ b/hosts/m3-kratos/services/default.nix @@ -3,6 +3,7 @@ ./containers ./mem0.nix ./n8n.nix + ./netbird.nix ./postgres.nix ./sound.nix ./udev.nix diff --git a/hosts/m3-kratos/services/netbird.nix b/hosts/m3-kratos/services/netbird.nix new file mode 100644 index 0000000..8a73d6e --- /dev/null +++ b/hosts/m3-kratos/services/netbird.nix @@ -0,0 +1,5 @@ +{pkgs, ...}: { + services.netbird.enable = true; + environment.systemPackages = [pkgs.netbird-ui]; + networking.firewall.checkReversePath = "loose"; +} diff --git a/secrets.nix b/secrets.nix index 4d8e9d2..a578235 100644 --- a/secrets.nix +++ b/secrets.nix @@ -13,6 +13,7 @@ let in { "secrets/anytype-key.age".publicKeys = systems ++ users; "secrets/anytype-key-ares.age".publicKeys = systems ++ users; + "secrets/authentik-env.age".publicKeys = systems ++ users; "secrets/baserow-env.age".publicKeys = systems ++ users; "secrets/ghost-env.age".publicKeys = systems ++ users; "secrets/littlelink-m3tam3re.age".publicKeys = systems ++ users; diff --git a/secrets/authentik-env.age b/secrets/authentik-env.age new file mode 100644 index 0000000..1de2de4 Binary files /dev/null and b/secrets/authentik-env.age differ