From f7fa85cc1fcde9c161d5baf03effae614357e30e Mon Sep 17 00:00:00 2001 From: WilliButz Date: Wed, 4 Oct 2023 17:55:39 +0200 Subject: [PATCH] module: add nginx support with cert auto-discovery --- flake.nix | 11 +++++++---- module.nix | 35 +++++++++++++++++++++++++++++++++++ test.nix | 17 +++++++++++++---- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/flake.nix b/flake.nix index 6c0ec3a..b43825f 100644 --- a/flake.nix +++ b/flake.nix @@ -197,10 +197,13 @@ ''; }; }; - checks.default = (import ./test.nix { - inherit pkgs authentik-version; - inherit (self) nixosModules; - }); + checks = { + default = self.checks.${system}.vmtest; + vmtest = (import ./test.nix { + inherit pkgs authentik-version; + inherit (self) nixosModules; + }); + }; devShells.default = pkgs.mkShell { packages = [ # to generate a v2 lockfile from the v3 lockfile provided by upstream: diff --git a/module.nix b/module.nix index c93f38a..b51ad35 100644 --- a/module.nix +++ b/module.nix @@ -7,6 +7,9 @@ let inherit (lib) types; + inherit (lib.attrsets) + recursiveUpdate; + inherit (lib.modules) mkDefault mkIf @@ -47,6 +50,19 @@ in default = true; }; + nginx = { + enable = mkEnableOption "basic nginx configuration"; + enableACME = mkEnableOption "Let's Encrypt and certificate discovery"; + host = mkOption { + type = types.str; + example = "auth.example.com"; + description = mdDoc '' + Specify the name for the server in {option}`services.nginx.virtualHosts` and + for the associated Let's Encrypt certificate. + ''; + }; + }; + environmentFile = mkOption { type = types.nullOr types.path; default = null; @@ -106,6 +122,7 @@ in name = mkDefault "authentik"; host = mkDefault ""; }; + cert_discovery_dir = mkIf (cfg.nginx.enable && cfg.nginx.enableACME) "env://CREDENTIALS_DIRECTORY"; }; redis.servers.authentik = { enable = true; @@ -154,6 +171,10 @@ in # TODO maybe make this configurable ExecStart = "${cfg.authentikComponents.celery}/bin/celery -A authentik.root.celery worker -Ofair --max-tasks-per-child=1 --autoscale 3,1 -E -B -s /tmp/celerybeat-schedule -Q authentik,authentik_scheduled,authentik_events"; EnvironmentFile = mkIf (cfg.environmentFile != null) [ cfg.environmentFile ]; + LoadCredential = mkIf (cfg.nginx.enable && cfg.nginx.enableACME) [ + "${cfg.nginx.host}.pem:${config.security.acme.certs.${cfg.nginx.host}.directory}/fullchain.pem" + "${cfg.nginx.host}.key:${config.security.acme.certs.${cfg.nginx.host}.directory}/key.pem" + ]; }; }; authentik = { @@ -184,6 +205,20 @@ in }; }; }; + + services.nginx = mkIf cfg.nginx.enable { + enable = true; + recommendedTlsSettings = true; + recommendedProxySettings = true; + virtualHosts.${cfg.nginx.host} = { + inherit (cfg.nginx) enableACME; + forceSSL = cfg.nginx.enableACME; + locations."/" = { + proxyWebsockets = true; + proxyPass = "https://localhost:9443"; + }; + }; + }; })) # LDAP outpost diff --git a/test.nix b/test.nix index 767500a..0d76509 100644 --- a/test.nix +++ b/test.nix @@ -25,6 +25,10 @@ pkgs.nixosTest { services.authentik = { enable = true; environmentFile = authentik-env; + nginx = { + enable = true; + host = "localhost"; + }; }; services.xserver.enable = true; @@ -53,7 +57,7 @@ pkgs.nixosTest { with subtest("Frontend renders"): machine.succeed("su - alice -c 'firefox http://localhost:9000/if/flow/initial-setup' >&2 &") machine.wait_for_text("Welcome to authentik") - machine.screenshot("initial-setup_1") + machine.screenshot("1_rendered_frontend") with subtest("admin account setup works"): machine.send_key("tab") @@ -66,15 +70,20 @@ pkgs.nixosTest { machine.send_key("ret") machine.wait_for_text("My applications") machine.send_key("esc") - machine.screenshot("initial-setup_2") + machine.screenshot("2_initial_setup_successful") with subtest("admin settings render and version as expected"): machine.succeed("su - alice -c 'firefox http://localhost:9000/if/admin' >&2 &") machine.wait_for_text("General system status") - machine.screenshot("initial-setup_3") + machine.screenshot("3_rendered_admin_interface") machine.succeed("su - alice -c 'xdotool click 1' >&2") machine.succeed("su - alice -c 'xdotool key --delay 100 Page_Down Page_Down' >&2") machine.wait_for_text("${authentik-version}") - machine.screenshot("initial-setup_4") + machine.screenshot("4_correct_version_in_admin_interface") + + with subtest("nginx proxies to authentik"): + machine.succeed("su - alice -c 'firefox http://localhost/' >&2 &") + machine.wait_for_text("authentik") + machine.screenshot("5_nginx_proxies_requests") ''; }