Give a Service Only the File Access It Needs¶
A temperature logger needs to read its settings and write readings. It does not need to rewrite its settings or share temporary files with every other program. Raspberry Pi service isolation lets you test those requirements separately.
Outcome: observe a readable but non-writable settings file, a writable results directory and a private /tmp view. Complete the first restriction lab. You need Python 3, a working systemd user manager, XDG_RUNTIME_DIR and permitted unprivileged user/mount namespaces. Run the lab on the Pi as your ordinary user, without sudo.
Plan the file access before choosing settings¶
For this disposable logger, predict these results:
| Operation | Ordinary shell | Restricted service |
|---|---|---|
| Read the sample settings | Allowed | Allowed |
| Append to the sample settings | Allowed | Denied |
| Create a sample result | Allowed | Allowed |
Read the shell's temporary marker at its /tmp path |
Allowed | Not visible at that path |
ReadOnlyPaths changes write access in the service's filesystem view. PrivateTmp gives it separate temporary directories. Neither makes readable settings confidential. See the authoritative filesystem restriction reference for prerequisites and limitations.
Check the environment¶
These checks are read-only:
Stop if the user bus is unavailable or the runtime directory is unset. Some Ubuntu configurations restrict unprivileged user namespaces through security policy; another device may reject this lab even if the Pi example works. Do not disable AppArmor or change kernel policy to make it pass. A namespace/startup error is an unsupported or failed exercise, not evidence that file writes were blocked.
Run the disposable filesystem lab¶
Copy the whole block. It uses a new directory inside your user runtime directory, not your home or system configuration. The second temporary file is only a marker, not a real secret. Paths are passed as program arguments rather than inserted into Python source.
Expect settings read allowed, settings append blocked, result creation allowed, separate temporary contents, and the final PASS. All must occur with a zero exit status. The shell checks that no extra settings line appeared, then successfully appends its own line: this is not a host-wide chmod.
The exclusive open("x") on the marker is deliberate. If the service still sees the shell's existing file, creation fails instead of silently overwriting it. The same pathname can name different files in different mount namespaces.
Understand what this does not isolate¶
The lab protects only the selected settings path from writes in the service view; it does not make the rest of the filesystem read-only. The results directory remains writable because it is outside that path, not because ReadWritePaths grants new Unix permissions. The filesystem permissions lesson still applies.
Private temporary paths do not hide the rest of your home, revoke inherited file descriptors, or create a VM. A different program running directly as your user retains your user's access. This is a cooperative demonstration of specific restrictions, not a safe environment for running hostile code.
For a real logger, decide its dedicated account, required device access and data ownership as well. Settings such as ProtectSystem, ProtectHome and StateDirectory can help build a broader policy, but do not paste them into working services without checking their dependencies and testing recovery. Never mount private keys or a container-management socket merely to make a program start. The systemd service guide covers persistent service setup separately.
Failures and cleanup¶
226/NAMESPACE, permission errors during setup, or a missing user bus mean stop and inspect the exact error. The @mount syscall filter also requires kernel/systemd support. Do not remove restrictions just to obtain a green result.
The command creates no persistent unit. On success it removes its samples; on failure set -e stops before the final PASS, and the printed practice directory/host marker may remain. Inspect those exact paths, remove only the three known sample files when present, then remove their empty directories. Do not use recursive deletion of /tmp or your runtime directory. The service's private temporary files are cleaned up after the service stops; the host marker is a separate file.
Checkpoint: why is a readable settings file still unsuitable for a secret the service must not learn? Why can your shell write the file after the service was denied?
Next: limit a service's resource use. Return to Service Isolation.
The complete lab was checked on the Pi listed in verification scope. It does not test every filesystem path or resistance to namespace escapes.