diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 1a8bd9cccb18..3ee242ab2226 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -681,6 +681,7 @@ ./services/security/hologram-server.nix ./services/security/hologram-agent.nix ./services/security/munge.nix + ./services/security/nginx-sso.nix ./services/security/oauth2_proxy.nix ./services/security/oauth2_proxy_nginx.nix ./services/security/physlock.nix diff --git a/nixos/modules/services/security/nginx-sso.nix b/nixos/modules/services/security/nginx-sso.nix new file mode 100644 index 000000000000..d792f90abe64 --- /dev/null +++ b/nixos/modules/services/security/nginx-sso.nix @@ -0,0 +1,58 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.nginx.sso; + pkg = getBin pkgs.nginx-sso; + configYml = pkgs.writeText "nginx-sso.yml" (builtins.toJSON cfg.configuration); +in { + options.services.nginx.sso = { + enable = mkEnableOption "nginx-sso service"; + + configuration = mkOption { + type = types.attrsOf types.unspecified; + default = {}; + example = literalExample '' + { + listen = { addr = "127.0.0.1"; port = 8080; }; + + providers.token.tokens = { + myuser = "MyToken"; + }; + + acl = { + rule_sets = [ + { + rules = [ { field = "x-application"; equals = "MyApp"; } ]; + allow = [ "myuser" ]; + } + ]; + }; + } + ''; + description = '' + nginx-sso configuration + (documentation) + as a Nix attribute set. + ''; + }; + }; + + config = mkIf cfg.enable { + systemd.services.nginx-sso = { + description = "Nginx SSO Backend"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = '' + ${pkg}/bin/nginx-sso \ + --config ${configYml} \ + --frontend-dir ${pkg}/share/frontend + ''; + Restart = "always"; + DynamicUser = true; + }; + }; + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 88edef8e7520..a1cdcf839889 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -153,6 +153,7 @@ in nfs4 = handleTest ./nfs.nix { version = 4; }; nghttpx = handleTest ./nghttpx.nix {}; nginx = handleTest ./nginx.nix {}; + nginx-sso = handleTest ./nginx-sso.nix {}; nix-ssh-serve = handleTest ./nix-ssh-serve.nix {}; novacomd = handleTestOn ["x86_64-linux"] ./novacomd.nix {}; nsd = handleTest ./nsd.nix {}; diff --git a/nixos/tests/nginx-sso.nix b/nixos/tests/nginx-sso.nix new file mode 100644 index 000000000000..e19992cb6bf7 --- /dev/null +++ b/nixos/tests/nginx-sso.nix @@ -0,0 +1,44 @@ +import ./make-test.nix ({ pkgs, ... }: { + name = "nginx-sso"; + meta = { + maintainers = with pkgs.stdenv.lib.maintainers; [ delroth ]; + }; + + machine = { + services.nginx.sso = { + enable = true; + configuration = { + listen = { addr = "127.0.0.1"; port = 8080; }; + + providers.token.tokens = { + myuser = "MyToken"; + }; + + acl = { + rule_sets = [ + { + rules = [ { field = "x-application"; equals = "MyApp"; } ]; + allow = [ "myuser" ]; + } + ]; + }; + }; + }; + }; + + testScript = '' + startAll; + + $machine->waitForUnit("nginx-sso.service"); + $machine->waitForOpenPort(8080); + + # No valid user -> 401. + $machine->fail("curl -sSf http://localhost:8080/auth"); + + # Valid user but no matching ACL -> 403. + $machine->fail("curl -sSf -H 'Authorization: Token MyToken' http://localhost:8080/auth"); + + # Valid user and matching ACL -> 200. + $machine->succeed("curl -sSf -H 'Authorization: Token MyToken' -H 'X-Application: MyApp' http://localhost:8080/auth"); + ''; +}) diff --git a/pkgs/servers/nginx-sso/default.nix b/pkgs/servers/nginx-sso/default.nix new file mode 100644 index 000000000000..a25eff5b05c9 --- /dev/null +++ b/pkgs/servers/nginx-sso/default.nix @@ -0,0 +1,29 @@ +{ buildGoPackage, fetchFromGitHub, stdenv }: + +buildGoPackage rec { + name = "nginx-sso-${version}"; + version = "0.15.1"; + rev = "v${version}"; + + goPackagePath = "github.com/Luzifer/nginx-sso"; + + src = fetchFromGitHub { + inherit rev; + owner = "Luzifer"; + repo = "nginx-sso"; + sha256 = "0mm6yhm22wf32yl9wvl8fy9m5jjd491khyy4cl73fn381h3n5qi2"; + }; + + postInstall = '' + mkdir -p $bin/share + cp -R $src/frontend $bin/share + ''; + + meta = with stdenv.lib; { + description = "SSO authentication provider for the auth_request nginx module"; + homepage = https://github.com/Luzifer/nginx-sso; + license = licenses.asl20; + maintainers = with maintainers; [ delroth ]; + platforms = platforms.unix; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index ba59be8201fe..9621ca428aa6 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -13742,6 +13742,8 @@ in inherit (darwin.apple_sdk.frameworks) Security; }; + nginx-sso = callPackage ../servers/nginx-sso { }; + percona-server56 = callPackage ../servers/sql/percona/5.6.x.nix { }; percona-server = percona-server56;