Skip to content

Commit

Permalink
nixos/stargazer: module bug fix and hardening (#294795)
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperSandro2000 authored Sep 3, 2024
2 parents d85bcd1 + be1336d commit 3bd4ec6
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 1 deletion.
6 changes: 6 additions & 0 deletions nixos/doc/manual/release-notes/rl-2411.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,12 @@
for `stateVersion` ≥ 24.11. (It was previously using SQLite for structured
data and the filesystem for blobs).

- The `stargazer` service has been hardened to improve security, but these
changes make break certain setups, particularly around traditional CGI.

- The `stargazer.allowCgiUser` option has been added, enabling
Stargazer's `cgi-user` option to work, which was previously broken.

- The `shiori` service now requires an HTTP secret value `SHIORI_HTTP_SECRET_KEY` to be provided via environment variable. The nixos module therefore, now provides an environmentFile option:

```
Expand Down
57 changes: 57 additions & 0 deletions nixos/modules/services/web-servers/stargazer.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -206,6 +221,48 @@ in
# User and group
User = cfg.user;
Group = cfg.group;
AmbientCapabilities = lib.mkIf cfg.allowCgiUser [
"CAP_SETGID"
"CAP_SETUID"
];

# Hardening
UMask = "0077";
PrivateTmp = true;
ProtectHome = true;
ProtectSystem = "full";
ProtectClock = true;
ProtectHostname = true;
ProtectControlGroups = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
PrivateDevices = true;
NoNewPrivileges = true;
RestrictSUIDSGID = true;
PrivateMounts = true;
MemoryDenyWriteExecute = true;
LockPersonality = true;
RestrictRealtime = true;
RemoveIPC = true;
CapabilityBoundingSet = [
"~CAP_SYS_PTRACE"
"~CAP_SYS_ADMIN"
"~CAP_SETPCAP"
"~CAP_SYS_TIME"
"~CAP_SYS_PACCT"
"~CAP_SYS_TTY_CONFIG "
"~CAP_SYS_CHROOT"
"~CAP_SYS_BOOT"
"~CAP_NET_ADMIN"
] ++ lib.lists.optional (!cfg.allowCgiUser) [
"~CAP_SETGID"
"~CAP_SETUID"
];
SystemCallArchitectures = "native";
SystemCallFilter = [ "~@cpu-emulation @debug @keyring @mount @obsolete" ]
++ lib.lists.optional (!cfg.allowCgiUser) [ "@privileged @setuid" ];
};
};

Expand Down
27 changes: 26 additions & 1 deletion nixos/tests/web-servers/stargazer.nix
Original file line number Diff line number Diff line change
Expand Up @@ -117,16 +117,41 @@ 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)
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)
'';
}

0 comments on commit 3bd4ec6

Please sign in to comment.