Déléguer, c'est autoriser une personne à lancer une commande précise avec
des privilèges élevés, et rien d'autre. Le fichier /etc/sudoers est
l'endroit où cette frontière s'écrit : un développeur qui doit redémarrer
nginx n'a besoin ni du mot de passe root, ni d'un compte partagé, ni
d'un accès à rm. Vous allez apprendre à écrire une règle correcte, à la
valider avec visudo avant qu'elle ne verrouille la machine, à la
ranger dans /etc/sudoers.d/ et à vérifier ensuite qui peut
réellement quoi.
Cette page traite de la configuration. Si vous cherchez simplement à
lancer une commande privilégiée sur votre poste, à ouvrir un shell root ou
à comprendre le groupe sudo, commencez par Utiliser sudo : exécuter une
commande en
root.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Écrire une règle sudoers (
utilisateur hôte=(cible) commandes) - Éditer sudoers avec
visudosans vous verrouiller hors du système - Regrouper les règles avec
User_Alias,Cmnd_AliasetRunas_Alias - Déléguer une commande sans mot de passe grâce à
NOPASSWD, et connaître son coût - Auditer les droits réels avec
sudo -lU <user>et les journaux système
Le modèle de délégation de sudo
Section intitulée « Le modèle de délégation de sudo »Sans sudo, il n'existe que deux états : vous êtes root, ou vous ne l'êtes pas. Cette binarité pousse aux pires pratiques, le mot de passe root partagé dans un gestionnaire d'équipe, ou le compte de service utilisé par cinq personnes. Plus personne ne sait qui a lancé quoi, et le départ d'un collaborateur impose de tout changer.
sudo casse cette binarité en introduisant un troisième état : une identité nominative qui reçoit un sous-ensemble de privilèges. Le principe est celui du moindre privilège : n'accordez que ce qui est strictement nécessaire à la tâche, pour réduire la surface d'attaque autant que la surface d'erreur. Un compte compromis ne rend alors accessible que la poignée de commandes qui lui étaient déléguées.
Ce modèle repose sur trois questions auxquelles chaque règle répond : qui est autorisé, sous quelle identité la commande s'exécute, et quelles commandes exactement sont permises. Tout le reste de cette page consiste à répondre proprement à ces trois questions.
Éditer sudoers sans se verrouiller
Section intitulée « Éditer sudoers sans se verrouiller »Une erreur de syntaxe dans /etc/sudoers n'est pas un incident
bénin : sudo refuse alors le fichier entier et plus personne ne peut
élever ses privilèges, y compris vous. Sur un serveur distant sans accès
console, cela devient un incident de production. C'est la raison d'être de
visudo : il ouvre une copie de travail, verrouille le fichier
contre les éditions concurrentes et surtout contrôle la syntaxe avant
de remplacer l'original.
sudo visudo # édition de /etc/sudoerssudo visudo -f /etc/sudoers.d/webops # édition d'un fichier dédiéRefusez l'habitude de nano /etc/sudoers, même « juste pour une ligne ».
Pour contrôler un fichier sans l'éditer, par exemple après un
déploiement automatisé, visudo -c valide l'ensemble de la configuration :
sudo visudo -c/etc/sudoers: parsed OK/etc/sudoers.d/README: parsed OK/etc/sudoers.d/webops: parsed OKChaque fichier doit répondre parsed OK. Tant que cette commande
renvoie une erreur, considérez que votre configuration est cassée et
gardez impérativement un terminal root déjà ouvert à côté pour réparer.
Anatomie d'une règle sudoers
Section intitulée « Anatomie d'une règle sudoers »Une règle sudoers tient sur une ligne et se lit en quatre morceaux. La comprendre, c'est pouvoir écrire n'importe quelle délégation sans copier un exemple au hasard sur un forum.
marc ALL = (root) /usr/bin/systemctl restart nginx | | | | | | | +-- les commandes autorisées | | +------------------------ l'identité cible (« sous qui ») | +------------------------------- l'hôte où la règle s'applique +--------------------------------------- qui est autoriséLe premier champ désigne toujours qui : un utilisateur
(marc), un groupe préfixé de % (%webops), ou un User_Alias
défini plus haut dans le fichier. Le champ hôte vaut presque toujours
ALL : il n'a d'intérêt que si vous distribuez un sudoers commun à
plusieurs machines. L'identité cible entre parenthèses indique sous
quel compte la commande s'exécutera, (root) dans l'immense majorité des
cas, et peut préciser un groupe avec (root:root). Enfin viennent les
commandes, en chemin absolu.
Deux règles fondatrices en découlent, à graver avant d'écrire quoi que ce soit :
- Le chemin doit être absolu.
systemctlseul ne matche rien ; il faut/usr/bin/systemctl. Vérifiez le chemin réel aveccommand -v systemctl, il varie entre distributions. - La dernière règle qui matche gagne. Contrairement au réflexe « premier match » des pare-feux, sudo applique la dernière correspondance. Une règle permissive placée après une règle restrictive annule cette dernière.
Regrouper les règles avec les alias
Section intitulée « Regrouper les règles avec les alias »Passé trois utilisateurs et cinq commandes, écrire une ligne par personne
devient ingérable. sudoers propose pour cela des alias, des étiquettes
que vous définissez et réutilisez. C'est le seul mécanisme de
regroupement du format, avec les groupes système (%webops).
Trois types d'alias couvrent les besoins réels. Ils se définissent en tête de fichier, avant les règles qui les emploient :
| Alias | Regroupe | Exemple |
|---|---|---|
User_Alias | Des utilisateurs autorisés | User_Alias WEBOPS = marc, sophie |
Cmnd_Alias | Des commandes (chemins absolus) | Cmnd_Alias NGINX_OPS = /usr/bin/systemctl reload nginx |
Runas_Alias | Des identités cibles | Runas_Alias DEPLOYER = deploy |
Voici une délégation complète et cohérente : l'équipe web peut recharger et
redémarrer nginx, lire les journaux du service, et lancer rsync sous
l'identité technique deploy. Personne ne reçoit root.
User_Alias WEBOPS = marc, sophieRunas_Alias DEPLOYER = deployCmnd_Alias NGINX_OPS = /usr/bin/systemctl reload nginx, /usr/bin/systemctl restart nginxCmnd_Alias LOGS = /usr/bin/journalctl -u nginx *
WEBOPS ALL=(root) NOPASSWD: NGINX_OPS, LOGSWEBOPS ALL=(DEPLOYER) NOPASSWD: /usr/bin/rsyncValidez, puis vérifiez ce que le système a réellement compris de vos intentions, ce qui n'est pas toujours ce que vous croyez avoir écrit :
sudo visudo -c -f /etc/sudoers.d/delegationsudo -lU marc/etc/sudoers.d/delegation: parsed OK
User marc may run the following commands on serveur: (root) NOPASSWD: /usr/bin/systemctl reload nginx, /usr/bin/systemctl restart nginx, /usr/bin/journalctl -u nginx * (deploy) NOPASSWD: /usr/bin/rsyncLes alias ont été résolus : sudo affiche les commandes réelles, pas les
étiquettes. Un %groupe système reste souvent préférable à un User_Alias
quand les membres changent souvent : vous ajoutez le collaborateur au
groupe avec usermod -aG sans jamais rouvrir sudoers.
Déléguer sans mot de passe avec NOPASSWD
Section intitulée « Déléguer sans mot de passe avec NOPASSWD »Par défaut, une règle sudoers demande le mot de passe de l'appelant. Le
tag NOPASSWD: lève cette demande pour les commandes qui suivent. Il
est indispensable pour les scripts et les agents de CI qui n'ont
aucun terminal pour saisir un mot de passe, et pratique pour une commande
lancée cinquante fois par jour.
%webops ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginxLe membre du groupe exécute alors la commande sans aucune saisie, et seulement celle-là :
sudo -n systemctl restart nginx # autorisé, aucun mot de passesudo -n systemctl stop nginx # non déléguéSorry, user marc is not allowed to execute '/usr/bin/systemctl stop nginx' as root on serveur.Le refus est net et tracé. C'est exactement le comportement recherché :
restart est permis, stop ne l'est pas, alors que les deux commandes
diffèrent d'un mot.
Le piège de l'identité cible
Section intitulée « Le piège de l'identité cible »L'identité cible entre parenthèses n'est pas décorative, et c'est là que se niche l'erreur la plus fréquente. On croise souvent une règle de ce genre, censée laisser un développeur redémarrer le serveur web « sous le compte du serveur web » :
# Règle inopérante : ne la copiez pasweb_admin ALL=(www-data) /usr/bin/systemctl restart nginxElle échoue pour deux raisons distinctes. D'abord, elle ne porte pas
le tag NOPASSWD: : le mot de passe sera demandé, contrairement à ce
qu'affirment bien des tutoriels qui recopient cet exemple. Ensuite et
surtout, systemctl restart s'adresse à systemd via D-Bus, et
systemd exige que l'appelant soit root ou passe par une autorisation
polkit. Exécutée sous www-data, la commande est rejetée :
Failed to restart nginx.service: Interactive authentication required.La cible correcte pour piloter un service est donc (root). L'identité
cible autre que root garde tout son sens pour d'autres usages, par exemple
lancer un script de déploiement sous un compte technique dédié, comme
le (DEPLOYER) de l'exemple précédent.
Ranger les règles dans /etc/sudoers.d/
Section intitulée « Ranger les règles dans /etc/sudoers.d/ »Modifier /etc/sudoers directement pose un problème pratique : le fichier
appartient au paquet de la distribution et chaque mise à jour majeure
peut vous poser une question de conflit. La bonne pratique consiste à
laisser ce fichier tranquille et à déposer vos règles dans des fichiers
dédiés, un par usage, sous /etc/sudoers.d/. La dernière ligne du
sudoers principal les inclut :
@includedir /etc/sudoers.dLa directive moderne est @includedir ; les formes #includedir et
#include sont des alias historiques d'avant sudo 1.9.1 et
fonctionnent encore. sudo lit tous les fichiers du répertoire, en
ordre lexical, ce qui explique la convention de préfixe numérique
(10-webops, 20-dba) pour maîtriser l'ordre d'application, souvenez-vous
que la dernière règle qui matche gagne.
Deux contraintes non négociables pèsent sur ces fichiers, et elles sont la cause de la quasi-totalité des « ma règle ne fait rien » :
- Les droits doivent être
0440 root:root. Un fichier trop permissif est ignoré, avec un avertissement au login.visudo -fpose les bons droits tout seul. - Le nom ne doit contenir ni point ni tilde final. sudo saute silencieusement tout fichier dont le nom contient un
.ou finit par~. Un drop-in nommé10-webops.confn'est jamais lu, et rien ne vous prévient.
Le second piège mérite un test systématique. Après avoir déposé un fichier,
ne supposez pas qu'il est actif : demandez à sudo ce qu'il en pense avec
sudo -lU <user>. Si la sortie n'a pas changé, le fichier est ignoré.
Comment sudo prend sa décision
Section intitulée « Comment sudo prend sa décision »Comprendre l'ordre des vérifications permet de diagnostiquer un refus sans
tâtonner. Quand un utilisateur tape une commande préfixée de sudo, le
schéma suivant se déroule à chaque appel.
sudo lit sudoers et ses inclusions, puis cherche une règle qui
corresponde simultanément à quatre critères : l'utilisateur
appelant (directement, via un %groupe ou un User_Alias), l'hôte
courant, l'identité cible demandée avec -u (root par défaut), et la
commande avec ses arguments. Si plusieurs règles correspondent, la
dernière l'emporte.
La décision qui en sort est binaire. Autorisé : sudo demande le mot de
passe si NOPASSWD: est absent et si le timestamp de la session a
expiré, puis exécute la commande sous l'identité cible. Refusé : sudo
affiche Sorry, user ... is not allowed to execute ... et journalise
la tentative. Ces deux issues laissent une trace nominative, ce qui fait de
sudo un outil d'imputabilité autant que de délégation.
Auditer qui peut faire quoi
Section intitulée « Auditer qui peut faire quoi »C'est ici que se corrige l'idée fausse la plus répandue : sudo -l ne
liste que les droits de l'utilisateur qui l'appelle. Cette commande ne
donne aucune vue d'ensemble du système et ne répond pas à la question
« qui a des droits sudo sur cette machine ? ».
Pour inspecter le compte d'un autre utilisateur, il faut l'option
-U, exécutée avec les privilèges d'administration :
sudo -lU marcMatching Defaults entries for marc on serveur: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
User marc may run the following commands on serveur: (root) NOPASSWD: /usr/bin/systemctl reload nginx, /usr/bin/systemctl restart nginxPour obtenir la cartographie complète de la machine, aucune option
magique n'existe : il faut itérer sudo -lU sur les comptes humains.
La boucle suivante parcourt les UID de comptes réels et affiche la
situation de chacun :
getent passwd | awk -F: '$3>=1000 && $3<65534 {print $1}' | while read -r u; do echo "--- $u" sudo -lU "$u" | grep -E "may run|not allowed"done--- ubuntuUser ubuntu may run the following commands on serveur:--- web_adminUser web_admin is not allowed to run sudo on serveur.--- marcUser marc may run the following commands on serveur:Cette boucle donne la photo de l'état configuré. Pour l'état réel, autrement dit ce qui a effectivement été exécuté, les journaux prennent le relais. sudo journalise chaque appel, autorisé comme refusé :
journalctl -t sudo --no-pager | tail -5Jul 12 08:39:12 serveur sudo[3594]: marc : PWD=/ ; USER=root ; COMMAND=/usr/bin/systemctl restart nginxJul 12 08:41:22 serveur sudo[3870]: marc : command not allowed ; PWD=/ ; USER=root ; COMMAND=/usr/bin/systemctl stop nginxChaque ligne nomme l'appelant (marc), l'identité cible
(USER=root), la commande complète et le verdict : une tentative
refusée apparaît explicitement en command not allowed. Sur les
distributions qui utilisent encore un fichier texte, les mêmes lignes
arrivent dans /var/log/auth.log (Debian/Ubuntu) ou /var/log/secure
(RHEL). Une rafale de refus sur un compte est un signal à traiter
immédiatement.
Bonnes pratiques de délégation
Section intitulée « Bonnes pratiques de délégation »Une délégation mal écrite offre un chemin d'élévation vers root tout en donnant l'illusion de la restriction. Ces réflexes coûtent peu et évitent la faille.
Fuyez les jokers dans les chemins. Une règle
%devs ALL=(root) /usr/bin/systemctl restart * autorise en réalité le
redémarrage de n'importe quel service, y compris ceux dont dépend votre
sécurité. Un * dans un chemin de commande est presque toujours une
faille. Énumérez les commandes, même si la liste est longue.
Méfiez-vous des binaires qui savent lancer d'autres programmes.
Déléguer vim, less, find, awk ou tar avec les privilèges root
revient à déléguer root entier : tous permettent d'ouvrir un shell
depuis leur interface. Le projet
GTFOBins recense ces binaires et la
manière exacte dont un attaquant s'en sert pour s'échapper de la
restriction. Consultez-le avant d'ajouter un binaire à une règle : un
sudo tar innocent est un shell root déguisé.
Préférez sudoedit à sudo vim quand il s'agit de modifier un
fichier : l'édition se déroule alors avec vos privilèges sur une copie,
et seul le remplacement final est privilégié. Déléguez à des groupes
plutôt qu'à des personnes, pour que l'arrivée ou le départ d'un
collaborateur ne demande jamais de rouvrir sudoers. Enfin, relisez les
délégations périodiquement : une règle posée « pour dépanner » un mardi
soir survit des années.
Dépannage
Section intitulée « Dépannage »Les symptômes ci-dessous couvrent l'écrasante majorité des incidents sudoers. Le point commun de la plupart d'entre eux : la règle existe, mais sudo ne la lit pas ou ne la matche pas.
| Symptôme | Cause probable | Solution |
|---|---|---|
user is not in the sudoers file | L'utilisateur n'est dans aucune règle ni dans %sudo/%wheel | usermod -aG sudo <user> (Debian) ou wheel (RHEL), puis vérifier avec sudo -lU <user> |
Plus aucun sudo ne fonctionne après une édition | Erreur de syntaxe écrite sans visudo | Réparer depuis une console root ou pkexec visudo, puis valider avec visudo -c |
Un fichier de /etc/sudoers.d/ n'a aucun effet | Nom contenant un . ou finissant par ~, ou droits ≠ 0440 | Renommer sans point, chmod 0440, chown root:root |
sudoers.d/... bad permissions au login | Fichier non 0440 root:root | Le réécrire avec visudo -f /etc/sudoers.d/<fichier> (pose les bons droits) |
| La commande est refusée alors que la règle semble bonne | Chemin relatif ou différent du chemin réel du binaire | Comparer avec command -v <binaire>, écrire le chemin absolu |
Interactive authentication required | Commande systemctl lancée sous une identité cible autre que root | Cibler (root) dans la règle |
| Une règle restrictive est ignorée | Une règle plus permissive matche après (la dernière gagne) | Réordonner : placer le permissif avant le restrictif |
D'où vient sudo
Section intitulée « D'où vient sudo »Connaître l'origine de l'outil aide à comprendre pourquoi son fichier de configuration a cette allure si particulière : il est plus vieux que la plupart des distributions qui l'embarquent.
sudo est écrit vers 1980 par Bob Coggeshall et Cliff Spencer au
département d'informatique de SUNY/Buffalo, pour un VAX-11/750 sous
BSD. Le nom signifie « superuser do », littéralement « fais en tant que
superutilisateur » ; la lecture « substitute user do », souvent répétée,
est une rétro-étymologie postérieure. La première diffusion publique
date de 1985, et le projet est maintenu par Todd C. Miller depuis
1994, aujourd'hui sous licence ISC. Cette longévité explique la
compatibilité ascendante têtue du format sudoers, et donc la
cohabitation de directives modernes (@includedir) avec leurs vieux alias
(#includedir).
Mettre en pratique
Section intitulée « Mettre en pratique »Écrire une règle sudoers sur le papier ne suffit pas : il faut la voir refuser ce qui n'est pas délégué. Le lab vous fait rédiger un drop-in dans /etc/sudoers.d/, le valider avec visudo, puis prouver avec sudo -lU que l'utilisateur ne peut lancer que la commande prévue, et rien d'autre.
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »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
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
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
À retenir
Section intitulée « À retenir »- sudo délègue sans partager root : une identité nominative reçoit un sous-ensemble de commandes.
- Format d'une règle :
utilisateur hôte=(cible) commandes, avec des chemins absolus obligatoires. - Le premier champ est un utilisateur, un
%groupeou unUser_Alias: il n'existe pas de rôle dans sudoers. - Toujours
visudo: une erreur écrite directement dans sudoers verrouille tout sudo. - Drop-ins dans
/etc/sudoers.d/en0440 root:root; un nom avec un.ou finissant par~est ignoré silencieusement. - La dernière règle qui matche gagne : l'ordre compte, à l'inverse du réflexe « premier match ».
- Pour piloter un service, la cible est
(root): sous un autre compte, systemd renvoieInteractive authentication required. sudo -lne montre que vos droits ; l'audit passe parsudo -lU <user>et les journaux.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Durcir et journaliser sudo : La suite : use_pty, enregistrement de session, NOEXEC, sudoedit et les CVE majeures.
- Durcir l'authentification avec PAM : sudo s'appuie sur PAM : politiques de mot de passe et verrouillage de comptes.
- GTFOBins : Les binaires qui permettent de s'échapper d'une règle sudo trop généreuse.