Watch
0
0
Fork
You've already forked hyperhive
0

hive-priv: create the nixos-containers directories at boot

This commit is contained in:
atlas 2026-11-13 07:37:18 +01:00 • committed by mara
commit bf77b72217
3 changed files with 42 additions and 5 deletions

View file

@ -163,7 +163,10 @@ above for how the hard-coded unit name scopes its access instead.
**Socket-activated** — systemd starts `hive-priv` on the first **Socket-activated** — systemd starts `hive-priv` on the first
incoming connection (`LISTEN_FDS=1`); it's not running between calls. incoming connection (`LISTEN_FDS=1`); it's not running between calls.
The `ProtectSystem=strict` + `ReadWritePaths` sandbox limits filesystem The `ProtectSystem=strict` + `ReadWritePaths` sandbox limits filesystem
writes to only the paths `hive-priv` legitimately needs. The unit also sets writes to only the paths `hive-priv` legitimately needs. A `ReadWritePaths`
entry that's missing fails the unit with `226/NAMESPACE`, so tmpfiles rules
create `/etc/nixos-containers`, `/var/lib/nixos-containers` and
`/run/hive-agent` on a hive that has no declared container yet. The unit also sets
`LockPersonality`, `RestrictRealtime`, `ProtectKernelLogs` and `LockPersonality`, `RestrictRealtime`, `ProtectKernelLogs` and
`ProtectKernelModules`: it changes no execution domain, schedules nothing in `ProtectKernelModules`: it changes no execution domain, schedules nothing in
real time, reads no kernel log, and loads no module. It sets none of real time, reads no kernel log, and loads no module. It sets none of

View file

@ -43,10 +43,17 @@ in
}; };
config = lib.mkIf config.services.hyperhive.deploy.hive-controller.enable { config = lib.mkIf config.services.hyperhive.deploy.hive-controller.enable {
# The parent of every agent socket dir. hive-priv is its only writer # Every directory hive-priv writes to that nothing else creates before it
# (`EnsureAgentSocketDir`), and its unit lists it in `ReadWritePaths`, # starts. Its unit lists them in `ReadWritePaths`, which fails the unit
# which fails the unit when the path is missing. # (226/NAMESPACE) when a path is missing:
systemd.tmpfiles.rules = [ "d /run/hive-agent 0755 root root - -" ]; # /run/hive-agent parent of every agent socket dir
# /etc/nixos-containers exists only once a container is declared
# /var/lib/nixos-containers same; 0700 is the mode nixos-container gives it
systemd.tmpfiles.rules = [
"d /run/hive-agent 0755 root root - -"
"d /etc/nixos-containers 0755 root root - -"
"d /var/lib/nixos-containers 0700 root root - -"
];
assertions = [ assertions = [
( (

View file

@ -2339,6 +2339,33 @@ let
&& (sc.ProtectKernelLogs or false) && (sc.ProtectKernelLogs or false)
&& (sc.ProtectKernelModules or false); && (sc.ProtectKernelModules or false);
} }
{
# A path in `ReadWritePaths` without a `-` prefix must exist or the unit
# fails with 226/NAMESPACE, and a hive with no declared container has no
# /etc/nixos-containers. Each required-to-exist path is created by a
# tmpfiles rule. Presence control: the other rule in the list is found by
# the same lookup; the toggled-off fixture has no hive-priv and no rule.
name = "hive-priv's ReadWritePaths directories are all created by tmpfiles rules";
ok =
let
rules = allLocal.systemd.tmpfiles.rules;
rw = allLocal.systemd.services.hive-priv.serviceConfig.ReadWritePaths;
created = [
"/run/hive-agent"
"/etc/nixos-containers"
"/var/lib/nixos-containers"
];
hasRule = p: lib.any (r: lib.hasPrefix "d ${p} " r) rules;
in
lib.all (p: lib.elem p rw && hasRule p) created
&& lib.elem "d /etc/nixos-containers 0755 root root - -" rules
&& lib.elem "d /var/lib/nixos-containers 0700 root root - -" rules
&& !(lib.any (p: lib.hasPrefix "-" p) rw)
&& hasRule "/var/lib/hyperhive/agents"
&& !(lib.any (
r: lib.hasPrefix "d /etc/nixos-containers " r
) centralToggleOff.systemd.tmpfiles.rules);
}
{ {
# Hyperhive's own declarative containers each run the root check from # Hyperhive's own declarative containers each run the root check from
# their own unit, warn-only. Every container in these fixtures is one of # their own unit, warn-only. Every container in these fixtures is one of