Description
systemd can confine each service with options in its unit or in a drop-in
(systemctl edit <unit>): a dedicated or dynamic user (User=, DynamicUser=), a read-only
view of the system (ProtectSystem=strict, ProtectHome=, ReadWritePaths=), a private /tmp
and device set (PrivateTmp=, PrivateDevices=), no privilege gain
(NoNewPrivileges=, CapabilityBoundingSet=), and kernel and system call filters
(ProtectKernelTunables=, RestrictAddressFamilies=, SystemCallFilter=...).
systemd-analyze security scores each service from 0 (confined) to 10 (unconfined) and labels
it OK, MEDIUM, EXPOSED or UNSAFE.
The check lists the services that systemd-analyze security labels UNSAFE with their score;
it always passes, so the control ends as review. A person decides which network-facing
services to confine first. Many Debian services already ship hardened units (for example
systemd-resolved, chrony); OpenSSH stays largely unconfined by design, since it must start
login sessions.
Rationale
Most daemons only need a few directories, capabilities and system calls. Confining them limits what an attacker gains by exploiting one: no access to other services' data, no kernel tuning, no new privileges. This is the compartmentalization ANSSI asks for each service.
Impact
Options that are too strict make a service fail at start-up or at run time (cannot write its files, cannot open a socket). Each change must be tested on the service and kept in a drop-in so package upgrades do not overwrite it.
Audit
- Run
systemd-analyze securityand note the services ratedUNSAFEorEXPOSED. - For each service that listens on the network or parses untrusted data, check that a drop-in
under
/etc/systemd/system/<unit>.d/sets the sandboxing options it supports, and thatsystemd-analyze security <unit>shows an improved score.
Automated: every check must pass. Scanners report each check by its id.
exposure
Lists the services rated UNSAFE by systemd-analyze security, for review.
script: |
command -v systemd-analyze >/dev/null 2>&1 || { echo "systemd-analyze not found"; exit 3; }
o=$(systemd-analyze security --no-pager 2>/dev/null) || { echo "systemd-analyze security failed"; exit 3; }
total=$(printf '%s\n' "$o" | awk 'NR > 1' | grep -c .)
unsafe=$(printf '%s\n' "$o" | awk 'NR > 1 && $3 == "UNSAFE" { printf "%s=%s ", $1, $2 }')
n=$(printf '%s' "$unsafe" | wc -w)
echo "$n of $total services UNSAFE: $unsafe"
Remediation
For each service to confine, run systemctl edit <unit> and add the options it tolerates, for
example:
[Service]
ProtectSystem=strict
ReadWritePaths=/var/lib/<service>
ProtectHome=yes
PrivateTmp=yes
PrivateDevices=yes
NoNewPrivileges=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
Restart the service, check that it works and its logs (journalctl -u <unit>), then compare
systemd-analyze security <unit>.
Rollback
Run systemctl revert <unit> to remove the drop-ins, then restart the service.
References
- systemd.exec(5), Debian manual pages Debian, vendor-doc, accessed 2026-10-18
- systemd-analyze(1), Debian manual pages Debian, vendor-doc, accessed 2026-10-18
- Debian Wiki - ServiceSandboxing Debian, vendor-doc, accessed 2026-10-18
- ANSSI-BP-028 v2.0 - Recommandations de configuration d'un système GNU/Linux (R64, R65, R66) ANSSI, guide, accessed 2026-10-18
Mappings
| Framework | ID | Relation | Note |
|---|---|---|---|
| ANSSI-BP-028 - Recommandations de configuration d'un système GNU/Linux2.0 | R64 | partial | Covers service privileges through systemd users and capabilities. |
| ANSSI-BP-028 - Recommandations de configuration d'un système GNU/Linux2.0 | R65 | partial | Covers compartmentalization with systemd namespaces; containers and VMs are out of scope. |
| ANSSI-BP-028 - Recommandations de configuration d'un système GNU/Linux2.0 | R66 | partial | Covers system call and kernel access filters set by systemd. |
| NIST SP 800-53 Rev. 55.1.1 | SC-39 | related | |
| NIST SP 800-53 Rev. 55.1.1 | AC-6 | related |
How this control relates to the other framework's: equivalent, stricter, looser, partial or related.
Threats mitigated
People and lifecycle
| Authors |
|
| Verified | 2026-10-18 by Sn0wAlice on 12, Proxmox VM, Debian 12 genericcloud image, kernel 6.1.0-54-cloud-amd64. Check lists the UNSAFE services from systemd-analyze security and ends as review, on fresh and loaded systems. |
| Verified | 2026-10-18 by Sn0wAlice on 13, Proxmox VM, Debian 13 genericcloud image, kernel 6.12.113+deb13-cloud-amd64. Check lists the UNSAFE services from systemd-analyze security and ends as review, on fresh and loaded systems. |
| Introduced in | v0.1.0 |
| Created, updated | 2026-10-18, 2026-10-18 |
| Translations | fr |