Aller au contenu
Administration Linux medium

Administrer utilisateurs et groupes

24 min de lecture

Créer un compte, le rattacher aux bons groupes, le modifier sans casser les fichiers qu'il possède, puis le désactiver vraiment le jour du départ : c'est le cycle de vie d'un compte Linux. Cette page vous donne les commandes exactes de chaque étape (useradd, usermod, gpasswd, userdel, chage), la commande de vérification qui va avec, et les deux pièges qui coûtent le plus cher en production : le compte « verrouillé » qui garde son accès SSH, et les fichiers orphelins laissés derrière un compte supprimé.

Les notions de base (UID, GID, root, contenu de /etc/passwd et /etc/group) sont détaillées dans Utilisateurs et groupes Linux. Ici, on passe à l'administration : vous agissez sur le système, avec sudo.

  • Lister les comptes et les groupes réellement connus du système
  • Créer un utilisateur avec son répertoire personnel et son mot de passe
  • Organiser les droits avec des groupes primaires et secondaires
  • Modifier et supprimer un compte sans laisser de fichiers orphelins
  • Désactiver réellement un accès, y compris par clé SSH
  • Vérifier l'état d'un compte avec id, chage -l et passwd -S

Sous Linux, l'identité est le premier mécanisme de sécurité : le noyau n'autorise une lecture, une écriture ou une exécution qu'en fonction de l'UID (identifiant utilisateur) et des GID (identifiants de groupe) du processus qui demande l'accès.

Un utilisateur représente une identité unique. Il peut correspondre à un humain, ou à un service (nginx, postgres) qui doit tourner avec le moins de droits possible. Chaque compte possède un répertoire personnel, un shell de connexion et une liste de groupes.

Un groupe rassemble des utilisateurs qui partagent les mêmes permissions sur des ressources. C'est ce qui rend une politique d'accès maintenable : vous attribuez les droits une fois au groupe, puis vous gérez uniquement des appartenances.

Le cas typique : une équipe de développement. Vous créez un groupe developpeurs, vous donnez l'écriture au dossier /srv/projets à ce groupe, puis vous y ajoutez chaque nouvel arrivant. Aucune permission de fichier n'est retouchée à l'arrivée d'une personne de plus.

Avant toute manipulation, regardez ce qui existe déjà : un compte que vous croyez absent existe peut-être en local, ou vient d'un annuaire (LDAP, Active Directory via SSSD). Créer un doublon d'UID est une source classique de fichiers accessibles par la mauvaise personne.

La commande de référence est getent : elle interroge toutes les sources déclarées dans /etc/nsswitch.conf (le fichier qui décide où le système va chercher les identités), pas seulement les fichiers locaux.

Fenêtre de terminal
getent passwd # tous les comptes connus du système
getent group # tous les groupes connus du système
getent passwd paul # la fiche d'un compte précis

Une fiche getent passwd se lit ainsi : nom, mot de passe (le x renvoie vers /etc/shadow), UID, GID principal, commentaire, répertoire personnel, shell.

Pour vous limiter aux comptes humains, filtrez sur l'UID : les distributions réservent les UID inférieurs à 1000 aux comptes système.

Fenêtre de terminal
awk -F: '$3 >= 1000 && $1 != "nobody" { print $1, $3 }' /etc/passwd

Pour connaître les groupes d'une personne, id est plus complet que groups : il affiche les UID/GID numériques en plus des noms, ce qui permet de repérer tout de suite un décalage d'identifiant.

Fenêtre de terminal
id paul

Sortie sur un compte fraîchement créé :

uid=1001(paul) gid=1001(paul) groups=1001(paul)

La commande universelle est useradd, présente sur toutes les distributions. Seule, elle ne crée pas le répertoire personnel : l'option -m est indispensable.

Fenêtre de terminal
sudo useradd -m paul

Vérifiez immédiatement le résultat, c'est le réflexe à prendre après chaque action :

Fenêtre de terminal
id paul
ls -ld /home/paul

Regardez la sortie de id paul : le groupe principal s'appelle paul, pas users. C'est le comportement par défaut de Debian, Ubuntu et RHEL modernes, piloté par la directive USERGROUPS_ENAB yes du fichier /etc/login.defs : useradd crée un groupe privé homonyme du compte, avec le même identifiant.

L'intérêt est un cloisonnement par défaut : comme personne d'autre n'est membre du groupe paul, les fichiers créés avec des droits de groupe généreux ne fuitent pas vers les autres comptes du serveur. C'est aussi ce qui rend le umask 002 sans danger sur ces distributions.

Deux options permettent de forcer ce comportement dans un sens ou dans l'autre :

  • -U, --user-group : créer le groupe homonyme (comportement par défaut) ;
  • -N, --no-user-group : ne pas le créer, le compte reçoit alors le groupe principal défini par GROUP dans /etc/default/useradd.

Un compte fraîchement créé n'a aucun mot de passe utilisable : le champ correspondant dans /etc/shadow contient !. La connexion par mot de passe est donc impossible tant que vous n'en définissez pas un.

Fenêtre de terminal
sudo passwd paul

La saisie est invisible à l'écran, c'est normal. Vérifiez ensuite l'état du mot de passe, le deuxième champ doit passer de L à P :

Fenêtre de terminal
sudo passwd -S paul

En production, vous fixez souvent le shell, l'UID et parfois le groupe principal. L'exemple ci-dessous crée un compte dont le groupe principal est developpeurs, ce qui remplace le groupe privé homonyme :

Fenêtre de terminal
sudo groupadd developpeurs
sudo useradd -m -s /bin/bash -g developpeurs -u 1050 pierre
id pierre

La sortie confirme les trois choix, shell mis à part :

uid=1050(pierre) gid=1001(developpeurs) groups=1001(developpeurs)

Choisir -g developpeurs signifie que tous les fichiers créés par pierre appartiendront par défaut au groupe developpeurs. C'est pratique pour un dossier partagé, mais cela affaiblit le cloisonnement décrit plus haut : réservez ce montage à des comptes projet, pas au compte d'administration d'une personne.

Les groupes évitent la gestion fichier par fichier. Vous créez un groupe fonctionnel, vous lui donnez les droits sur une ressource, puis vous gérez les appartenances. C'est la base d'une politique d'accès auditable.

Fenêtre de terminal
sudo groupadd developpeurs
getent group developpeurs

Un compte a un seul groupe principal (celui de /etc/passwd) et autant de groupes secondaires que nécessaire. Pour un ajout, l'option -a est obligatoire :

Fenêtre de terminal
sudo usermod -aG developpeurs paul
id paul
  • -a, --append : ajoute sans toucher aux appartenances existantes ;
  • -G, --groups : la liste des groupes secondaires.

Un point qui déroute souvent : une session déjà ouverte conserve les groupes qu'elle avait au moment de la connexion. L'utilisateur doit se reconnecter pour que le nouveau groupe soit pris en compte. La vérification se fait avec id dans la nouvelle session, pas dans l'ancienne.

gpasswd -d retire une appartenance secondaire. Le groupe principal n'est pas concerné.

Fenêtre de terminal
sudo gpasswd -d paul developpeurs
id paul

Le groupe principal se change avec usermod -g. Utile quand le groupe privé homonyme n'a plus de sens, typiquement pour un compte de service qui doit écrire dans une arborescence partagée.

Fenêtre de terminal
sudo usermod -g developpeurs paul
id paul

Attention : les fichiers déjà créés gardent leur ancien groupe. Un chgrp -R est souvent nécessaire derrière, sinon l'utilisateur ne peut plus écrire dans ses propres anciens dossiers via son nouveau groupe.

Fenêtre de terminal
sudo groupdel developpeurs

La commande refuse de supprimer un groupe qui sert de groupe principal à un compte, ce qui est une protection utile :

groupdel: cannot remove the primary group of user 'paul'

Retirez d'abord ces comptes ou changez leur groupe principal. Supprimer un groupe ne supprime aucun utilisateur, mais les fichiers qui portaient ce GID se retrouvent sans groupe nommé : ls -l affichera un numéro brut à la place du nom.

usermod couvre le renommage, le déplacement du répertoire personnel, le changement de shell et d'UID. Ce sont des opérations à faire hors session : demandez à la personne de se déconnecter, sinon les processus en cours gardent l'ancienne identité et écrivent des fichiers avec l'ancien UID.

ObjectifCommandeVérification
Renommer le comptesudo usermod -l pierre paulgetent passwd pierre
Déplacer le répertoire personnelsudo usermod -d /home/pierre -m pierrels -ld /home/pierre
Changer le shellsudo usermod -s /bin/bash pierregetent passwd pierre
Changer l'UIDsudo usermod -u 1234 pierreid pierre

Le renommage avec -l ne déplace pas le répertoire personnel : après usermod -l pierre paul, le compte pierre pointe toujours vers /home/paul. C'est l'option -d combinée à -m qui déplace réellement le contenu.

usermod -u réattribue automatiquement les fichiers situés dans le répertoire personnel, mais pas ceux qui se trouvent ailleurs. Après un sudo usermod -u 1234 paul sur un compte qui possédait un fichier dans /srv/app, voici l'état réel :

-rw-r--r-- 1 1234 0 0 /home/paul/notes.txt <- réattribué
-rw-r--r-- 1 1001 0 0 /srv/app/data.txt <- resté sur l'ancien UID

Le fichier de /srv/app affiche un UID numérique orphelin. Pire : si un autre compte reçoit un jour l'UID 1001, il héritera de ce fichier sans que personne ne l'ait décidé. Notez donc l'ancien UID avant l'opération et corrigez ce qui reste :

Fenêtre de terminal
sudo find / -xdev -uid 1001 -exec chown 1234 {} +

La suppression est définitive et se prépare en trois temps : relever l'UID, archiver ce qui doit l'être, puis supprimer et faire le ménage.

C'est l'étape que tout le monde saute, et elle conditionne la suite : une fois le compte supprimé, le nom n'existe plus et vous ne pouvez plus faire de recherche par nom.

Fenêtre de terminal
id -u pierre # affiche par exemple 1050
Fenêtre de terminal
sudo tar czf /var/backups/pierre-home.tar.gz -C /home pierre

userdel seul retire le compte des bases système mais conserve tous ses fichiers, y compris son répertoire personnel :

Fenêtre de terminal
sudo userdel pierre

L'option -r va plus loin. Son périmètre exact, tel que le décrit son manuel (remove home directory and mail spool), est limité à deux emplacements :

  • le répertoire personnel (/home/pierre) et tout son contenu ;
  • la boîte mail locale (/var/mail/pierre).
Fenêtre de terminal
sudo userdel -r pierre

Tout ce que l'utilisateur possédait ailleurs sur le disque (/srv, /var/www, /opt, /tmp) reste en place, avec un UID qui ne correspond plus à personne.

Ici se cache l'erreur la plus fréquente. La recherche par nom échoue une fois le compte supprimé, puisque find doit résoudre le nom en UID :

Fenêtre de terminal
find / -user pierre
find: 'pierre' is not the name of a known user

Deux méthodes fonctionnent réellement. La première utilise l'UID relevé avant la suppression :

Fenêtre de terminal
sudo find / -xdev -uid 1050 -ls

La seconde ne demande rien : -nouser sélectionne les fichiers dont l'UID n'existe dans aucune base de comptes. C'est le filet de sécurité quand personne n'a noté l'UID.

Fenêtre de terminal
sudo find / -xdev -nouser -ls

L'option -xdev limite la recherche au système de fichiers racine et évite de balayer /proc, /sys et les montages réseau, qui produisent du bruit et allongent la recherche. Répétez la commande sur chaque système de fichiers monté que vous voulez couvrir (sudo find /srv -xdev -nouser -ls).

Chaque fichier trouvé doit ensuite être réattribué à son nouveau responsable, ou supprimé si la donnée est morte :

Fenêtre de terminal
sudo chown -R marie:developpeurs /srv/projets/api-facturation

Créer les comptes et les groupes ne sert à rien tant que les fichiers ne portent pas les bons droits. Le trio à connaître est chmod (les permissions rwx), chown (le propriétaire) et chgrp (le groupe), avec sa notation octale (750, 640) et sa notation symbolique (u+x, g-w).

Ces commandes ont leur page dédiée dans le parcours, et il n'y a aucune raison de les réapprendre ici :

Supprimer n'est pas toujours la bonne réponse. Un départ en congé longue durée, une suspension, une enquête interne : vous voulez bloquer l'accès sans perdre les fichiers ni les réglages. C'est là que la distinction entre verrouiller un mot de passe et désactiver un compte devient critique.

Fenêtre de terminal
sudo passwd -l paul

La commande place un ! devant le hash du mot de passe dans /etc/shadow : aucun mot de passe saisi ne peut plus correspondre. Le compte existe toujours, le répertoire personnel est conservé, et le hash d'origine est préservé, ce qui permet un retour en arrière immédiat avec passwd -u.

sudo usermod -L paul fait exactement la même chose : les deux commandes posent le même ! dans /etc/shadow. Il n'y a pas de « verrouillage global » plus fort d'un côté que de l'autre.

Pour fermer un compte quel que soit le moyen d'authentification, il faut l'expirer :

Fenêtre de terminal
sudo usermod --expiredate 1 paul

La date d'expiration est fixée au 2 janvier 1970, donc dans le passé : le compte est expiré, et toutes les connexions sont refusées, y compris par clé SSH. sudo chage -E 0 paul produit le même effet.

Une désactivation complète combine les trois gestes, dans cet ordre :

Fenêtre de terminal
sudo usermod --expiredate 1 paul # expirer le compte
sudo passwd -l paul # verrouiller le mot de passe
sudo pkill -KILL -u paul # fermer les sessions déjà ouvertes

Le pkill n'est pas décoratif : l'expiration bloque les nouvelles connexions, elle ne tue pas une session SSH en cours. Sans lui, la personne reste sur le serveur jusqu'à ce qu'elle se déconnecte d'elle-même.

Pour réactiver le compte, on lève l'expiration puis on déverrouille le mot de passe :

Fenêtre de terminal
sudo usermod --expiredate "" paul
sudo passwd -u paul

Il faut deux commandes, car aucune ne dit tout. chage -l affiche l'expiration du compte, que passwd -S ignore complètement :

Fenêtre de terminal
sudo chage -l paul
Account expires : Jan 02, 1970

La ligne Account expires doit afficher une date passée pour un compte désactivé, ou never pour un compte actif. Pour l'état du mot de passe :

Fenêtre de terminal
sudo passwd -S paul

Le deuxième champ vaut L, P ou NP. Attention à leur sens exact, car il recouvre l'écriture du champ mot de passe dans /etc/shadow :

ÉtatChamp dans /etc/shadowSignification
Pun hash ($y$j9T$...)Mot de passe utilisable
L! devant le hashVerrouillé, le hash est conservé, passwd -u le rétablit
L* seulJamais de mot de passe utilisable : cas normal des comptes de service
NPchamp videAucun mot de passe : connexion possible sans en saisir, à corriger d'urgence

Le * n'est donc pas la marque d'un verrouillage : c'est l'état d'origine d'un compte système qui n'a jamais eu de mot de passe, et il n'y a rien à « déverrouiller » derrière. Seul le ! signale une action de verrouillage.

Un compte expiré garde un mot de passe parfaitement valide : passwd -S affiche toujours P. C'est bien chage -l qui fait foi pour savoir si un accès est réellement fermé.

La gestion des comptes est la première surface d'attaque d'un serveur : un compte oublié, c'est une porte ouverte qui ne déclenche aucune alerte. Quatre règles couvrent l'essentiel du risque.

Un compte par personne, jamais de compte partagé. Un compte admin utilisé par cinq personnes rend la traçabilité impossible : les journaux ne diront jamais qui a lancé la commande destructrice, et le départ d'une seule personne oblige à changer le secret pour tout le monde.

Les comptes de service n'ont pas de shell. Un service n'a aucune raison de pouvoir ouvrir une session interactive. Créez-le avec -r (compte système, UID inférieur à 1000) et un shell qui refuse la connexion :

Fenêtre de terminal
sudo useradd -r -s /usr/sbin/nologin -M exportateur-metriques

Le chemin du shell diffère selon la distribution : /usr/sbin/nologin sur Debian et Ubuntu, /sbin/nologin sur RHEL. L'option -M évite de créer un répertoire personnel inutile.

Passez par sudo, pas par root. Donnez les droits nécessaires via sudo et limitez les commandes autorisées, au lieu de distribuer un accès root complet. Un accès root partagé présente le même défaut de traçabilité qu'un compte partagé.

Auditez régulièrement. Deux commandes suffisent à repérer les dérives : la première liste l'état du mot de passe de tous les comptes, la seconde montre qui ne s'est jamais connecté.

Fenêtre de terminal
sudo passwd -Sa | awk '$2 == "NP" { print "SANS MOT DE PASSE:", $1 }'
lastlog | grep -i "never logged in"

Tout compte humain qui ressort en NP, ou qui ne s'est jamais connecté depuis des mois, doit être expiré puis supprimé après archivage. Le rollback est simple tant que vous n'avez pas supprimé : usermod --expiredate "" <compte> remet l'accès en service.

Les erreurs de gestion de comptes se ressemblent toutes : l'action semble avoir réussi, mais l'accès ou les droits ne suivent pas. Voici les symptômes les plus fréquents et leur cause réelle.

SymptômeCause probableSolution
L'ancien salarié se connecte encore en SSHMot de passe verrouillé, mais compte non expirésudo usermod --expiredate 1 <compte> puis sudo pkill -KILL -u <compte>
find: '<nom>' is not the name of a known userLe compte a été supprimé, find -user ne peut plus résoudre le nomsudo find / -xdev -nouser -ls
L'utilisateur ajouté à un groupe n'a toujours pas les droitsSa session date d'avant l'ajoutDéconnexion/reconnexion, puis contrôle avec id
ls -l affiche un nombre à la place du propriétaireFichier orphelin après userdel ou usermod -usudo chown <nouveau_proprietaire> <fichier>
groupdel: cannot remove the primary group of userLe groupe est le groupe principal d'un compteChanger ce groupe principal (usermod -g) avant de supprimer
useradd: UID 1050 is not uniqueL'UID est déjà pris par un autre compteChoisir un autre UID, ou laisser le système l'attribuer

Ces habitudes coûtent quelques secondes à la création d'un compte et évitent des heures d'archéologie six mois plus tard.

Adoptez une convention de nommage. Minuscules, sans accent ni espace, format cohérent (prenom.nom). Pour les groupes, nommez l'activité (dev, infra, compta), pas la personne ni le serveur : un groupe survit à ceux qui le composent.

N'éditez jamais /etc/passwd, /etc/group ou /etc/shadow à la main. Un caractère de travers dans ces fichiers peut empêcher toute connexion, y compris celle de root. Utilisez usermod, groupmod, gpasswd, ou les éditeurs vipw et vigr qui posent un verrou et contrôlent la syntaxe avant d'écrire.

Forcez le changement de mot de passe à la première connexion. Le mot de passe initial transite forcément par un canal imparfait : il ne doit pas survivre à la première session.

Fenêtre de terminal
sudo chage -d 0 paul

Générez ce mot de passe initial avec un outil, pas avec votre imagination : openssl rand -base64 18, ou pwgen -s 16 1 si vous installez le paquet pwgen.

Gérez des groupes, pas des permissions individuelles. Un droit posé directement sur un compte est invisible dans une revue d'accès. Un droit posé sur un groupe se lit d'un coup d'oeil avec getent group, et se retire avec un seul gpasswd -d.

Documentez les mouvements. Qui a été créé, dans quels groupes, par qui, et pourquoi. Le jour de l'audit, ou le jour où un accès inexpliqué apparaît, cette trace vaut tous les outils.

Le cycle de vie d'un compte s'apprend les mains sur le clavier. Deux labs prolongent ce guide : le premier vous fait créer un compte avec un UID, un shell et des groupes imposés, en vérifiant chaque choix avec id ; le second vous fait poser une politique d'expiration et de complexité des mots de passe, puis prouver qu'elle s'applique réellement.

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • useradd -m crée un groupe privé homonyme, pas un groupe users : c'est le comportement par défaut sur Debian, Ubuntu et RHEL, piloté par USERGROUPS_ENAB yes dans /etc/login.defs.
  • usermod -aG sans le -a écrase toutes les appartenances secondaires existantes, y compris sudo. Et un nouveau groupe n'est actif qu'après reconnexion.
  • passwd -l et usermod -L font la même chose : ils posent un ! devant le hash et ne bloquent pas les clés SSH. Seule l'expiration (usermod --expiredate 1) ferme réellement un compte.
  • chage -l fait foi, pas passwd -S : un compte expiré affiche toujours un mot de passe P. La ligne Account expires est la seule preuve.
  • Dans /etc/shadow, ! = verrouillé, * = jamais de mot de passe (comptes de service), champ vide = aucun mot de passe, donc à corriger d'urgence.
  • userdel -r ne supprime que le répertoire personnel et la boîte mail. Tout ce que le compte possédait dans /srv, /var/www ou /opt reste en place.
  • Relevez l'UID avec id -u avant de supprimer : après coup, find -user échoue et il ne reste que sudo find / -xdev -nouser -ls pour retrouver les fichiers orphelins.
  • Un compte de service n'a pas de shell : useradd -r -s /usr/sbin/nologin (/sbin/nologin sur RHEL), et les humains passent par sudo, jamais par root.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn