Outils pour utilisateurs

Outils du site


expert:sudo_sans_mot_de_passe

Exécution sous root par sudo

(Edition initiale: Tyrtamos; mise à jour mars 2007)

Problème à résoudre

Comment un administrateur peut-il permettre à un utilisateur normal d'exécuter certains programmes système qui nécessitent un droit “root”, sans lui donner le mot de passe “root” ?

Références documentaires

Principe

Il s'agit de modifier le fichier /etc/sudoers (avec l'éditeur “visudo” sous root) en ajoutant une ligne qui définit les droits pour les utilisateurs.

Prenons un exemple:

jeanmarc  ALL = (root)  NOPASSWD:   /sbin/fdisk  -l,   /sbin/shutdown -h now

(le paramêtre de fdisk est un “L” minuscule)

Ce qui donne l'autorisation à l'utilisateur “jeanmarc” accédant à la machine à partir de n'importe où (“ALL” = localhost, réseau local, internet, …), d'exécuter le programme “/sbin/fdisk -l” ainsi que “/sbin/shutdown -h now” comme s'il était root, sans avoir besoin du mot de passe root.

Quand jeanmarc veut exécuter le 1er programme, par exemple, il tape dans une console (sous son login perso):

sudo /sbin/fdisk -l

A noter que sudo ne change pas votre environnement (PATH). Cela veut dire que certaines commandes que root peut déclencher sans préciser son chemin, vous obligeront, vous, à préciser son chemin.

La syntaxe de sudoers est très puissante, et permet de gérer les droits avec beaucoup de finesse: liste d'utilisateur et de groupes, limitation des origines d'accès, liste des programmes autorisés (y compris avec arguments et jokers=*), etc…

Ce fichier /etc/sudoers n'est éditable que par root et lisible que par le groupe de root, ce qui limite le problème de sécurité.

Attention: avec la suse 10.2, il est venu un nouveau programme yast pour modifier le fichier sudoers: je vous conseille de ne pas l'utiliser! il ne prend pas en compte tous les éléments de syntaxe (par exemple, il refuse les jokers dans les adresses ip ce qui empêche les restrictions au réseau local), il ne m'a pas été possible de créer un alias des “origines”, etc…: attendez qu'il soit au point! (ou ayez un cd-live sous la main pour corriger, au cas où…).

Comment modifier le fichier sudoers

Le fichier /etc/sudoers n'est modifiable que sous root.

Il est important de n'éditer /etc/sudoers qu'avec l'éditeur visudo (qui vient avec le package sudo) !!!

Ça marche comme vim, (qui n'est pas très ergonomique…) mais ça fait des choses en plus: verrouillage du fichier pendant l'édition et vérification de syntaxe. Et ce n'est pas du luxe…

Petit rappel du fonctionnement de visudo

Appel dans une console sous root:

visudo
  • touche [inser] pour passer en mod insertion
  • touche [echap] pour sortir du mode d'insertion
  • touche [:] pour passer en mode commande quand on est sorti du mode insertion
  • taper [x] en mode commande pour sortir de visudo avec enregistrement
  • taper [q!] en mode commande pour sortir de visudo sans enregistrement

et c'est tout ce qu'il y a d'important à savoir (en tout cas, je n'en utilise jamais plus).

Vérification de syntaxe

En dehors de visudo, on peut aussi faire vérifier la syntaxe avec:

sudo -v

qui ne renvoie rien quand c'est ok.

Syntaxe du fichier sudoers

la ligne de sudoers est en gros celle-ci (ce qui est entre crochets est optionnel):

utilisateur[, utilisateur2, ...]   origine[, origine2, ...] = [(à_la_place_de_qui)]  commande[, commande1, ...]

Signification: l'utilisateur “utilisateur”, accédant à l'ordinateur à partir de “origine”, a le droit d'exécuter “commande” comme s'il était “à_la_place_de_qui”

“utilisateur” peut être:

  • un nom d'utilisateur
  • un nom de groupe (précédé par %: par exemple %users, ou %sousadmin)
  • un alias défini précédemment par User_Alias
  • une liste d'utilisateurs, de groupes et d'alias séparés par des virgules

Alias d'utilisateurs créé comme suit:

User_Alias  nom_d'alias = utilisateur1, utilisateur2, ...

“origine” est l'origine de l'accès de l'utilisateur sur la machine, et peut être:

  • un nom de machine du réseau
  • une adresse IP de réseau (y compris avec joker: 192.168.0.* peut indiquer toutes les machines du réseau local)
  • localhost
  • un alias défini précédemment par Host-Alias
  • une liste
  • ALL pour indiquer n'importe quelle origine

Alias d'origines créé comme suit:

Host_Alias  nom_d'alias = origine1, origine2, ...

“(à_la_place_de_qui)” donne l'utilisateur pour le compte de qui le programme sera exécuté.

Si ce paramêtre n'est pas mentionné, c'est root par défaut.

Mais quand l'utilisateur est “root”, on met ici “(ALL)”, auquel cas root a le droit de lancer des commandes pour le compte de n'importe qui d'autre.

“commande” donne la liste des programmes à exécuter, séparés par des virgules s'il y en a plusieurs:

On peut créer un alias de programmes à exécuter:

Cmnd_Alias  nom_d'alias = progg1, prog2, ...

On peut utiliser un modificateur comme NOPASSWD: qui modifie (=dit de ne pas demander de mot de passe) tous les programmes qui suivent jusqu'à fin de ligne ou jusqu'à PASSWD: (qui dit le contraire).

Comment savoir ce à quoi on a droit?

Un utilisateur peut faire (sous son login):

sudo -l 

(l'option est un “L” minuscule), ce qui lui donne la liste des commandes pour lesquelles il a obtenu des droits supplémentaires grâce au fichier sudoers.

Cette commande demande le mot de passe de root, à moins qu'on ait modifié sudoers pour que ce soit le mot de passe de l'utilisateur (cf chapitre suivant).

Comment faire pour que sudo ne demande plus le mot de passe root

Faire que sudo demande le mot de passe utilisateur (au lieu du mot de passe root)

Sur la suse (ce n'est pas forcément le cas pour les autres distributions), l'utilisation de sudo pour lancer une commande à la place de “root”, déclenche la demande du mot de passe “root”.

Pour que ce soit désormais le mot de passe de l'utilisateur qui soit demandé, il faut, toujours avec visudo, mettre en commentaire (un “#” devant) les 2 lignes suivantes:

#Defaults targetpw    # ask for the password of the target user i.e. root
#ALL ALL=(ALL) ALL # WARNING! Only use this together with 'Defaults targetpw'!

Mais, bien sûr, ça ne vous permet de lancer une commande “root” avec votre mot de passe que si une ligne de sudoers vous en a donné les droits!

Attention: comme c'est précisé, ne jamais désactiver la 1ère ligne seulement sans la 2ème!!!

Faire comme dans Ubuntu: administrer avec sudo sans mot de passe root

En plus de la modification précédente, on crée un groupe (admin) à qui on attribue dans sudoers tous les pouvoirs de root à condition d'utiliser sudo et de donner son mot de passe utilisateur.

Il suffit d'ajouter dans sudoers la ligne:

%admin  ALL = (ALL) ALL

Et, bien sûr, il faut s'inscrire dans ce groupe admin, ainsi que les autres utilisateurs à qui on veut confier ce droit. Avec Ubuntu, l'utilisateur créé pendant l'installation est d'autorité placé dans ce groupe.

Une fois qu'une commande avec sudo a été exécutée, une autre commande avec sudo peut être exécutée juste après sans nouvelle demande de mot de passe. Ça marche pendant un certain délai qui est de 5minutes par défaut. Si on veut le changer, par exemple pour 15 minutes, il faut ajouter la ligne suivante après les autres lignes “defaults”:

Defaults passwd_timeout=15  

Une valeur de “0” oblige à introduire le mot de passe à chaque fois.

Faire que sudo ne demande plus aucun mot de passe!

Il suffit d'ajouter le modificateur “NOPASSWD:” avant les commandes sans mots de passe.

Ce modificateur est valable jusqu'à la fin de ligne, ou jusqu'à la rencontre du modificateur “PASSWD:” qui a l'effet contraire (=demande le mot de passe avec les commandes qui suivent).

Prenons un exemple:

tyrtamos localhost, nesti, 192.168.0.* = (root)  NOPASSWD:  reboot, halt

qui veut dire ceci: à condition que j'accède à la machine directement par son clavier, ou par le réseau local (par vnc par exemple), cette ligne me donne (à moi seulement) les droits de rebooter ou d'arrêter linux sans me demander le mot de passe root.

A ne surtout pas faire:

Sauf si on a décidé de lui donner les droits “root”, ne jamais donner à un utilisateur le droit d'aumenter ses droits!

Il est facile de comprendre que si, par exemple, un utilisateur a le droit de modifier /etc/sudoers, il peut facilement s'attribuer tous les droits root en ajoutant une seule ligne!

Mais cet exemple est simpliste, et il existe des cas où il vaut mieux réfléchir à ce qu'on est en train de faire. Par exemple, que donne à votre avis “sudo sudo /bin/sh”? Rien, heureusement parce que ça, c'est prévu…

Et quand on se trompe dans le mot de passe

Comment injurier les pirates

Il y a une instruction amusante à placer dans sudoers:

Defaults insults 

A partir de cette instruction, tout utilisateur qui se trompe dans le mot de passe demandé en réponse à sudo, se fait copieusement injurier!

Mais c'est en anglais, malheureusement: c'est vraiment dommage que ce ne soit pas traduit en français (on devrait même pouvoir en rajouter…)!

On a droit à combien d'essais infructueux?

On a droit à 3 erreurs par défaut avant que sudo ne vous abandonne à votre triste sort (les erreurs sont enregistrés dans le fichier log: voir ci-dessous).

Ce nombre est modifiable avec l'option “passwd_tries” à placer dans le fichier sudoers (voir page “man sudoers”).

Traçage des erreurs

Les erreurs de mot de passe sont enregistrés dans le fichier log:

/var/log/messages

Lancement d'une commande "root" sans sudo ni mot de passe!

Prenons un exemple:

Sur la suse, le répertoire /root n'est visible que par root. Je veux me donner (et à moi seulement) le droit de lister le répertoire /root comme si j'étais root, à condition que j'accède à partir de la machine elle-même ou à partir du réseau local.

J'ajoute au fichier /etc/sudoers (grâce à visudo) la ligne suivante:

tyrtamos localhost, nesti, 192.168.0.* = (root) NOPASSWD: /bin/ls -l /root

Je fabrique un script shell (fichier texte) que j'appelle “lsroot” et qui contient:

#!/bin/sh
sudo /bin/ls -l /root

et qui ne fait que de lister le contenu du répertoire root.

Je le place (sous root) dans /usr/bin, avec propriétaire:groupe ⇒ root:root et indicateur “fichier exécutable”.

Dans une console sous mon login normal, si je fais:

ls -l /root

il me dit que je n'ai pas les droits pour lister le contenu du répertoire root, ce qui est normal.

Mais si je fais maintenant:

lsroot

le listage du répertoire /root apparait, bien que je n'ai pas utilisé sudo, parce que c'est le script du fichier lsroot qui le fait.

On peut aussi faire exécuter le programme par un raccourci que l'on clique sur le bureau:

  • sur le bureau: clic à droite → créer un nouveau → lien vers une application
  • onglet application → commande = /usr/bin/lsroot
  • option avancées → “exécutez dans un terminal” et “ne pas fermer quand la commande se termine”
  • validez

Cliquez sur le raccourci placé sur le bureau: une console s'ouvre et liste le contenu du répertoire /root sans demander le mot de passe de root.

On peut aussi pour certains ordres automatiser le lancement du fichier exécutable, en le plaçant:

  • pour qu'il se lance à l'ouverture de votre session KDE (si vous utilisez KDE).
  • dans le processus d'initialisation de KDE ou de linux lui-même (/etc/init.d).
  • dans les tâches cron (déclenchement temporel)

On pourrait imaginer, par exemple, le montage automatique d'une partition personnelle à l'ouverture de session, et son démontage automatique à la clôture de cette session, et ceci sans mot de passe (alors que mount nécessite d'être root). Le script de montage sera dans:

  • /home/loginutilisateur/.kde/Autostart

Et le script de démontage sera dans (le répertoire shutdown est à créer, mais ce nom est prédéfini: ne le changez pas):

  • /home/loginutilisateur/.kde/shutdown

Conclusion

Dans ces exemples, on voit bien à quel point le fichier /etc/sudoers permet de définir les privilèges avec beaucoup de précisions.

Beaucoup plus en tout cas que de mettre le bit setuid sur la commande shell elle-même. En plus, le bit setuid ne marche pas sur les scripts shell mais seulement sur les commandes shell

Amusez-vous bien!

expert/sudo_sans_mot_de_passe.txt · Dernière modification: 2014/05/09 18:56 (modification externe)