mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 02:25:56 +00:00
Relax NoNewPrivileges only when a least-privilege sudo grant is active
Live proof on a real systemd host (Debian 12 container, full
install/report/update/uninstall cycle) caught what no unit test did:
NoNewPrivileges=true blocks sudo outright, so the --grant-smart and
--grant-pct helpers failed inside the service and SMART/pct silently
disappeared while the install reported success. A unit with an active
grant now sets NoNewPrivileges=false, keeping the rest of the hardening;
a grantless least-privilege install keeps NNP enabled. Docs and contracts
state the trade-off: each grant is a scoped, auditable widening.
Also proven in the same live cycle: the flag-conflict refusals, user and
sudoers provisioning, wrapper execution as the service user, the healthy
privilege report ({runningAsRoot:false, serviceUser:pulse-agent,
smartctlHelper:true}), --update preserving the profile without repeated
flags, and uninstall removing the sudoers file and helpers.
This commit is contained in:
@@ -146,7 +146,11 @@ dropping the LXC-attach ambient capability grant entirely.
|
||||
Two optional flags restore the collectors that genuinely need elevation, each
|
||||
through an exact-command sudoers grant validated with `visudo` and a
|
||||
root-owned wrapper the agent is pointed at via an absolute-path-only
|
||||
environment override:
|
||||
environment override. Because `NoNewPrivileges` blocks `sudo` entirely, a
|
||||
unit with an active grant sets `NoNewPrivileges=false` while keeping the
|
||||
remaining hardening; a grantless least-privilege install keeps
|
||||
`NoNewPrivileges=true`. Choose grants deliberately: each one is a scoped,
|
||||
auditable widening of the profile.
|
||||
|
||||
- `--grant-smart` allows exactly `smartctl`, restoring SMART disk health.
|
||||
- `--grant-pct` allows exactly `pct list` and `pct df`, restoring Proxmox LXC
|
||||
|
||||
@@ -6419,7 +6419,10 @@ installed unit rather than requiring the flags to be repeated. Optional
|
||||
need elevation through visudo-validated, exact-command sudoers rules and
|
||||
root-owned wrapper helpers the agent reaches only via the absolute-path-only
|
||||
`PULSE_SMARTCTL_PATH` / `PULSE_PCT_PATH` overrides; the pct grant covers
|
||||
`pct list` and `pct df` only and can never widen into `pct exec`. The agent
|
||||
`pct list` and `pct df` only and can never widen into `pct exec`. An active
|
||||
grant sets `NoNewPrivileges=false` because NNP blocks sudo outright (proven
|
||||
on a live systemd host); a grantless profile keeps `NoNewPrivileges=true`.
|
||||
The agent
|
||||
authors a `privilege` block in its report (`pkg/agents/host/report.go`
|
||||
`PrivilegeStatus`: effective root, service user, active helpers) so the
|
||||
server can present the profile descriptively. Uninstall removes the sudoers
|
||||
|
||||
@@ -3474,6 +3474,8 @@ exact-command sudoers rules with root-owned wrapper helpers wired through
|
||||
flag is refused (never silently downgraded to root) on appliance platforms
|
||||
and non-systemd init systems, is mutually exclusive with
|
||||
`--enable-commands`, and `--update` preserves an installed profile and its
|
||||
grants by reading the existing unit. Uninstall removes the sudoers file and
|
||||
helper directory. `scripts/installtests/install_sh_test.go`
|
||||
grants by reading the existing unit. A unit with an active grant sets
|
||||
`NoNewPrivileges=false` because NNP blocks sudo (proven on a live systemd
|
||||
host); a grantless profile keeps `NoNewPrivileges=true`. Uninstall removes
|
||||
the sudoers file and helper directory. `scripts/installtests/install_sh_test.go`
|
||||
(`TestInstallSHLeastPrivilegeProfile`) pins these invariants.
|
||||
|
||||
@@ -2287,6 +2287,8 @@ non-root with a nologin shell, keep every sudoers grant exact-command and
|
||||
visudo-validated with the pct grant excluding `pct exec`/`start`/`stop`/
|
||||
`enter`, refuse `--enable-commands` under the profile, refuse unsupported
|
||||
platforms instead of silently reverting to root, and drop the LXC-attach
|
||||
ambient capability grant. The agent-reported privilege profile is
|
||||
ambient capability grant. `NoNewPrivileges` stays enabled on a grantless
|
||||
profile and is relaxed only when a sudo grant is active, because NNP blocks
|
||||
sudo outright; that relaxation is part of the grant's declared cost. The agent-reported privilege profile is
|
||||
informational: the fleet doctor presents it descriptively and must not treat
|
||||
a non-root agent as unhealthy on that evidence alone.
|
||||
|
||||
@@ -1034,6 +1034,14 @@ render_systemd_agent_unit() {
|
||||
no_new_privileges="false"
|
||||
restrict_suidsgid="false"
|
||||
fi
|
||||
if [[ "$LEAST_PRIVILEGE" == "true" ]] && [[ "$GRANT_SMART" == "true" || "$GRANT_PCT" == "true" ]]; then
|
||||
# The scoped sudo helpers are the profile's only privilege path, and
|
||||
# NoNewPrivileges blocks sudo outright ("no new privileges flag is
|
||||
# set"). Proven on a live systemd host: with NNP on, every helper call
|
||||
# fails and SMART/pct silently disappear. A grant therefore relaxes
|
||||
# NNP; a grantless least-privilege install keeps it.
|
||||
no_new_privileges="false"
|
||||
fi
|
||||
if systemd_agent_may_attach_lxc; then
|
||||
# lxc-attach into an unprivileged guest writes /proc/<pid>/uid_map,
|
||||
# which needs CAP_SETUID in the parent user namespace. NoNewPrivileges
|
||||
|
||||
@@ -5564,6 +5564,9 @@ func TestInstallSHLeastPrivilegeProfile(t *testing.T) {
|
||||
`"network-online.target" "$SERVICE_USER" ""`,
|
||||
"# The least-privilege profile never attaches into guests",
|
||||
`rm -f "$PRIVILEGE_SUDOERS_FILE"`,
|
||||
// NoNewPrivileges blocks sudo, so an active grant must relax it or
|
||||
// the helpers silently fail inside the service (proven live).
|
||||
`if [[ "$LEAST_PRIVILEGE" == "true" ]] && [[ "$GRANT_SMART" == "true" || "$GRANT_PCT" == "true" ]]; then`,
|
||||
}
|
||||
for _, needle := range required {
|
||||
if !strings.Contains(script, needle) {
|
||||
|
||||
Reference in New Issue
Block a user