DEV Community

OnaEiuspkz
OnaEiuspkz

Posted on

RestrictFileSystems controls filesystem types, not application paths

RestrictFileSystems controls filesystem types, not application paths

RestrictFileSystems= is easy to misread. It does not decide which directories a service can open. It decides which filesystem types the service can use when it attempts to open a file. That distinction matters when a hardening review checks the setting name and misses the paths that still remain available.

The policy model

The directive takes a space-separated list of filesystem names. By default, the list is an allowlist. A unit with RestrictFileSystems=ext4 tmpfs can open files on those filesystem types and is denied access to other filesystem types. Prefixing the list with ~ changes it to a denylist.

systemd also provides predefined sets such as @basic-api, @auxiliary-api, @network, @temporary, and @known. The sets reduce typing, but they do not tell an operator whether the application's data directory is on the named filesystem. The deployment still needs a mount inventory.

The rules are useful when a service should never touch network filesystems, FUSE mounts, or less common kernel filesystems. They are less useful when the service stores data on one of several local filesystem types that vary between hosts. An allowlist copied from a developer laptop can break a production host that uses XFS instead of ext4.

The enforcement dependency

On Linux, systemd implements this control through BPF and the cgroup v2 hierarchy. A host without the required kernel and LSM support cannot apply the policy as written. systemd reports a dedicated exit code when BPF setup fails, but an operator may only notice a failed service after deployment.

Check the runtime before using the setting as a compliance control:

systemd --version
mount | grep cgroup2
cat /sys/kernel/security/lsm
systemd-analyze security example.service
Enter fullscreen mode Exit fullscreen mode

The exact kernel configuration varies by distribution. The useful result is not a copied string from the systemd manual. It is evidence that the target host enforces the policy and that the service can reach its data after enforcement begins.

Filesystem type is only one axis

If a service runs on the same ext4 filesystem as application data, secrets, logs, and unrelated tenant files, allowing ext4 grants access to all of them, subject to normal ownership and permission checks. RestrictFileSystems= narrows kernel interfaces. It does not create a tenant boundary inside one filesystem.

Use it with path controls:

[Service]
RestrictFileSystems=ext4 tmpfs
ReadOnlyPaths=/
ReadWritePaths=/var/lib/example
ProtectSystem=strict
CapabilityBoundingSet=
SystemCallFilter=~@mount @swap
Enter fullscreen mode Exit fullscreen mode

The example assumes the service needs ext4 and tmpfs and nothing else. A service that reads configuration from a network share, stores backups on a mounted volume, or uses an overlay filesystem needs a different list. Do not broaden the allowlist until you know which mount supplies each required path.

Test the excluded case

Verification should cover both the allowed and denied paths. Start the service, write to its approved data directory, and read its configuration. Then use a disposable test unit to attempt a file operation on a filesystem that the policy excludes. Do not run the test against production data.

Record the effective property and the test result:

systemctl show example.service -p RestrictFileSystems -p ExecMainStatus
systemd-run --wait --pipe --property=RestrictFileSystems=ext4 -- /bin/sh -c 'test -r /proc/version'
Enter fullscreen mode Exit fullscreen mode

The transient-unit result depends on the host's actual mount layout. A zero exit code does not prove that every production path is reachable. A failure may come from a path permission rather than the filesystem policy. Inspect the error, the unit status, and the kernel logs together.

Keep the control specific

The best use of RestrictFileSystems= is a narrow statement about the service's storage model: this daemon reads its binaries and data only from these filesystem types. That statement should be written down and retested when the storage platform changes.

The dangerous pattern is an allowlist broad enough to make the service start on every host. It may include many filesystem types and provide little reduction. The useful control is the smallest set that survives a production-like test, paired with path restrictions and a capability set that cannot repair the namespace.

References

Top comments (0)