From bf2aefd507b04b4cd636ed66c8f50ab7b21d4624 Mon Sep 17 00:00:00 2001 From: Tim Van Baak Date: Tue, 6 Jun 2023 13:47:57 -0700 Subject: [PATCH] Add nginx reverse proxy configuration --- module.nix | 40 +++++++++++++++++++++++++++++++++++----- tests/demo.nix | 36 +----------------------------------- 2 files changed, 36 insertions(+), 40 deletions(-) diff --git a/module.nix b/module.nix index 9477496..40addbd 100644 --- a/module.nix +++ b/module.nix @@ -1,7 +1,7 @@ flake: { config, lib, pkgs, ... }: let - inherit (lib) mapAttrsToList mkEnableOption mkMerge mkOption types; + inherit (lib) filterAttrs foldl imap1 mapAttrsToList mkEnableOption mkIf mkMerge mkOption types; intakeCfg = config.services.intake; in { options = { @@ -9,13 +9,19 @@ in { listen.addr = mkOption { type = types.str; default = "0.0.0.0"; - description = "Listen address for the nginx entry point."; + description = "The listen address for the entry point to intake services. This endpoint will redirect to a local port based on the request's HTTP Basic Auth credentials."; }; listen.port = mkOption { type = types.port; - default = 80; - description = "Listen port for the nginx entry point."; + default = 8032; + description = "The listen port for the entry point to intake services. This endpoint will redirect to a local port based on the request's HTTP Basic Auth credentials."; + }; + + internalPortStart = mkOption { + type = types.port; + default = 24130; + description = "The first port to use for internal service endpoints. A number of ports will be continguously allocated equal to the number of users with enabled intake services."; }; users = mkOption { @@ -41,11 +47,18 @@ in { # Define the intake package and a python environment to run it from intake = flake.packages.${pkgs.stdenv.hostPlatform.system}.default; pythonEnv = pkgs.python38.withPackages (pypkgs: [ intake ]); + + # Assign each user an internal port for their personal intake instance + enabledUsers = filterAttrs (userName: userCfg: userCfg.enable) intakeCfg.users; + enabledUserNames = mapAttrsToList (userName: userCfg: userName) enabledUsers; + userPortList = imap1 (i: userName: { ${userName} = i + intakeCfg.internalPortStart; }) enabledUserNames; + userPort = foldl (acc: val: acc // val) {} userPortList; in { + # Define a user service for each configured user systemd.services = let runScript = userName: pkgs.writeShellScript "intake-run.sh" '' - ${pythonEnv}/bin/intake run -d /home/${userName}/.local/share/intake + ${pythonEnv}/bin/intake run -d /home/${userName}/.local/share/intake --port ${toString userPort.${userName}} ''; # systemd service definition for a single user, given `services.intake.users.userName` = `userCfg` userServiceConfig = userName: userCfg: { @@ -63,5 +76,22 @@ in { }; }; in mkMerge (mapAttrsToList userServiceConfig intakeCfg.users); + + # Define an nginx reverse proxy to request auth + services.nginx = mkIf (enabledUsers != {}) { + enable = true; + virtualHosts."intake" = mkIf (enabledUsers != {}) { + listen = [ intakeCfg.listen ]; + locations."/" = { + proxyPass = "http://127.0.0.1:$target_port"; + basicAuth = { alpha = "alpha"; beta = "beta"; }; + }; + extraConfig = foldl (acc: val: acc + val) "" (mapAttrsToList (userName: port: '' + if ($remote_user = "${userName}") { + set $target_port ${toString port}; + } + '') userPort); + }; + }; }; } diff --git a/tests/demo.nix b/tests/demo.nix index 7413082..61e5c0b 100644 --- a/tests/demo.nix +++ b/tests/demo.nix @@ -11,41 +11,7 @@ flake: { pkgs, ... }: services.intake.users.alpha.enable = true; - services.nginx.enable = true; - services.nginx.virtualHosts = { - alpha-fsid = { - listen = [ { addr = "localhost"; port = 8030; } ]; - locations."/".tryFiles = "/dev/null @dummy"; - locations."@dummy" = { - proxyPass = "http://127.0.0.1:5000"; - }; - }; - beta-fsid = { - listen = [ { addr = "localhost"; port = 8031; } ]; - locations."/".tryFiles = "/dev/null @dummy"; - locations."@dummy" = { - return = "200 'youve reached beta'"; - extraConfig = '' - add_header Content-Type text/plain always; - ''; - }; - }; - redirector = { - listen = [ { addr = "localhost"; port = 8032; } ]; - locations."/" = { - proxyPass = "http://127.0.0.1:$target_port"; - basicAuth = { alpha = "alpha"; beta = "beta"; }; - }; - extraConfig = '' - if ($remote_user ~ "alpha|^$") { - set $target_port 8030; - } - if ($remote_user = "beta") { - set $target_port 8031; - } - ''; - }; - }; + services.intake.users.beta.enable = true; users.users.alpha = { isNormalUser = true;