feat(#702): drop hive-c0re from root to hive-core user (privsep phase 2)
This commit is contained in:
parent
5e0da97ee5
commit
0bec3af933
2 changed files with 128 additions and 261 deletions
|
|
@ -315,6 +315,17 @@ in
|
|||
managerToplevel
|
||||
];
|
||||
|
||||
# Unprivileged coordinator user. hive-c0re runs as this user
|
||||
# (privsep phase 2); privileged operations are delegated to
|
||||
# hive-priv which runs as root, socket-activated at
|
||||
# /run/hive/priv.sock.
|
||||
users.users.hive-core = {
|
||||
isSystemUser = true;
|
||||
group = "hive-core";
|
||||
description = "hive-c0re coordinator daemon user";
|
||||
};
|
||||
users.groups.hive-core = { };
|
||||
|
||||
# Open the per-agent web-port range when the gateway is *off* —
|
||||
# otherwise the gateway nginx is the sole external entry point.
|
||||
# See `docs/gateway.md::Firewall posture (host-level)`.
|
||||
|
|
@ -412,12 +423,22 @@ in
|
|||
};
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/hive-c0re --socket /run/hyperhive/host.sock serve --hyperhive-flake ${cfg.hyperhiveFlake} --nixpkgs-flake ${cfg.nixpkgsFlake} --nixpkgs-unstable-flake ${cfg.nixpkgsUnstableFlake} --dashboard-port ${toString cfg.dashboardPort} --operator-pronouns ${lib.escapeShellArg cfg.operatorPronouns} --context-window-tokens ${lib.escapeShellArg (builtins.toJSON cfg.contextWindowTokens)}";
|
||||
# One-time migration: chown existing state tree to the service
|
||||
# user after upgrading from a root-run install. The `+` prefix
|
||||
# runs this step as root even though User = hive-core. systemd's
|
||||
# StateDirectory chowns the top-level dir at every start, but
|
||||
# pre-existing files inside may still be root-owned.
|
||||
ExecStartPre = "+${pkgs.coreutils}/bin/sh -c 'chown -R hive-core:hive-core /var/lib/hyperhive || true'";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 2;
|
||||
User = "hive-core";
|
||||
Group = "hive-core";
|
||||
SupplementaryGroups = [ "systemd-journal" ];
|
||||
RuntimeDirectory = "hyperhive";
|
||||
RuntimeDirectoryMode = "0750";
|
||||
RuntimeDirectoryPreserve = "yes";
|
||||
StateDirectory = "hyperhive";
|
||||
StateDirectoryMode = "0750";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -451,18 +472,18 @@ in
|
|||
# privileged operations on behalf of hive-c0re. Systemd creates and
|
||||
# holds `/run/hive/priv.sock` before the first connection arrives.
|
||||
#
|
||||
# Mode 0660 root:root is correct for phase 1 (hive-c0re still runs as
|
||||
# root and is the only caller). Phase 2 (privsep: hive-c0re drops to a
|
||||
# non-root user) will add `SocketGroup = hive-core` so the unprivileged
|
||||
# hive-c0re process can still connect.
|
||||
# Mode 0660 hive-core:hive-core: only the hive-c0re service user can
|
||||
# connect. hive-priv (server) runs as root and validates every request
|
||||
# against a strict allowlist before executing any privileged op.
|
||||
systemd.sockets.hive-priv = {
|
||||
description = "hive-priv privileged helper socket";
|
||||
wantedBy = [ "sockets.target" ];
|
||||
socketConfig = {
|
||||
ListenStream = "/run/hive/priv.sock";
|
||||
SocketMode = "0660";
|
||||
# Create /run/hive/ if absent; 0755 so future unprivileged callers
|
||||
# can traverse into it to reach the socket.
|
||||
SocketGroup = "hive-core";
|
||||
# Create /run/hive/ if absent; 0755 so the hive-core user can
|
||||
# traverse into it to reach the socket.
|
||||
DirectoryMode = "0755";
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue