hive-priv: lock personality, deny realtime, kernel logs and module loading
Adds LockPersonality, RestrictRealtime, ProtectKernelLogs and ProtectKernelModules to the hive-priv unit. Nothing in hive-priv's sources or its children uses personality(2), real-time scheduling, /dev/kmsg, /proc/kmsg or explicit module loading. A module-eval case pins the four directives on the rendered unit.
This commit is contained in:
parent
07456c27f3
commit
b8897e7c7a
3 changed files with 30 additions and 1 deletions
|
|
@ -322,7 +322,13 @@ 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.
|
writes to only the paths `hive-priv` legitimately needs. The unit also sets
|
||||||
|
`LockPersonality`, `RestrictRealtime`, `ProtectKernelLogs` and
|
||||||
|
`ProtectKernelModules`: it changes no execution domain, schedules nothing in
|
||||||
|
real time, reads no kernel log, and loads no module. It sets none of
|
||||||
|
`RestrictNamespaces` (`nsenter` into a container needs `setns`),
|
||||||
|
`RestrictAddressFamilies`, `PrivateDevices`, `CapabilityBoundingSet` or
|
||||||
|
`SystemCallFilter`; those need a watched deploy to judge.
|
||||||
|
|
||||||
### Privilege boundary summary
|
### Privilege boundary summary
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,15 @@ in
|
||||||
# meta/applied repos; libgit2 refuses them without safe.directory.
|
# meta/applied repos; libgit2 refuses them without safe.directory.
|
||||||
# See safeDirGitconfig above.
|
# See safeDirGitconfig above.
|
||||||
ExecStartPre = "+-${pkgs.coreutils}/bin/cp ${safeDirGitconfig} /var/lib/hive-priv/.gitconfig";
|
ExecStartPre = "+-${pkgs.coreutils}/bin/cp ${safeDirGitconfig} /var/lib/hive-priv/.gitconfig";
|
||||||
|
# Kernel surfaces neither hive-priv nor its children use: no
|
||||||
|
# personality(2), no real-time scheduling, no /dev/kmsg or
|
||||||
|
# /proc/kmsg, no explicit module loading (kernel-initiated autoload
|
||||||
|
# still works). Container start/stop run in `container@.service`,
|
||||||
|
# not under this unit.
|
||||||
|
LockPersonality = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1083,6 +1083,20 @@ let
|
||||||
{ unit, ... }: !(bare.systemd.services ? ${unit}) && !(bare.systemd.timers ? ${unit})
|
{ unit, ... }: !(bare.systemd.services ? ${unit}) && !(bare.systemd.timers ? ${unit})
|
||||||
) storeRefreshed;
|
) storeRefreshed;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
# `or false` so a dropped key fails this case by name instead of
|
||||||
|
# aborting eval. Only the rendered unit is pinned; eval cannot show
|
||||||
|
# that hive-priv still works under the directives.
|
||||||
|
name = "hive-priv locks personality and denies real-time scheduling, kernel logs and module loading";
|
||||||
|
ok =
|
||||||
|
let
|
||||||
|
sc = allLocal.systemd.services.hive-priv.serviceConfig;
|
||||||
|
in
|
||||||
|
(sc.LockPersonality or false)
|
||||||
|
&& (sc.RestrictRealtime or false)
|
||||||
|
&& (sc.ProtectKernelLogs or false)
|
||||||
|
&& (sc.ProtectKernelModules or false);
|
||||||
|
}
|
||||||
]
|
]
|
||||||
# Starting a unit that stays `active (exited)` is a no-op, so a timer aimed
|
# Starting a unit that stays `active (exited)` is a no-op, so a timer aimed
|
||||||
# at one fires and fetches nothing.
|
# at one fires and fetches nothing.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue