Un peu d'histoire ! La gestion des privilèges sur Linux/BSD/UNIX (root ou rien ?)

1. Pourquoi « root ou rien » dans les premiers Unix ?

À l'origine, Unix ne distinguait que deux mondes : UID 0 (root) et les autres.
Cette simplicité historique tenait à la taille du noyau, à la compatibilité logicielle et à la facilité d'audit : on surveillait simplement qui obtenait root via su ou sudo.

Plutôt que d'inventer un « root‑light » universel, les Unix modernes ont choisi de démanteler progressivement les pouvoirs de root et de les attribuer finement :

En pratique, l'administrateur compose ces briques selon le besoin : par exemple un démon Linux peut être lancé en conteneur rootless, n'avoir que CAP_NET_BIND_SERVICE, et être encore muselé par un profil SELinux ; un service FreeBSD tourne dans une jail, puis s'autolimite avec Capsicum ; OpenBSD impose pledge dans le code source et délègue les rares commandes critiques via doas.

Résultat : il existe déjà des « super‑utilisateurs limités », mais ils sont fabriqués à la carte en agrégeant de minuscules privilèges plutôt qu'en définissant un nouvel UID magique.
C'est plus souple, plus sûr et plus évolutif qu'un rôle « semi‑root » figé.


2. Mécanismes généraux de délégation/fractionnement des privilèges

Mécanisme Sur quel noyau ? Idée directrice
set‑user‑ID & set‑group‑ID POSIX (tous les Unix) Lancer un programme ponctuellement avec l'UID/GID indiqué sur l'inode.
Groupes & ACL POSIX.1e Tous Donner un droit fin (lecture, écriture...) à d'autres utilisateurs ou groupes.
Capabilities POSIX (aka « privilèges ») Linux, Solaris/Illumos, partiellement FreeBSD Décomposer root en dizaines de capabilités « monter un FS », « changer l'heure », « raw socket », etc. stockées dans le cred du processus ou sur l'inode.
MAC / LSM / RBAC SELinux/SMACK/AppArmor (Linux), MAC FreeBSD, RBAC Solaris, systrace/pledge OpenBSD Politique externe qui décide : « ce contexte peut faire X ».
Confinement d'espace chroot, jail FreeBSD, zone Solaris, conteneur/namespaces Linux On donne même UID 0, mais dans un espace restreint (filesystem, réseau, PID, user NS...).
Securelevel {Net,Open,Free}BSD Basculer le noyau en mode « gel » : plus de montages en RW, pas de kldload, etc.
Sandbox système d'appels seccomp Linux, pledge/unveil OpenBSD, Capsicum FreeBSD Restreindre la surface kernel visible par le processus.

3. Détail par famille de noyaux

3.1 Linux

Fonction Depuis Description
POSIX Capabilities (capabilities(7)) 2.2 (1999) puis 2.6+ 38 capabilités aujourd'hui (ex. CAP_SYS_MODULE, CAP_NET_BIND_SERVICE). Stockées en 4 jeux : permitted, effective, inheritable, bounding set + depuis 4.3 ambient. Ajout possible par setcap, suppression globale via prctl(PR_CAPBSET_DROP).
Namespaces 2.4 → 6.0 user, pid, mnt, net, ipc, uts, cgroup, time. Dans un user NS, uid 0 n'est plus root hors du namespace.
LSM (SELinux, AppArmor, etc.) 2.6 Hook linéaire au cœur du noyau. SELinux implémente un RBAC complet ; un rôle peut posséder juste le droit « monter /tmp » mais pas « kill un processus système ».
seccomp‑BPF 3.5 Filtrage de syscalls au cas par cas.
Landlock 5.13 Sandboxing extensible par l'utilisateur non‑root via règles eBPF sur l'arborescence.
File capabilities 2.6.24 Équivalent plus sûr du set‑uid : un binaire n'hérite que des capabilités listées dans son xattr security.capability.

3.2 FreeBSD

Fonction Depuis Description
MAC Framework 5.0 (2003) Modules mac_bsdextended, mac_portacl, mac_seeotheruids... Politique composite possible (MLS, Biba, etc.).
Jail(8) 4.0 (2000) Confinement kernel‑level ; root à l'intérieur n'a aucun privilège hors de sa jail.
Capsicum 9.0 (2012) Mode capability‑based au niveau file‑descriptor : un processus peut se « capter » (cap_enter()) puis ne plus jamais ouvrir de nouvel objet, seulement utiliser des descripteurs déjà limités par des rights.
Securelevel 2.1 Seuil « kern.securelevel » ≥ 1 : plus de kldload, plus d'horloge réglable, FS système en RO, etc.
Hier(7) privilèges noyau Interne FreeBSD décompose déjà root en ~130 privilèges (priv(9)) consommés par chaque syscall ; un module MAC peut en refuser tout ou partie.

3.3 OpenBSD

Fonction Depuis Description
pledge(2) 5.9 (2016) Le code source appelle pledge("stdio rpath inet", NULL) ; le noyau tue le proc dès qu'il sort de la liste.
unveil(2) 6.4 (2018) Limite l'accès chemin par chemin (unveil("/var/db", "rw")).
Securelevel 2.0 Même principe que FreeBSD.
doas(1) Userland Délégation à la sudo mais avec syntaxe minimaliste.
chroot partout Culturel Beaucoup de démons (httpd, smtpd, bgpd) démarrent ‑u _toto et immédiatement chroot("/").

3.4 NetBSD

3.5 Solaris / Illumos (exemple d'Unix propriétaire)

Fonction Depuis Description
Privileges(5) Solaris 10 (2005) Root est réduit à ~80 privilèges (proc_exec, sys_time, ...). Tout compte peut en recevoir une liste blanche persistante (user_attr, ppriv).
RBAC complet 8 → 10 Triptyque rolesprofilesauthorizations ; pfexec joue le rôle d'un sudo intégré au noyau.
Zones 10 Combinaison de container + RBAC : dans une zone non‑globale, même un vrai root n'a pas sys_config.

3.4 NetBSD

3.5 Solaris / Illumos (exemple d'Unix propriétaire)

Fonction Depuis Description
Privileges(5) Solaris 10 (2005) Root est réduit à ~80 privilèges (proc_exec, sys_time, ...). Tout compte peut en recevoir une liste blanche persistante (user_attr, ppriv).
RBAC complet 8 → 10 Triptyque rolesprofilesauthorizations ; pfexec joue le rôle d'un sudo intégré au noyau.
Zones 10 Combinaison de container + RBAC : dans une zone non‑globale, même un vrai root n'a pas sys_config.

4. Alors... pourquoi n'a‑t‑on pas simplement inventé « root‑light » ?


5. Comment « faire » aujourd'hui ?

# Création d'un service « backup » qui ne sait QUE monter /dev/sdb et changer d'uid
setcap cap_sys_admin,cap_dac_read_search=eip /usr/local/bin/backup
systemd-analyze security backup.service # vérifie la surface

ou démarrer dans un conteneur rootless (podman run --uidmap 0:10000:1 ...).

Démon → service foo onestart à l'intérieur d'une jail + capsicum dans le code source.

Ajouter pledge("stdio rpath sendfd") et doas.conf(5) pour n'autoriser que doas -u _postgres pg_dump.

useradd -P"File System Backup" -A"solaris.device.mount" backupop
rolemod -K type=role backupop

Conclusion

Le « super‑utilisateur intermédiaire » n'est pas un nouvel UID ; il est réalisé par la décomposition (capabilities, privilèges), l'encadrement (MAC/RBAC), ou l'isolation (jail/namespace). Chaque famille Unix propose ses briques ; c'est à l'administrateur de composer la dose exacte de pouvoir, plutôt que d'adopter un rôle « semi‑root » monolithique qui serait soit trop faible, soit trop dangereux.


⬆️ Retour en haut de la page