Administration Linux

Utilisateurs, groupes et permissions Linux : bits rwx, umask, ACL et sudo

Débutant12 min de lectureMis à jour

Cette page a été traduite de l'anglais avec l'aide de l'IA, puis vérifiée par rapport à l'original. Lire la version anglaise

Sur une machine Linux, chaque décision d'accès se ramène à un identifiant utilisateur numérique, un ensemble d'identifiants de groupe et douze bits attachés à un fichier. Ce guide montre où sont stockés les comptes, comment le noyau évalue une vérification de permissions, et comment élargir ou restreindre l'accès sans risque avec chmod, umask, les ACL et sudo. Il se termine par l'authentification SSH par clé, le mode de connexion à adopter sur tout serveur exposé au réseau.

Ce que vous allez apprendre

  • Décrire comment les comptes, les groupes principaux et les groupes secondaires sont stockés et créés
  • Lire et définir des modes de fichier aussi bien sous forme symbolique qu'octale, et prévoir le résultat d'un umask
  • Expliquer le rôle de setuid, setgid et du sticky bit, et les cas où chacun a légitimement sa place
  • Accorder une exception à un utilisateur ou un groupe précis avec une ACL POSIX plutôt qu'en relâchant le mode
  • Déléguer des commandes d'administration avec des règles sudo et se connecter avec une paire de clés SSH

Les permissions sont la première chose que vérifie un système Linux et la dernière que la plupart des gens apprennent correctement. Le modèle tient dans la tête — un identifiant utilisateur numérique, une liste d'identifiants de groupe et douze bits par fichier — mais les détails piègent : pourquoi un chmod 777 sur un répertoire web est à la fois un problème de sécurité et, le plus souvent, même pas la solution ; pourquoi s'ajouter au groupe docker n'a aucun effet tant qu'on ne s'est pas déconnecté ; pourquoi un dossier partagé produit sans cesse des fichiers que personne d'autre ne peut modifier.

Ce guide commence par les comptes eux-mêmes, passe en revue les bits rwx classiques et les bits spéciaux qui les coiffent, puis aborde les deux mécanismes vers lesquels on se tourne quand le modèle classique est trop grossier : les listes de contrôle d'accès et sudo. Les exemples supposent un système récent : Debian, Ubuntu ou une distribution de la famille RHEL. Si le format de sortie de ls -l vous est encore peu familier, lisez d'abord le guide sur le système de fichiers.

Qui vous êtes pour le noyau

Le noyau ne connaît pas les noms d'utilisateur. Il connaît un identifiant utilisateur (UID) et un ensemble d'identifiants de groupe (GID) rattachés à chaque processus. Les noms n'existent que pour rendre les sorties lisibles par des humains ; la traduction se fait en espace utilisateur, via /etc/passwd, /etc/group et le service d'annuaire que la machine est configurée pour consulter.

$ id
uid=1000(alice) gid=1000(alice) groups=1000(alice),27(sudo),110(www-data)

/etc/passwd contient une ligne par compte, aux champs séparés par des deux-points : nom, un x à l'emplacement où se trouvait autrefois le mot de passe haché, UID, GID principal, un champ de commentaire libre, répertoire personnel et shell de connexion. Il est lisible par tous, car de nombreux programmes ont besoin de faire correspondre identifiants et noms.

alice:x:1000:1000:Alice Martin:/home/alice:/bin/bash
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

Les véritables empreintes de mots de passe se trouvent dans /etc/shadow, lisible uniquement par root, avec les informations de vieillissement : date du dernier changement, durées de vie minimale et maximale, période d'avertissement et date d'expiration. Un ! ou un * dans le champ de l'empreinte signifie qu'aucun mot de passe ne pourra jamais correspondre : c'est ainsi que l'on verrouille les comptes de service. Ces comptes reçoivent en outre /usr/sbin/nologin comme shell, afin que même une authentification réussie ne puisse pas ouvrir de session interactive.

Sur la plupart des distributions, les UID inférieurs à 1000 sont réservés au système ; les utilisateurs humains commencent à 1000. L'UID 0 est spécial dans le noyau lui-même : c'est le superutilisateur, pour qui la plupart des vérifications de permissions sont tout simplement ignorées.

Créer et modifier des comptes

sudo useradd -m -s /bin/bash -c "Bob Chen" bob   # -m creates and populates /home/bob
sudo passwd bob
sudo usermod -aG www-data,sudo bob               # -a is essential: append, do not replace
sudo usermod -L bob                              # lock the password
sudo userdel -r bob                              # -r also removes the home directory

Debian et Ubuntu fournissent aussi adduser, une surcouche interactive qui choisit des valeurs par défaut raisonnables et demande le mot de passe. Quel que soit l'outil, l'option la plus importante est -a sur usermod -G : sans elle, la liste des groupes secondaires est remplacée, et plus d'un administrateur s'est ainsi coupé l'accès à sudo.

Les nouveaux répertoires personnels sont initialisés à partir de /etc/skel : tout ce que vous y placez — un .bashrc par défaut, une configuration d'éditeur, un répertoire .ssh avec le bon mode — est copié pour chaque compte créé ensuite.

Groupes principaux et secondaires

Chaque compte possède exactement un groupe principal, enregistré dans /etc/passwd et utilisé comme groupe propriétaire des fichiers qu'il crée. Il peut en outre appartenir à un nombre quelconque de groupes secondaires, listés dans /etc/group.

www-data:x:33:alice,bob
developers:x:1500:alice,bob,carol

La plupart des distributions créent un groupe privé par utilisateur (alice:alice), de sorte qu'un mode par défaut de 0644 n'accorde rien à personne d'autre, même si le fichier est déplacé plus tard dans une zone partagée. L'accès partagé s'exprime alors en créant un groupe au nom explicite et en y ajoutant des membres.

Comme les identifiants sont établis à l'ouverture de la session, id fait foi pour ce que vos processus actuels peuvent faire, tandis que /etc/group montre ce que votre prochaine connexion obtiendra. Si vous ne pouvez pas vous déconnecter, newgrp developers lance un sous-shell avec la nouvelle appartenance.

Les douze bits

Chaque fichier porte un UID propriétaire, un GID de groupe et un mode : trois ensembles de trois bits, plus trois bits spéciaux par-dessus.

BitSur un fichier ordinaireSur un répertoire
rlire le contenulister les noms qu'il contient
wmodifier le contenucréer, renommer et supprimer des entrées
xl'exécuter comme programmele traverser, c'est-à-dire y résoudre des noms

Le noyau évalue dans un ordre strict et s'arrête à la première correspondance : si votre UID est celui du propriétaire, le triplet propriétaire s'applique et rien d'autre n'est consulté ; sinon, si l'un de vos GID correspond au groupe du fichier, c'est le triplet groupe ; sinon, le triplet autres. C'est pourquoi ----rwxrwx refuse tout au propriétaire tout en autorisant tous les autres — un ordre qui surprend ceux qui imaginent que les ensembles se cumulent.

La ligne « répertoire » du tableau a deux conséquences. D'abord, supprimer un fichier est une écriture dans son répertoire, pas dans le fichier : vous pouvez donc supprimer un fichier en lecture seule d'un répertoire où vous avez le droit d'écrire. Ensuite, x sans r sur un répertoire est une combinaison utile : vous pouvez ouvrir /srv/data/report.pdf si vous connaissez le nom, mais pas énumérer le contenu.

Modes octaux

Chaque triplet est un nombre sur trois bits : r=4, w=2, x=1. On les additionne.

OctalSymboliqueUsage typique
644rw-r--r--fichiers de données et de configuration ordinaires
600rw-------clés privées, identifiants, ~/.ssh/id_ed25519
755rwxr-xr-xprogrammes, scripts et la plupart des répertoires
750rwxr-x---un répertoire partagé avec un seul groupe
775rwxrwxr-xun répertoire dans lequel un groupe peut écrire
700rwx------un répertoire privé comme ~/.ssh

chmod accepte les deux formes. La forme symbolique est relative et souvent plus sûre, car elle ne modifie que les bits nommés :

chmod 640 /etc/myapp/secrets.env
chmod u+x deploy.sh          # add execute for the owner only
chmod go-w,o-rx /srv/private # remove group write, and all "other" access
chmod -R u=rwX,g=rX,o= /srv/app   # capital X: execute only where it is already set, or on directories

Retenez ce X majuscule : chmod -R 755 rend exécutables tous les fichiers de données, alors que chmod -R u=rwX,go=rX corrige les répertoires sans prétendre que des fichiers sont des programmes.

La propriété se change avec chown et chgrp, et seul root peut céder un fichier à quelqu'un d'autre :

sudo chown -R www-data:www-data /var/www/example.com
sudo chgrp developers /srv/shared
sudo chown --reference=/etc/nginx/nginx.conf /etc/nginx/conf.d/site.conf

umask : les permissions de naissance des fichiers

Un programme demande un mode lorsqu'il crée un fichier — par convention 0666 pour les données et 0777 pour les répertoires. Le umask du processus retire des bits de cette demande avant la création du fichier. C'est un masque des bits à effacer, pas à accorder.

Avec la valeur par défaut courante 022, un nouveau fichier obtient 0666 & ~022 = 0644 et un nouveau répertoire 0777 & ~022 = 0755. Avec umask 027, le même fichier devient 0640 et le répertoire 0750, invisibles pour les utilisateurs extérieurs au groupe. Choisissez umask 077 sur une machine où rien ne doit être partagé par défaut.

$ umask
0022
$ umask 027; touch a; mkdir b; ls -ld a b
-rw-r-----  1 alice alice    0 Sep  7 11:20 a
drwxr-x---  2 alice alice 4096 Sep  7 11:20 b

Le umask étant une propriété du processus, il est hérité par les processus enfants et doit être défini là où le processus démarre : dans /etc/profile ou ~/.profile pour les shells de connexion, via une directive UMask= pour un service systemd, ou dans la configuration propre au démon. Notez que les fichiers ne reçoivent jamais le bit d'exécution à partir d'une demande 0666 : c'est pourquoi un script extrait d'une archive a si souvent besoin d'un chmod +x explicite.

setuid, setgid et le sticky bit

Au-dessus des neuf bits de permission se trouvent trois bits supplémentaires, affichés aux positions x de ls -l.

setuid (4000, un s dans le triplet propriétaire) fait s'exécuter un programme avec les privilèges de son propriétaire plutôt que ceux de l'appelant. /usr/bin/passwd en est l'exemple canonique : un utilisateur non privilégié doit pouvoir réécrire une ligne de /etc/shadow, et c'est le setuid root qui le permet. Le setuid est puissant et a historiquement causé de nombreuses élévations de privilèges locales : il n'a sa place que sur les binaires de la distribution et quasiment nulle part ailleurs. Traquer les surprises tient en une ligne :

sudo find / -xdev -type f -perm -4000 -printf '%M %u %p\n' 2>/dev/null

setgid (2000) fait la même chose pour le groupe sur un exécutable, mais sa forme la plus utile concerne les répertoires : les fichiers créés à l'intérieur héritent du groupe du répertoire au lieu du groupe principal de leur créateur, et les nouveaux sous-répertoires héritent eux aussi du bit setgid. C'est la recette classique pour un espace de projet partagé.

sudo install -d -o root -g developers -m 2775 /srv/projects

Le sticky bit (1000, un t dans le triplet autres) réserve la suppression, dans un répertoire accessible en écriture à tous, au propriétaire de chaque fichier. /tmp est en drwxrwxrwt précisément pour cette raison : tout le monde peut y créer des fichiers, personne ne peut supprimer ceux des autres.

chmod 2775 /srv/projects   # setgid directory
chmod 1777 /srv/scratch    # sticky, world-writable
chmod g+s,o-rwx /srv/team  # symbolic equivalents

Un répertoire setgid fixe le groupe mais pas le mode : un membre qui crée un fichier avec umask 022 produit toujours rw-r--r--, que ses collègues ne peuvent pas modifier. Associez le bit setgid à un umask 002 pour les utilisateurs concernés, ou utilisez une ACL, ce qui est la meilleure réponse.

Les ACL, quand trois ensembles ne suffisent pas

Une liste de contrôle d'accès (ACL) POSIX attache à un fichier des entrées nommées pour des utilisateurs et des groupes : vous pouvez ainsi donner accès à une personne de plus sans inventer de groupe ni relâcher other. Le système de fichiers doit être monté avec la prise en charge des ACL, ce qui est le cas par défaut pour ext4 et XFS sur les noyaux actuels.

$ setfacl -m u:jenkins:rx /srv/app/bin
$ setfacl -m g:auditors:r /var/log/app/audit.log
$ getfacl /srv/app/bin
# file: srv/app/bin
# owner: deploy
# group: deploy
user::rwx
user:jenkins:r-x
group::r-x
mask::r-x
other::---

ls -l signale un fichier porteur d'une ACL par un + final. L'entrée mask plafonne toutes les entrées nommées ainsi que la classe groupe ; sur un fichier doté d'une ACL, chmod g= modifie le masque et non l'entrée du groupe, d'où ces moments de perplexité du type « je l'ai pourtant accordé, et ça ne marche toujours pas ».

Les ACL par défaut d'un répertoire offrent le mécanisme d'héritage qui manque aux bits classiques. Elles s'appliquent aux entrées créées ultérieurement : un utilisateur de déploiement peut ainsi conserver l'accès en écriture à tout ce qu'un build dépose dans une arborescence :

sudo setfacl -R -m u:deploy:rwx -m d:u:deploy:rwx /var/www/example.com
sudo setfacl -x u:jenkins /srv/app/bin     # remove one entry
sudo setfacl -b /srv/app/bin               # remove the whole ACL

Utilisez les ACL à bon escient et documentez-les. Dans un simple ls -l, rien ne les trahit hormis ce +, et une énigme de permissions que personne ne sait expliquer est pire qu'un groupe un peu maladroit.

Déléguer des privilèges avec sudo

La pratique moderne consiste à désactiver la connexion directe en root et à accorder des privilèges précis via sudo. La politique se trouve dans /etc/sudoers et, de préférence, dans des fichiers sous /etc/sudoers.d/. Éditez-les toujours avec visudo, qui valide la syntaxe avant d'installer le fichier.

# /etc/sudoers.d/deploy   (mode 0440, edited with: sudo visudo -f /etc/sudoers.d/deploy)
Cmnd_Alias APPCTL = /usr/bin/systemctl restart app, /usr/bin/systemctl status app

%developers ALL=(ALL) APPCTL
deploy      ALL=(www-data) NOPASSWD: /usr/bin/rsync

Lisez une règle comme qui host=(sous quelle identité) quoi. La première ligne permet aux membres du groupe developers de redémarrer un service, après avoir saisi leur propre mot de passe. La seconde permet au compte deploy d'exécuter rsync en tant que www-data sans mot de passe, ce dont a besoin un pipeline automatisé.

Deux habitudes gardent sudo sous contrôle. Accordez des commandes, pas des shells : %developers ALL=(ALL) NOPASSWD: ALL revient à donner root avec quelques étapes en plus, et toute commande autorisée capable de lancer un shell ou de modifier un fichier arbitraire (vi, less, find, tar) équivaut à un accès root complet. Et conservez les journaux : chaque appel est enregistré par le journal ou par syslog, ce qui fait de journalctl -t sudo une piste d'audit réellement utile, comme l'explique le guide sur les logs et le dépannage.

Se connecter avec des clés plutôt qu'avec des mots de passe

L'authentification SSH par mot de passe attire les attaques par force brute dès qu'une machine obtient une adresse publique. Les paires de clés éliminent purement et simplement le secret devinable.

ssh-keygen -t ed25519 -C "alice@laptop"        # private key stays on your machine
ssh-copy-id [email protected]           # appends the public key remotely
ssh -o PreferredAuthentications=publickey [email protected]

La clé privée doit être en mode 600 et le répertoire ~/.ssh en 700 ; sshd refuse les clés lisibles par le groupe ou par tous, et il refuse authorized_keys si le répertoire personnel lui-même est accessible en écriture au groupe. Une fois que chaque compte qui a besoin d'un accès dispose d'une clé, durcissez le démon dans /etc/ssh/sshd_config.d/ :

PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
AllowGroups sshusers

Validez avec sudo sshd -t et rechargez plutôt que de redémarrer, et — c'est l'étape que l'on saute — gardez votre session existante ouverte pendant que vous en testez une nouvelle depuis un autre terminal. Une coquille dans sshd_config sur une machine distante, c'est au mieux un ticket de support.

Erreurs fréquentes

chmod 777 comme étape de débogage. Cela donne l'accès en écriture à tous les utilisateurs de la machine et corrige rarement le vrai problème, qui est généralement un mauvais propriétaire ou un x manquant sur un répertoire parent. Trouvez le maillon défaillant avec namei -l /var/www/example.com/index.php.

usermod -G sans -a. La commande supprime silencieusement tous les autres groupes secondaires, y compris sudo et wheel.

Un chmod récursif avec un mode numérique. chmod -R 755 rend exécutables tous les fichiers de configuration et toutes les images. Utilisez u=rwX,go=rX, ou find … -type d -exec chmod 755 et -type f -exec chmod 644.

Croire que les permissions protègent l'historique d'un fichier. Restreindre un mode ne change rien aux copies déjà faites, et un secret commité dans Git ou écrit dans une image de conteneur y reste. Effectuez plutôt une rotation du secret.

Oublier que root ignore les bits. Un mode en lecture seule ne protège pas d'un processus root, pas plus qu'à l'intérieur d'un conteneur qui tourne en root avec le chemin monté en bind mount.

Changer de groupe sans nouvelle session. id reflète la session : c'est là qu'il faut regarder avant de conclure que le groupe n'a pas été pris en compte.

À retenir

  • Le noyau autorise en fonction de l'UID et du GID ; les noms viennent de /etc/passwd et /etc/group, les empreintes et le vieillissement des mots de passe de /etc/shadow.
  • La vérification des permissions s'arrête à la première classe correspondante — propriétaire, puis groupe, puis autres — si bien que les triplets ne se cumulent jamais.
  • Sur un répertoire, x signifie traverser et w créer ou supprimer : c'est pourquoi on peut supprimer un fichier en lecture seule, et pourquoi un x manquant casse tout un chemin.
  • umask retire des bits au moment de la création ; définissez-le dans le profil de connexion ou dans une unité de service, pas après coup.
  • setgid sur un répertoire règle l'héritage du groupe, le sticky bit protège les répertoires ouverts en écriture à tous, et setuid est réservé presque exclusivement aux binaires de la distribution.
  • Recourez à une ACL POSIX, avec une entrée par défaut pour l'héritage, quand un utilisateur ou un groupe a besoin d'une exception ; recourez à des règles sudo limitées à des commandes précises quand un humain a besoin de privilèges.
  • Remplacez les mots de passe SSH par des paires de clés, puis désactivez PasswordAuthentication et vérifiez depuis une deuxième session avant de fermer la première.

Sources et lectures complémentaires

Questions fréquentes

Pourquoi ne puis-je pas entrer dans un répertoire alors que ses fichiers sont lisibles ?
Les répertoires utilisent le bit d'exécution différemment : x donne le droit de traverser le répertoire, c'est-à-dire d'y résoudre un nom. Sans x sur chaque répertoire du chemin, le noyau s'arrête avant même de regarder le fichier. Un répertoire avec r mais sans x permet de lister les noms, mais pas de faire un stat ni d'ouvrir quoi que ce soit : voilà pourquoi 0644 sur un répertoire est presque toujours une erreur.
Je me suis ajouté à un groupe mais j'obtiens toujours « permission denied ». Qu'est-ce qui ne va pas ?
L'appartenance aux groupes est copiée dans les identifiants du processus au moment de la connexion. Votre shell actuel a démarré avant la modification, il porte donc toujours l'ancienne liste. Déconnectez-vous puis reconnectez-vous, ouvrez une nouvelle session, ou lancez newgrp nomdugroupe dans le shell courant. Vérifiez la liste effective avec la commande id plutôt qu'en lisant /etc/group, car le noyau utilise ce qui a été attribué à votre session.
Faut-il modifier /etc/sudoers directement ?
Non. Utilisez visudo, qui verrouille le fichier et refuse d'installer une version dont la syntaxe est invalide. Un fichier sudoers mal formé peut empêcher tous les administrateurs d'élever leurs privilèges sur la machine. Mieux encore : déposez un petit fichier dans /etc/sudoers.d/ et éditez-le avec visudo -f, pour que les mises à jour de paquets n'entrent jamais en conflit avec vos règles et que chaque délégation ait son propre fichier.
Quelle différence entre su et sudo ?
su lance un shell sous l'identité d'un autre utilisateur et demande le mot de passe de celui-ci : quiconque l'utilise doit donc connaître les identifiants du compte cible. sudo exécute une seule commande selon une politique définie dans /etc/sudoers, authentifie l'appelant avec son propre mot de passe et journalise chaque appel. sudo permet de déléguer finement et d'auditer après coup, c'est pourquoi la plupart des distributions désactivent désormais complètement la connexion directe en root.