mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-11 14:00:29 +00:00
4686efd8c8
The unified agent's Linux installer only offered the root profile, and the docs called non-root unsupported. That default is the most-cited reason security-conscious evaluators reject Pulse without trying it. install.sh gains --least-privilege: the service runs as a dedicated nologin pulse-agent system user with every existing hardening directive, no LXC-attach ambient capabilities, docker-group membership for socket reads, and refusal (not silent root fallback) on appliance platforms, non-systemd init systems, and --enable-commands. Optional --grant-smart and --grant-pct restore the only two collectors that need elevation through visudo-validated exact-command sudoers rules and root-owned wrappers the agent reaches via new 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. --update preserves the profile and its grants by reading the installed unit. The agent now authors a privilege block in its report (effective root, service user, active helpers), carried through models into the fleet doctor as a descriptive field: Agent Doctor shows the profile and its helpers instead of presenting intentionally absent collectors as a fault, and a least-privilege agent can never be marked unhealthy on that evidence alone.
28 lines
1014 B
Go
28 lines
1014 B
Go
package hostagent
|
|
|
|
import (
|
|
"os"
|
|
"os/user"
|
|
"strings"
|
|
|
|
agentshost "github.com/rcourtman/pulse-go-rewrite/pkg/agents/host"
|
|
)
|
|
|
|
// collectPrivilegeStatus reports the privilege the agent actually runs with.
|
|
// The values are facts about this process, not configuration: effective uid,
|
|
// the service account name, and whether the scoped privilege-helper overrides
|
|
// a least-privilege install configures are in effect. On Windows Geteuid is
|
|
// always -1, so RunningAsRoot stays false and ServiceUser carries the account
|
|
// name; the server renders the profile descriptively rather than judging it.
|
|
func collectPrivilegeStatus() *agentshost.PrivilegeStatus {
|
|
status := &agentshost.PrivilegeStatus{
|
|
RunningAsRoot: os.Geteuid() == 0,
|
|
SmartctlHelper: strings.TrimSpace(os.Getenv("PULSE_SMARTCTL_PATH")) != "",
|
|
PctHelper: strings.TrimSpace(os.Getenv("PULSE_PCT_PATH")) != "",
|
|
}
|
|
if current, err := user.Current(); err == nil {
|
|
status.ServiceUser = strings.TrimSpace(current.Username)
|
|
}
|
|
return status
|
|
}
|