Hardening Immutable Linux: sysext, confext, and the Persistence Surface in 2026
Immutable base images are no longer a Flatcar-and-Bottlerocket curiosity. By early 2026, mainline distributions ship /usr as a read-only verity-protected tree on a meaningful share of new fleet builds, and operators compose runtime functionality through systemd sysext and confext images mounted at boot or on demand. The architecture is genuinely better for integrity — but it has shifted the persistence surface in ways most detection content has not caught up with. If your IR runbook still assumes /etc/cron.d and /usr/local/bin are the interesting places to look, you are auditing a machine that no longer exists.
This is a defender-oriented walkthrough of how the sysext/confext composition actually works on a current systemd (v256+), where the persistence opportunities sit, what telemetry is realistic to collect, and how to map the resulting controls.
How sysext and confext actually compose the running system
sysext images are squashfs, erofs, or raw .raw files that systemd-sysext merges into /usr and /opt via an overlayfs at activation time. confext is the same mechanism, restricted to /etc. Both are managed by systemd-sysext.service and systemd-confext.service, which scan a fixed search path: /var/lib/extensions, /run/extensions, /etc/extensions, plus the per-image /usr/lib/extensions for vendor-shipped extensions and (since v255) /var/lib/extensions.d for confext.
Each image carries an extension-release.NAME file that must match the host’s os-release ID and version constraints, otherwise activation is refused. On a dm-verity-protected host the base /usr is immutable, but the overlay is not — once systemd-sysext merge runs, the union mount makes the extension’s contents indistinguishable from base contents to anything walking the filesystem. ldconfig, systemctl daemon-reload, and the dynamic linker all happily pick up binaries and unit files delivered through the overlay.
That is the point of the feature. It is also the problem.
The persistence surface
Four properties make this surface attractive to an attacker who has already achieved privileged code execution:
- Atomic activation, no package manager footprint. A dropped
.rawplus asystemctl restart systemd-sysextproduces new binaries in/usr/binwithout touchingrpm -Va,dpkg --verify, or any package database. File integrity tools that hash/usragainst a known manifest will see the merged view and report no drift if the extension shadows nothing. - Survives reboot, survives
soft-reboot. Extensions in/var/lib/extensionspersist; those in/run/extensionssurvivesystemd-soft-rebootbecause the/runtmpfs is preserved across the userspace re-exec. Soft-reboot is increasingly used to apply updates without kernel reset, and an extension placed there outlives the very operation operators expect to clear runtime state. - Confext bypasses many
/etcwatches. Most EDR products that monitor/etcwatch the underlying directory, not the overlay. A confext that delivers/etc/pam.d/sshdor/etc/sudoers.d/zz-vendorlands in the merged view consumed by PAM and sudo, but inotify on the lower directory sees nothing. - The extension search path is itself writable.
/var/lib/extensionsis, by default, a normal directory on the writable partition. Anyone with root (or a misconfigured container with--privilegedand host bind mounts) can stage an image there.
A related variant uses portable services (portablectl attach), which is the same image format with a different activation path. Treat it as the same surface.
What to detect
The useful telemetry is narrow and high-signal. Aim for these:
- Filesystem events on the extension search paths. Auditd rules on
/var/lib/extensions,/etc/extensions,/run/extensions,/var/lib/extensions.d, and/var/lib/portables. Watchcreate,rename, andsetxattr. Any write to these paths outside of your image-deployment service account is an incident. - Unit-state changes for the merge services. Journal events from
systemd-sysext.serviceandsystemd-confext.service— specificallyMerged extensions ...lines — should correlate 1:1 with a controlled deployment. Ship the journal, parse those lines, alert on unmatched merges. - Mount table deltas. New overlay mounts on
/usror/etcoutside of boot./proc/self/mountinfosnapshotted on a schedule, diffed centrally, is sufficient and cheap. extension-releaseprovenance. For each active extension, record theID,VERSION_ID,SYSEXT_SCOPE, and the image’s verity root hash if present. Extensions without a verity root hash on a verity-protected host are a finding, not a warning.- Soft-reboot accounting.
systemd-soft-reboot.serviceinvocations should be reconciled against change tickets. An unscheduled soft-reboot is interesting on its own merits.
Do not rely on package-manager verification, generic /usr hashing, or AIDE configurations written before overlayfs-on-/usr became normal. They will not see what you need them to see.
Hardening posture
The tractable mitigations, in order of impact:
- Require signed, verity-protected extensions. Set
systemd.extension-images.require-signature=yes(or the equivalent in your image-builder) and configure/etc/verity.dwith the keys your build pipeline owns. Refuse to merge anything without a matching root hash. - Move the search path to read-only storage. Bind-mount
/var/lib/extensionsfrom a dm-verity volume managed by your update agent. The mutable copy lives only on the build/deploy host, never on production. - Disable confext where it is not used.
systemctl mask systemd-confext.serviceon hosts whose/etcis fully managed by configuration management. Confext exists for a reason, but most fleets do not need it on every node. - Constrain who can call the merge.
systemd-sysextrequires root, but root in a container with the host’s/var/lib/extensionsbind-mounted is enough. Audit container manifests for that mount and forCAP_SYS_ADMINplus host PID/mount namespaces. - Forbid
portablectl attachin production. It is a useful developer tool and a poor production primitive on a hardened host.
Control mapping
| Concern | 800-53 controls |
|---|---|
| Authorized extension provenance and signing | CM-5, CM-7, SI-7, SR-4, SR-11 |
| Inventory of active extensions and verity hashes | CM-8, CM-2 |
| Detection of unauthorized merges | AU-2, AU-6, AU-12, SI-4 |
| Boundary on who/what can stage images | AC-3, AC-6, CM-5(1) |
| Soft-reboot and runtime-state accountability | CM-3, CM-6, AU-12 |
| Acquisition and build-pipeline integrity | SA-10, SA-11, SR-3 |
SI-7 (software, firmware, and information integrity) is the one most assessors will reach for first. Push back on a control narrative that stops at “dm-verity protects /usr” — verity covers the lower layer, not the union. The integrity story has to include the extension lifecycle or it is incomplete.
Bottom line
Immutable Linux is a real improvement and the sysext/confext model is the right shape for fleet management. It is also a persistence surface that current detection content largely ignores. Treat the extension search path as a privileged code-loading interface, sign and verity-protect the images, and ship the merge events to your SIEM. If you cannot answer “which extensions are merged on this host right now, who signed them, and when did that change” from your telemetry, the host is not as immutable as the architecture diagram says it is.