image: SELinux allow fleet-agent to read chrony tracking.log under enforcing
The tracking.log approach (4ca0b6d) works in permissive but is blocked under
enforcing: chrony's log is labeled chronyd_var_log_t, confined by the shipped
policy to chronyd_t despite the 0644 mode. Verified on comet-beacon-54 — a
non-root read succeeds permissive, but under enforcing even a STIG-confined
admin (staff_t) gets Permission denied (ls -Z on the file is itself blocked).
The agent runs unconfined_service_t (confirmed via ps -eZ) and is denied the
same way.
Ship a minimal read-only allow module (files/stig/fleet-agent-chronylog.te):
allow unconfined_service_t chronyd_var_log_t:file { open read getattr } + dir
search to reach it. No write, no other chrony access, and no domain transition
(the agent reads a file; it does not exec chronyc) — narrower than the
abandoned nnp-transition module. Built + semodule -i'd in 2c-STIG alongside the
existing chrony_dhcp_dispatcher / fapolicyd_tmpfs modules. docs/stig-deviations
#16. Needs a workstation image rebuild + reboot; same policy-store-rebuild
reproducibility re-check as #14/#15.
This commit is contained in:
@@ -248,6 +248,38 @@ surface rather than detecting abuse of it. Requires a write primitive to a root-
|
||||
path either way (already-privileged context), which is fapolicyd's defense-in-depth
|
||||
threat model — not an unprivileged bypass.
|
||||
|
||||
## 16. Local SELinux policy module `fleet_agent_chronylog` (added 2026-07-10)
|
||||
|
||||
Not a STIG-rule waiver — a **minimal local read-only `allow` module** so the
|
||||
`fleet-agent` telemetry client can read chrony's tracking log under enforcing
|
||||
SELinux. Source: `files/stig/fleet-agent-chronylog.te`; built + `semodule -i`'d in
|
||||
the 2c-STIG provisioner (after #15).
|
||||
|
||||
**The rules:** `allow unconfined_service_t chronyd_var_log_t:file { open read
|
||||
getattr };` (+ `dir { search getattr open }` to reach the file).
|
||||
|
||||
**Why:** `fleet-agent` reports clock health (source/stratum/offset) by reading
|
||||
`/var/log/chrony/tracking.log` — deliberately a FILE read rather than a query to
|
||||
chronyd's command interface, which the hardened agent can't use (owner-write-only
|
||||
unix socket; STIG's `cmdport 0` closes the UDP port). But chrony's log dir + files
|
||||
are labeled `chronyd_var_log_t`, which the shipped policy confines to `chronyd_t` +
|
||||
log-admin roles. So although the file is mode `0644`, under enforcing the agent
|
||||
(`unconfined_service_t`) is **denied** by type enforcement — DAC allows, TE does
|
||||
not. Verified 2026-07-10 on `comet-beacon-54`: with SELinux **permissive** a
|
||||
non-root read of `tracking.log` succeeds; flip to **enforcing** and even a
|
||||
STIG-confined admin (`staff_t`) gets `Permission denied` (`ls -Z` on the file is
|
||||
itself blocked) — the signature of a type-enforcement block, not a DAC one.
|
||||
|
||||
**Scope:** read-only (`open`/`read`/`getattr`) on one log type + dir search to
|
||||
reach it. No write, no other chrony access, and — unlike the earlier abandoned
|
||||
approach — **no domain transition** (the agent reads a file; it does not exec
|
||||
`chronyc`). This replaces the never-shipped `fleet_agent_chronyc` nnp-transition
|
||||
module (that whole command-socket path was dropped for reading the log instead).
|
||||
**BENCH-VERIFY:** (a) the manager's Monitor chrony row populates on an enforcing
|
||||
boot; (b) no other chrony-log AVC (extend here if one appears); (c)
|
||||
**reproducibility** — `semodule -i` rebuilds the policy store, re-check verity hash
|
||||
stability (same concern as #14/#15). Only shipped when `enable_stig=true`.
|
||||
|
||||
## Things that are NOT deviations (kept / enforced)
|
||||
|
||||
- **SELinux enforcing** (`selinux --enforcing`; labels preserved into the erofs).
|
||||
|
||||
Reference in New Issue
Block a user