Partager :
Surface d'attaque · sudo
sudo NOPASSWD ne marche pas : sudo redemande le mot de passe (Ubuntu 24.04, Debian 13)
Publié le · HardStacked · 7 min
Tu as écrit user ALL=(ALL) NOPASSWD: ALL, ça marchait avant, et maintenant sudo demande le mot de passe. Dans un conteneur ou un script, sans terminal, il affiche sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper, puis sudo: a password is required. La question traîne sur askubuntu depuis le 2024-07-31 (question 1522123, 10 930 vues quand on l'a lue le 2026-10-26, quatre réponses, aucune acceptée), et la personne qui la pose la résume en une phrase :
« This works in previous versions, (22.04, 20.04) but in Ubuntu 24.04 I'm getting this error » (« Ça marche dans les versions précédentes, (22.04, 20.04), mais sur Ubuntu 24.04 j'obtiens cette erreur »)
Ta règle est correcte, et sudo l'a lue. Une autre règle qui te concerne aussi est lue après elle, et sudo applique la dernière qui correspond, pas la plus précise. Pire, sudo -l affiche NOPASSWD: ALL pendant que sudo demande quand même le mot de passe. La ligne qui compte, c'est la dernière. Tout ce qui suit a été mesuré sur un Raspberry Pi sous Debian 13, paquet sudo 1.9.16p2-3+deb13u2, le 2026-10-26.
01. Un test qui ne peut pas te verrouiller dehors
On reproduit avec un utilisateur dédié demo (sans mot de passe) et un groupe dédié demoadm, et chaque fichier créé a demo dans son nom. Le piège n'utilise volontairement pas %sudo : sinon, selon l'ordre de tes règles, tu pourrais couper ton propre accès sudo pendant l'essai et ne plus pouvoir le défaire. Ici, seul demo est touché. Et comme demo n'a pas de mot de passe, si sudo lui en demande un il ne pourra jamais répondre : c'est la preuve. sudo -n veut dire non interactif : il échoue au lieu d'attendre.
$ sudo groupadd demoadm
$ sudo useradd -m -G demoadm demo
$ echo 'demo ALL=(ALL) NOPASSWD: ALL' | sudo tee /etc/sudoers.d/05-demo
demo ALL=(ALL) NOPASSWD: ALL
$ sudo chmod 0440 /etc/sudoers.d/05-demo
$ sudo -u demo sudo -n true && echo 'no password asked'
no password asked
Une règle, dans son propre fichier, et ça marche. Rien de surprenant encore.
02. sudo: a password is required
Ajoute maintenant une deuxième règle qui concerne demo par son groupe. Elle est dans un fichier nommé 10-demo-group, qui se trie après 05-demo :
deuxième règle, par groupe
$ echo '%demoadm ALL=(ALL:ALL) ALL' | sudo tee /etc/sudoers.d/10-demo-group
%demoadm ALL=(ALL:ALL) ALL
$ sudo chmod 0440 /etc/sudoers.d/10-demo-group
$ sudo -u demo sudo -n true && echo 'no password asked'
sudo: a password is required
La règle NOPASSWD est toujours là, intacte. Sans terminal, la même chose donne le message exact de la question :
sans terminal
$ sudo -u demo sudo true </dev/null
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required
Le man de sudoers (Debian 13) le dit sans détour : « When multiple entries match for a user, they are applied in order. Where there are multiple matches, the last match is used (which is not necessarily the most specific match). » Une règle de groupe sans NOPASSWD, lue en dernier, remplace ta règle d'utilisateur pourtant plus précise.
03. sudo -l liste les deux règles, et la dernière gagne
C'est la partie qui fait douter de ses yeux. Demande à sudo ce que demo peut lancer (le sed coupe les lignes propres à chaque machine, comme les Defaults ; tu verras le nom de ta machine là où on a debian) :
sudo -l
$ sudo -l -U demo | sed -n '/^User/,$p'
User demo may run the following commands on debian:
(ALL) NOPASSWD: ALL
(ALL : ALL) ALL
NOPASSWD: ALL est affiché, et sudo demande le mot de passe. La liste suit l'ordre de lecture des règles, donc la ligne qui s'applique est celle du bas. Sur une vraie machine, tu ne sais peut-être pas de quel fichier vient chaque règle. sudo -ll te le dit, une fois la sortie filtrée sur les lignes qui nomment le fichier :
sudo -ll : quel fichier
$ sudo -ll -U demo | grep 'Sudoers entry'
Sudoers entry: /etc/sudoers.d/05-demo
Sudoers entry: /etc/sudoers.d/10-demo-group
Sur Debian 13, /etc/sudoers se termine par @includedir /etc/sudoers.d, ce que décrit /etc/sudoers.d/README. Tout fichier de sudoers.d est donc lu après tout /etc/sudoers, y compris sa ligne %sudo ALL=(ALL:ALL) ALL. C'est pourquoi mettre ta ligne « après %sudo » dans /etc/sudoers ne suffit pas toujours. On a mesuré que sudo -ll nomme le fichier sur sudo 1.9.16p2 ; on ne sait pas à partir de quelle version.
04. Un nom de fichier avec un point n'est jamais lu
Deuxième piège, même page. Le man dit que sudo lit les fichiers de /etc/sudoers.d en ordre lexical trié, en « skipping file names that end in `~' or contain a `.' character ». Donc 99-demo.conf n'existe pas pour sudo. Renommons notre fichier NOPASSWD ainsi :
renommé en 99-demo.conf
$ sudo mv /etc/sudoers.d/05-demo /etc/sudoers.d/99-demo.conf
$ sudo visudo -c | grep demo
/etc/sudoers.d/10-demo-group: parsed OK
$ sudo -u demo sudo -n true && echo 'no password asked'
sudo: a password is required
visudo -c ne liste même pas le fichier, et répond quand même OK (code 0). Personne ne te dit qu'une règle a été ignorée. Le tri est aussi lexical, pas numérique : l'exemple du man lui-même, c'est que /etc/sudoers.d/1_whoops est chargé après /etc/sudoers.d/10_second.
05. Le correctif : un fichier qui se trie en dernier, sans point
Mets ta règle dans /etc/sudoers.d/, dans un fichier sans point dont le nom se trie après les autres, ici 99-demo, mode 0440. Puis vérifie deux choses : ton fichier doit apparaître dans la liste parsed OK, et ta ligne NOPASSWD doit être la dernière dans sudo -l.
le correctif : 99-demo
$ sudo mv /etc/sudoers.d/99-demo.conf /etc/sudoers.d/99-demo
$ sudo visudo -c | grep demo
/etc/sudoers.d/10-demo-group: parsed OK
/etc/sudoers.d/99-demo: parsed OK
$ sudo -u demo sudo -n true && echo 'no password asked'
no password asked
$ sudo -l -U demo | sed -n '/^User/,$p'
User demo may run the following commands on debian:
(ALL : ALL) ALL
(ALL) NOPASSWD: ALL
L'ordre s'est inversé dans la liste, et le mot de passe n'est plus demandé. Pour écrire ta propre règle, la forme standard est sudo visudo -f /etc/sudoers.d/99-tonnom, qui vérifie la syntaxe avant d'enregistrer. Notre banc a utilisé tee et chmod pour que chaque étape soit visible dans la capture, puis visudo -c.
06. Ce que disent les réponses, et un point de sécurité
La réponse la plus votée (score 8) cite la même phrase du manuel et dit de mettre ta ligne après %sudo. Vrai, mais incomplet : un fichier de sudoers.d qui te correspond est lu après tout /etc/sudoers et gagne quand même. Une autre réponse (score 4) rapporte un /etc/sudoers.d/10-installer sur la machine de son auteur, contenant %sudo ALL=(ALL:ALL) ALL, qui écrasait la règle. C'est exactement notre piège ; on n'a pas vu ce fichier nous-mêmes, alors vérifie le tien avec sudo -ll. Une troisième réponse (score 0), postée par la personne qui pose la question, change %sudo en NOPASSWD avec sed. Ça marche, et ça donne root sans mot de passe à tous les membres du groupe sudo. Préfère une règle par utilisateur et, si tu peux, seulement les commandes dont ton script a besoin. Par exemple NOPASSWD: /usr/bin/systemctl restart nginx (c'est la syntaxe, on ne l'a pas exécutée).
07. Le démontage, et ce qu'on n'a pas testé
Le démontage retire nos deux fichiers, l'utilisateur et le groupe. L'avertissement de userdel ne parle que d'une boîte courriel qui n'a jamais existé. La dernière commande prouve que demo est parti :
démontage
$ sudo rm /etc/sudoers.d/99-demo /etc/sudoers.d/10-demo-group
$ sudo userdel -r demo
userdel: demo mail spool (/var/mail/demo) not found
$ sudo groupdel demoadm
$ id demo
id: 'demo': no such user
Mesuré : un Raspberry Pi, Debian 13, sudo 1.9.16p2. Non mesuré : Ubuntu 24.04 lui-même (la règle est dans le man sudoers upstream, mais on n'a pas testé cette machine), et sudo-rs, le sudo par défaut d'Ubuntu 25.10 et plus. On a mesuré sudo-rs depuis : sur Ubuntu 26.04, une ligne sudoers avec un joker est jetée en entier.
Partager :