Description
With kernel.apparmor_restrict_unprivileged_userns = 1, an unprivileged process can only
create a user namespace when its AppArmor profile allows it (the userns rule). Unconfined
programs get a namespace without any capability in it. Ubuntu ships profiles that grant the
right to the programs that need it, such as browsers, Flatpak, LXC, Podman and Buildah.
Ubuntu turns it on by default in /usr/lib/sysctl.d/10-apparmor.conf from 24.04 on. The
control guards against the common workaround of setting it back to 0 system-wide. Unlike
kernel.unprivileged_userns_clone, it keeps namespaces available to the programs that are
allowed to use them.
Rationale
Inside a user namespace, an unprivileged user holds capabilities such as CAP_NET_ADMIN or
CAP_SYS_ADMIN over the namespace, which exposes large parts of the kernel (netfilter,
filesystems, network stacks) to them. Many local privilege escalation exploits start by
creating one. Restricting namespaces to profiled programs removes that entry point for
everything else.
Impact
None on a default install. A program that needs user namespaces and has no AppArmor profile
(a self-built browser, an application from outside the archive, some sandboxing or container
tools) fails to start its sandbox. Give it a profile with the userns, rule in
/etc/apparmor.d/ instead of turning the restriction off for the whole system.
Applies when
Versions: 24.0426.04
The sysctl only exists in Ubuntu kernels from 23.10 on. The 20.04 and 22.04 kernels do not have it.
Setting
| Location | sysctl `kernel.apparmor_restrict_unprivileged_userns`, persisted in `/etc/sysctl.d/` |
| Default | 1 |
| Recommended | 1 |
Audit
Run sysctl kernel.apparmor_restrict_unprivileged_userns. The value must be 1.
Then check that no sysctl configuration file sets it to 0.
Automated: every check must pass. Scanners report each check by its id.
running
Running value of kernel.apparmor_restrict_unprivileged_userns.
key: kernel.apparmor_restrict_unprivileged_userns
value: 1
Remediation
Comment out every assignment of the key in /etc/sysctl.conf, /etc/sysctl.d/ and
/run/sysctl.d/ (a file such as 99-userns.conf sorts after 60-cirsec.conf and wins), create
/etc/sysctl.d/60-cirsec.conf containing kernel.apparmor_restrict_unprivileged_userns = 1,
then run sysctl --system.
| Restart | none |
| Disruption | low |
Rollback
Remove the line from /etc/sysctl.d/60-cirsec.conf and run sysctl --system. Commented-out
assignments can be restored from the backup directory /var/backups/cirsec/.
set
# CB-UBU-BOOT-016: set kernel.apparmor_restrict_unprivileged_userns = 1 for good.
# The usual workaround puts "= 0" in a file such as /etc/sysctl.d/99-userns.conf, which sorts after
# 60-cirsec.conf and would win at the next boot: such assignments are commented out (with a backup).
k=kernel.apparmor_restrict_unprivileged_userns
re='^[[:space:]]*kernel[./]apparmor_restrict_unprivileged_userns[[:space:]]*='
c=/etc/sysctl.d/60-cirsec.conf
for f in /etc/sysctl.conf /etc/sysctl.d/*.conf /run/sysctl.d/*.conf; do
[ -f "$f" ] && [ "$f" != "$c" ] || continue
grep -Eq "$re" "$f" || continue
cb_backup "$f"
sed -i --follow-symlinks -E "s|$re|# Disabled by CIRSEC Baselines CB-UBU-BOOT-016: &|" "$f"
done
cb_backup "$c"
touch "$c"
sed -i '/^[[:space:]]*kernel\.apparmor_restrict_unprivileged_userns[[:space:]]*=/d' "$c"
printf '%s = 1\n' "$k" >>"$c"
sysctl -q -w "$k=1"
Handwritten code reads parameters from CB_<NAME> environment variables. Each release turns these fixes into remediate.sh and an Ansible role per profile: dry run by default, a fix runs only when its check fails.
References
- Ubuntu Security documentation - AppArmor (unprivileged user namespace restrictions) Canonical, vendor-doc, accessed 2026-10-19
- Ubuntu blog - Restricted unprivileged user namespaces are coming to Ubuntu 23.10 Canonical, vendor-doc, accessed 2026-10-19
Mappings
| Framework | ID | Relation |
|---|---|---|
| NIST SP 800-53 Rev. 55.1.1 | AC-6 | related |
| 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
| Taxonomy | ID |
|---|---|
| MITRE ATT&CK | T1068 |
Related controls
- requires
CB-UBU-BOOT-008Install and enable AppArmor - related
CB-UBU-BOOT-009Stop unconfined unprivileged processes from switching AppArmor profiles
People and lifecycle
| Authors |
|
| Verified | 2026-10-19 by Sn0wAlice on 24.04, Proxmox VM, Ubuntu 24.04 cloud image, kernel 6.8.0-147-generic, BIOS boot. Passes on a fresh install (1); with /etc/sysctl.d/99-userns.conf setting 0 it fails, the fix comments it out; 1 kept after reboot; strict snap runs, unprivileged unshare -U refused. |
| Verified | 2026-10-19 by Sn0wAlice on 26.04, Proxmox VM, Ubuntu 26.04 cloud image, kernel 7.0.0-38-generic, BIOS boot. Passes on a fresh install (1); with /etc/sysctl.d/99-userns.conf setting 0 it fails, the fix comments it out; 1 kept after reboot; strict snap runs, unprivileged unshare -U refused. |
| Introduced in | v0.1.0 |
| Created, updated | 2026-10-19, 2026-10-19 |
| Translations | fr |