diff --git a/nixos/modules/services/web-servers/stargazer.nix b/nixos/modules/services/web-servers/stargazer.nix index da39c8172c8b..b8374313723d 100644 --- a/nixos/modules/services/web-servers/stargazer.nix +++ b/nixos/modules/services/web-servers/stargazer.nix @@ -83,6 +83,21 @@ in ''; }; + allowCgiUser = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + When enabled, the stargazer process will be given `CAP_SETGID` + and `CAP_SETUID` so that it can run cgi processes as a different + user. This is required if the `cgi-user` option is used for a route. + Note that these capabilities could allow privilege escalation so be + careful. For that reason, this is disabled by default. + + You will need to create the user mentioned `cgi-user` if it does not + already exist. + ''; + }; + store = lib.mkOption { type = lib.types.path; default = /var/lib/gemini/certs; @@ -206,6 +221,10 @@ in # User and group User = cfg.user; Group = cfg.group; + AmbientCapabilities = lib.mkIf cfg.allowCgiUser [ + "CAP_SETGID" + "CAP_SETUID" + ]; }; }; diff --git a/nixos/tests/web-servers/stargazer.nix b/nixos/tests/web-servers/stargazer.nix index 52bc93af1719..70a9fee456f1 100644 --- a/nixos/tests/web-servers/stargazer.nix +++ b/nixos/tests/web-servers/stargazer.nix @@ -117,16 +117,43 @@ in }; }; }; + cgiTestServer = { ... }: { + users.users.cgi = { + isSystemUser = true; + group = "cgi"; + }; + users.groups.cgi = { }; + services.stargazer = { + enable = true; + connectionLogging = false; + requestTimeout = 1; + allowCgiUser = true; + routes = [ + { + route = "localhost:/cgi-bin"; + root = "${test_env}/test_data"; + cgi = true; + cgi-timeout = 5; + cgi-user = "cgi"; + } + ]; + }; + }; }; testScript = { nodes, ... }: '' geminiserver.wait_for_unit("scgi_server") geminiserver.wait_for_open_port(1099) geminiserver.wait_for_unit("stargazer") - geminiserver.wait_for_open_port(1965) + geminiserver.wait_for_unit("stargazer") + cgiTestServer.wait_for_open_port(1965) + cgiTestServer.wait_for_open_port(1965) with subtest("stargazer test suite"): response = geminiserver.succeed("sh -c 'cd ${test_env}; ${test_script}/bin/test'") print(response) + with subtest("stargazer cgi-user test"): + response = cgiTestServer.succeed("sh -c 'cd ${test_env}; ${test_script}/bin/test --checks CGIVars'") + print(response) ''; }