Description
When these directories are separate filesystems, they are mounted with the options listed in
{{ mount_options }} (format directory:option,option). By default:
| Directory | Options |
|---|---|
/home, /var, /opt, /srv | nodev,nosuid |
/var/tmp, /var/log, /var/log/audit, /boot | nodev,nosuid,noexec |
/usr | nodev |
The hardened profiles also require noexec on /home. Every other local filesystem backed by a
block device, except / and the snap images under /snap, must be mounted with nodev. A directory that is not a separate
filesystem is skipped; when there is none besides /, the control does not apply.
ANSSI also recommends noexec on /var. It is left out: dpkg runs package maintainer scripts
from /var/lib/dpkg/info/, so package installation and upgrades fail with it. Container engines
that store images under /var/lib need exec as well, and so does snapd (/var/lib/snapd).
Ubuntu 24.04 and 26.04 cloud images have a separate /boot partition mounted with defaults,
and every release mounts /boot/efi without nodev: the check fails on a fresh image until
the options are added in /etc/fstab.
Rationale
Only /dev needs device files, and only system directories need setuid programs or executables.
nodev stops a device node created on a data filesystem (or brought on removable media) from
giving raw access to disks or memory. nosuid stops setuid programs planted there from granting
privileges, and noexec stops tools dropped there from being run directly.
Impact
noexec on /home (hardened profiles) prevents users from running their own scripts and
programs directly, including tools installed under ~/.local/bin. noexec on /boot and
/var/log has no known effect on Ubuntu. Snaps run from their own read-only squashfs
mounts under /snap, which snapd mounts with nodev: the check skips them, and these options
do not affect them.
Setting
| Location | /etc/fstab |
| Default | Options chosen at installation (usually defaults) |
| Recommended | {{ mount_options }}; nodev on every other local filesystem except / |
Parameters
| Parameter | Core | Server | Server hardened | Desktop | Desktop hardened | Bounds |
|---|---|---|---|---|---|---|
mount_optionslist. Required options per mount point, as directory:option,option. | /home:nodev,nosuid, /var:nodev,nosuid, /var/tmp:nodev,nosuid,noexec, /var/log:nodev,nosuid,noexec, /var/log/audit:nodev,nosuid,noexec, /boot:nodev,nosuid,noexec, /opt:nodev,nosuid, /srv:nodev,nosuid, /usr:nodev | /home:nodev,nosuid, /var:nodev,nosuid, /var/tmp:nodev,nosuid,noexec, /var/log:nodev,nosuid,noexec, /var/log/audit:nodev,nosuid,noexec, /boot:nodev,nosuid,noexec, /opt:nodev,nosuid, /srv:nodev,nosuid, /usr:nodev | /home:nodev,nosuid,noexec, /var:nodev,nosuid, /var/tmp:nodev,nosuid,noexec, /var/log:nodev,nosuid,noexec, /var/log/audit:nodev,nosuid,noexec, /boot:nodev,nosuid,noexec, /opt:nodev,nosuid, /srv:nodev,nosuid, /usr:nodev | /home:nodev,nosuid, /var:nodev,nosuid, /var/tmp:nodev,nosuid,noexec, /var/log:nodev,nosuid,noexec, /var/log/audit:nodev,nosuid,noexec, /boot:nodev,nosuid,noexec, /opt:nodev,nosuid, /srv:nodev,nosuid, /usr:nodev | /home:nodev,nosuid,noexec, /var:nodev,nosuid, /var/tmp:nodev,nosuid,noexec, /var/log:nodev,nosuid,noexec, /var/log/audit:nodev,nosuid,noexec, /boot:nodev,nosuid,noexec, /opt:nodev,nosuid, /srv:nodev,nosuid, /usr:nodev |
The value used is your override (tailoring file), else the profile's, else the one of the profile it extends, else the default. Bounds limit what an override may set.
Audit
- Run
findmnt -kn -o TARGET,SOURCE,OPTIONS. - For each mounted directory of
{{ mount_options }}, the options must contain the listed ones. - Every other line whose source is a
/dev/device, except/and/snap/..., must containnodev.
Automated: every check must pass. Scanners report each check by its id.
options
Mount options of the listed directories and nodev on other local block-device filesystems.
script: |
rc=0 seen=
for e in $CB_MOUNT_OPTIONS; do
p=${e%%:*}
o=$(findmnt -kn -o OPTIONS --mountpoint "$p" | tail -n 1)
[ -n "$o" ] || continue
seen="$seen $p "
miss=
for opt in $(printf '%s' "${e#*:}" | tr , ' '); do
case ,$o, in *,$opt,*) ;; *) miss="$miss $opt" ;; esac
done
if [ -z "$miss" ]; then echo "$p: ok"; else echo "$p: missing$miss"; rc=1; fi
done
other=$(findmnt -knr -o TARGET,SOURCE,OPTIONS | awk '$2 ~ "^/dev/" && $1 != "/" && $1 !~ "^/snap/"')
while read -r t _ o; do
[ -n "$t" ] || continue
case $seen in *" $t "*) continue ;; esac
seen="$seen $t "
case ,$o, in *,nodev,*) echo "$t: ok" ;; *) echo "$t: missing nodev"; rc=1 ;; esac
done <<EOF
$other
EOF
[ -n "$seen" ] || { echo "no separate filesystem besides /"; exit 2; }
exit $rc
Remediation
For each reported directory:
- Add the missing options to the fourth field of its line in
/etc/fstab(for a mount made by a systemd.mountunit, to itsOptions=). - Run
systemctl daemon-reloadandmount -o remount <directory>. - Check with
findmnt -kn <directory>, and reboot at the next maintenance window to confirm.
Test noexec and nosuid first on systems that run software from /opt, /srv or /home.
References
- mount(8), Ubuntu manual pages (filesystem-independent mount options) Canonical, vendor-doc, accessed 2026-10-19
- fstab(5), Ubuntu manual pages Canonical, vendor-doc, accessed 2026-10-19
- ANSSI-BP-028 v2.0 - Recommandations de configuration d'un système GNU/Linux (R28) ANSSI, guide, accessed 2026-10-19
Mappings
| Framework | ID | Relation | Note |
|---|---|---|---|
| ANSSI-BP-028 - Recommandations de configuration d'un système GNU/Linux2.0 | R28 | partial | Ours leaves out noexec on /var (breaks dpkg) and noexec on /home outside the hardened profiles. |
| NIST SP 800-53 Rev. 55.1.1 | CM-7 | related |
How this control relates to the other framework's: equivalent, stricter, looser, partial or related.
Threats mitigated
Related controls
- related
CB-UBU-FS-005Put /home, /var, /var/tmp, /var/log and /var/log/audit on separate filesystems - related
CB-UBU-FS-003Mount /tmp as a separate filesystem with nodev, nosuid and noexec
People and lifecycle
| Authors |
|
| Verified | 2026-10-19 by Sn0wAlice on 20.04, Proxmox VM 2520, Ubuntu 20.04 cloud image, kernel 5.4.0-216-generic. Fails on fresh install (/boot/efi without nodev); snap mounts skipped; loop-mounted /var/tmp fails without options and passes after remount with nodev,nosuid,noexec. |
| Verified | 2026-10-19 by Sn0wAlice on 22.04, Proxmox VM 2522, Ubuntu 22.04 cloud image, kernel 5.15.0-198-generic. Fails on fresh install (/boot/efi without nodev); snap mounts skipped; loop-mounted /var/tmp fails without options and passes after remount with nodev,nosuid,noexec. |
| Verified | 2026-10-19 by Sn0wAlice on 24.04, Proxmox VM 2524, Ubuntu 24.04 cloud image, kernel 6.8.0-147-generic. Fails on fresh install (/boot and /boot/efi without the options); passes once they are added in fstab and remounted, update-initramfs and update-grub still work; loop-mounted /var/tmp fails without options and passes after remount with nodev,nosuid,noexec. |
| Verified | 2026-10-19 by Sn0wAlice on 26.04, Proxmox VM 2526, Ubuntu 26.04 cloud image, kernel 7.0.0-38-generic. Fails on fresh install (/boot and /boot/efi without the options); passes once they are added in fstab and remounted, update-initramfs and update-grub still work; loop-mounted /var/tmp fails without options and passes after remount with nodev,nosuid,noexec. |
| Introduced in | v0.1.0 |
| Created, updated | 2026-10-19, 2026-10-19 |
| Translations | fr |