LinuxPedia

Wiki libre et indépendant dédié à GNU-Linux et BSD.

Outils pour utilisateurs

Outils du site


commande:su_sudo

— page corrigée — oh!rocks 2009/04/30 22:56

"su" et "sudo" pour obtenir des droits "root"

Les systèmes GNU-Linux utilisent une séparation des droits stricts entre le compte “administrateur” (“root”) et les comptes d'utilisateurs. Parfois pour effectuer une tâche sur des fichiers du système, ou pour simplement installer de nouveaux logiciels, vous aurez besoin d'obtenir les droits du super-utilisateur “root”.

<note>Un signe $ précède les commandes qui ne nécessitent pas des droits administrateur, un signe # celles qui nécessitent des droits administrateur. Les lignes qui ne commencent pas par un signe $ ou # correspondent au résultat de la commande précédente. Si le signe $ n'est pas suivi d'un espace il fait partie de la commande (exemple: $PATH est une variable ).</note>

su

Obtenir un shell d'un autre utilisateur

La commande “su” est la méthode traditionnelle pour obtenir les droits “root”, ou ceux de n'importe quel autre utilisateur du système. Un exemple rapide (la commande “whoami” permet de savoir sous quelle identité on est actuellement connecté):

$ whoami
tux
$ su gnu
Mot de passe :
$ whoami
gnu
$ whoami
tux
$ su root
Mot de passe :
whoami
root
# exit
$ whoami
tux

Rien de compliqué, on est connecté comme utilisateur “tux”, on passe la commande “su gnu” pour obtenir le statut de l'utilisateur “gnu”, et après avoir donné le mot de passe du compte “gnu” on devient effectivement “gnu”. Même chose avec le compte “root”, et on retourne à son identité précédente avec “exit”.

Tout cela est très bien, à un bémol près : si “su” permet de prendre l'identité de “root”, en revanche les variables d'environnement restent inchangées. Par exemple regardons ce qui se passe avec la variable “$PATH” qui détermine les chemins de référence dans lesquels le shell va chercher une commande, et la variable “$HOME” qui détermine le répertoire personnel:

$ whoami
tux
$ $PATH
bash: /usr/local/bin:/usr/bin:/bin:/usr/games:/usr/sbin:/opt
$ $HOME
bash: /home/tux
$ su
mot de passe :
# whoami
root
# $PATH
bash: /usr/local/bin:/usr/bin:/bin:/usr/games:/usr/sbin:/opt
# $HOME
bash: /home/tux

Les variables “$PATH” et “$HOME” sont les mêmes, d'ailleurs votre “prompt” (le texte en début de chaque ligne du shell) devrait toujours faire référence à votre nom d'utilisateur d'origine, seul le signe “$” aura été remplacé par “#” pour indiquer des droits “root”.
Pour obtenir également les variables d'environnement de l'utilisateur visé, il faut utiliser “su -l” (les options -, -l et --login sont équivalentes, - doit être indiqué après d'éventuelles autres options).

$ whoami
tux
$ $HOME
bash: /home/tux
$ su -l
mot de passe :
# whoami
root
# $HOME
-su: /root

<note>Certaines distributions utilisent également des variables “ENV_PATH” et “ENV_SUPATH” dans le fichier /etc/login.defs (Debian…) pour déterminer le “PATH” obtenu par “su”.</note>

Exécuter une commande avec "su -c"

Il est possible d'utiliser “su” pour temporairement exécuter une commande avec des droits “root”:

$ su -c "fdisk -l"

Si la commande exécutée comporte des options il faut la “protéger” par des doubles ( ) ou simples ( ' ) guillemets. Cet exemple exécutera “fdisk -l” (lister les partitions présentes sur le système) avec des droits root.

sudo, /etc/sudoers

La commande “sudo” est un outil très utile, particulièrement en environnement multi-utilisateurs. Sur certaines distributions comme Ubuntu elle a même complètement remplacé “su” et la nécessité d'un compte “root”.

<note warning> sudo est flexible et entièrement configurable, mais c'est un point critique de votre système. Vous DEVEZ utiliser “visudo” pour éditer le fichier de configuration /etc/sudoers, et être sûr de vous avant de placer des règles farfelues. Si vous êtes sur Ubuntu et que vos manipulations vous interdisent d'exécuter la commande “sudo”, vous êtes mal partis…</note>

<note>Certaines modifications ne prendront pas effet sur le shell en cours, vous devrez en ouvrir un nouveau pour les tester.</note>

Configuration minimale de "sudo"

Si vous avez choisi cette option lors de l'installation (Ubuntu, Debian, OpenSuse…) vous n'avez probablement rien à faire de particulier pour pouvoir utiliser “sudo” de manière basique (pour exécuter une commande avec des droits “root”).

Le comportement de la commande “sudo” se règle dans le fichier /etc/sudoers, ce fichier texte ne doit pas être édité directement, mais en passant par la commande spécifique “visudo”.
“visudo” va lancer un éditeur de texte parmi une liste définie lors de la compilation du programme “visudo”, par défaut il s'agit souvent de “vi”. L'édition s'effectue de manière à rendre impossible les éditions concurrentielles (évitant ainsi que plusieurs programmes modifient /etc/sudoers en même temps), la syntaxe est vérifiée avant enregistrement… Toutes ces précautions ne sont pas superflues : vu la nature de “sudo”, une erreur peut rendre votre système quasiment inutilisable si “sudo” est le seul moyen d'administration. Pire, une erreur peut créer une faille de sécurité béante autorisant un utilisateur (voir tous) à effectuer n'importe quelle commande en “root”, y compris à distance…

Il est possible d'utiliser un autre éditeur de texte que “vi” avec “visudo”, pour cela il faut modifier la variable $VISUAL avant de lancer “visudo” avec la commande :

# export VISUAL=nano

Dans ce cas vous indiquez que c'est l'éditeur “nano” qui doit être utilisé lors de l'exécution de “visudo”.

Un autre moyen de définir l'éditeur utilisé par “visudo” est d'ajouter au fichier /etc/sudoers:

Defaults editor = /usr/bin/nano:/usr/bin/vi

Dans ce cas “nano” sera utilisé préférentiellement, s'il est absent se sera “vi”.
Cette variable affecte également l'éditeur utilisé par la commande “sudoedit”, qui sert à éditer des fichiers qui nécessitent des droits root.

<note>Sur certaines distributions le choix de l'éditeur utilisé par “visudo” est fixé à la compilation, et pour qu'aucun autre ne puisse être utilisé les variables destinées à changer ce paramètre sont désactivées. Cela vise à limiter le risque qu'un attaquant utilise cette possibilité pour faire exécuter un programme arbitraire à “visudo”.</note>

La configuration minimale pour utiliser “sudo” sera :

Defaults targetpw  # demande le mot de passe de l'utilisateur cible
ALL ALL = (ALL) ALL  # ATTENTION! À n'utiliser QUE avec 'Defaults targetpw'!

Ces lignes sont en général déjà présentes et commentées lorsque “sudo” n'est pas configuré. Dans ce cas on définit une variable globale (“targetpw”) obligeant à fournir le mot de passe de l'utilisateur cible, au lieu du mot de passe de l'utilisateur qui exécute la commande “sudo”. Par exemple si vous êtes “tux” et exécutez “sudo reboot” c'est le mot de passe de “root” et non celui de “tux” qui sera demandé.

La seconde ligne obéit à la syntaxe:

utilisateur origine = (identité cible) commande

et indique que tous les utilisateurs (premier “ALL”), depuis n'importe où (connexion locale ou distante, second “ALL”), sont autorisés à prendre n'importe quelle identité (troisième ”=(ALL)“ et à exécuter n'importe quelle commande (quatrième “ALL”). Ce réglage est évidemment très permissif, et n'est destiné qu'à être temporaire et permettre la mise en place d'un système, après quoi une configuration digne de ce nom devra être réalisée.

:!: On comprend également que la deuxième ligne ne doit PAS être utilisée sans la première, car sans la variable “targetpw” c'est le mot de passe du compte utilisateur qui lance “sudo” qui permettra à n'importe qui d'exécuter n'importe quoi depuis n'importe où, même à distance via ssh…

Configuration avancée

On peut dissocier trois situations différentes:

Poste personnel, un seul utilisateur, pas de compte root

C'est la configuration type d'un portable sous Ubuntu par exemple. Dans ce cas il n'y a guère le choix, le mot de passe de l'utilisateur sera également celui de “sudo” (il devra donc théoriquement être aussi complexe qu'un mot de passe root traditionnel…). Dans ce contexte la configuration de base ne contiendra que peu de choses :

root ALL = (ALL) ALL
%admin ALL = (ALL) ALL

Cela autorise l'utilisateur ayant des droits root à exécuter un shell depuis n'importe où (local ou distant), sous n'importe quelle identité, n'importe quelle commande. La seconde ligne autorise tout membre du groupe “admin” à utiliser sudo pour prendre les droits root.

Dans cette configuration on est assez libre de créer des règles personnalisées, même très permissives, pour se faciliter la vie.

Permettre d'éteindre/redémarrer sans aucun mot de passe:

%users localhost = NOPASSWD: /sbin/reboot, /sbin/shutdown -h now

Dans cette configuration tous les utilisateurs qui disposent d”un compte sur la machine (“%users”) peuvent, depuis l'ordinateur (localhost), et sans mot de passe (NOPASSWD:), exécuter les commandes “reboot” et “shutdown -h now”. À noter que les commandes sont séparées par une virgule, et la directive “NOPASSWD:” est valable jusqu'à la fin de la ligne, ou la présence d'une directive contraire (“PASSWD:”). Remarquez également que l'on a pas indiqué l'identité cible, c'est “root” qui sera utilisé par défaut.

Un second exemple, mais cette fois on restreint à une commande + cible le droit d'utilisation sans mot de passe :

#Autorise "tux" à monter et démonter /dev/sdc1 sur /media/backup, sans mot de passe.
tux	ALL = NOPASSWD: /bin/mount /dev/sdc1 /media/backup, /bin/umount /media/backup

Dans ce cas “tux” ne pourra utiliser que l'exacte ligne de commande spécifiée ; il ne pourra pas monter “/dev/sdc3” ou utiliser “umount /media/backup/” avec un slash à la fin du chemin s'il n'est pas spécifié dans /etc/sudoers. On peut donc être extrêmement précis, et au besoin utiliser des “jokers” (“wildcards” en Anglais) comme “/dev/sdc?” pour toutes les partitions de sdc. On peut également nier une condition en la précédant d'un signe “!”. Par contre le joker “*” ne fonctionne pas pour les chemins dans /etc/sudoers.

Pour voir à quoi vous êtes autorisé, utilisez :

$ sudo -l

(l'option est un “L” minuscule)

Les alias

Cette syntaxe est pratique, mais il est possible de faire mieux avec des alias. Ici nous allons créer un alias de commande, le nom de l'alias sera “PAQUETS” (nom arbitraire, à vous de le choisir), et une série de commandes associées à cet alias. Ensuite nous autorisons l'utilisateur “tux” à exécuter ces commandes (depuis un shell local, sous l'identité “root”) sans mot de passe :

#définir un alias de commandes nommé "PAQUETS"
Cmnd_Alias      PAQUETS = /usr/bin/aptitude, /usr/bin/apt-get

#Autoriser "tux" à exécuter ces commandes sans mot de passe
tux	localhost=(root) NOPASSWD: PAQUETS

Nous réutilisons le nom d'alias plutôt qu'une liste de commande, ce qui rend bien plus rapide l'écriture de nouvelles règles.

Voici une liste des alias valides pour /etc/sudoers:

Alias Signification
Cmnd_Alias liste de commandes
User_Alias liste d'utilisateurs disposant d'un compte sur la machine
Runas_Alias liste d'identités cibles
Host_Alias liste d'origine possible des commandes (noms d'hosts, plage d'adresses ip, localhost)

:!: Il ne faut jamais définir un nom d'alias “ALL”, ce nom a une valeur spéciale pour sudo. Un nom d'alias doit commencer par une majuscule. Il faut échapper d'un anti-slash (\) les caractères spéciaux comme: @, !, =, :, ,, (, ), \, à l'intérieur d'un nom.

Options globales ("Defaults")

On peut définir des options globales pour “sudo” en utilisant la directive “Defaults”. De cette manière on peut induire un comportement global de “sudo”, sauf si ce comportement est explicitement nié pour une ligne particulière. Quelques exemples :

#Définir des options globales par défaut

Defaults always_set_home
Defaults editor = /usr/bin/nano:/usr/bin/vi
Defaults:tux       !authenticate
Defaults	mail_badpass
Defaults insults
Defaults timestamp_timeout = 0
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  • always_set_home fait que “sudo” transfère la variable $HOME de l'utilisateur cible (/root pour “root” par exemple).
  • editor permet de donner une liste des éditeurs de texte utilisés par “visudo”, dans l'ordre de préférence.
  • authenticate implique la nécessité de fournir un mot de passe pour utiliser “sudo”. Cette condition est vrai par défaut, on peut la nier pour un utilisateur ou une origine (localhost…) par exemple en la précédent de “!” comme c'est le cas ici. “tux” n'aura donc pas besoin de donner un mot de passe pour utiliser “sudo”.
  • mail_badpass envoie un message au compte configuré dans /etc/sudoers (defaut “root”) lorsqu'une tentative d'identification échoue.
  • insults avec ce paramètre “sudo” vous insultera en cas de mauvais mot de passe, au lieu de vous indiquer poliment que vous vous êtes trompés… Certaines insultes sont assez drôles ;) .
  • timestamp_timeout permet de régler la durée pendant laquelle “sudo” conserve en mémoire l'identification pour un utilisateur. La durée est indiquée en minutes, le réglage par défaut est souvent de 5mn. Mettre la valeur “0” (zéro) rend nécessaire de taper le mot de passe à chaque fois (sauf si “NOPASSWD:” est présent dans /etc/sudoers bien sûr). Ça peut être intéressant si “sudo” demande le mot de passe de l'utilisateur cible (“targetpw” ou “rootpw”), car si votre compte est compromis, et que vous invoquiez “sudo”, un “pirate” connecté en ssh sur votre compte pourra invoquer “sudo” à nouveau et obtenir les droits “root” sans connaître le mot de passe. En dehors de cette considération de sécurité une durée plus longue peut être plus confortable.

Une valeur négative fait que l'identification n'expire jamais (pour la même identité cible si “targetpwd” est utilisé).

  • Defaults secure_path permet d'assainir la variable $PATH pour l'utilisateur invoquant sudo.

Une petite sélection d'options possibles :

  • pwfeedback permet d'avoir un retour visuel lorsqu'on tape le mot de passe, très utile pour ne pas dérouter les débutants en ligne de commande, ou en GNU-Linux en général. Peut permettre à un observateur de voir combien de caractères contient le mot de passe (mais s'il est assez près pour ça, autant qu'il regarde vos doigts sur le clavier…).
  • rootpw permet de définir le mot de passe demandé comme étant celui de “root”, quelque soit l'identité cible.
  • shell_noargs permet à la commande “sudo” d'avoir le même comportement que “sudo -s”, soit ouvrir un shell “root”.
  • targetpw avec cette option “sudo” demande le mot de passe de l'utilisateur cible (“root” ou tout utilisateur visé par l'option -u), et non celui de l'utilisateur qui exécute la commande.
  • passwd_tries définit le nombre de tentatives pour taper le mot de passe, après quoi “sudo” quitte et enregistre l'échec dans son fichier log. Le défaut est de 3.
  • passwd_timeout définit la durée pendant laquelle “sudo” attend le mot de passe avant de quitter. Le défaut est de 5 minutes. Une valeur de 0 (zéro) fait que l'invite de mot de passe n'expire jamais.
  • badpass_message permet de personnaliser le message en cas d'erreur de mot de passe. Si vous préférez “va te faire un café et revient” aux réponses plus colorées du mode insults ;-) .
  • log_output , avec cette option tout ce qui est envoyé en sortie des commandes passées avec sudo sera enregistré dans un fichier journal (/var/log/sudo-io par défaut, ou un chemin indiqué avec l'option “iolog_dir”). Attention à cette option et plus encore à log_input, cette dernière enregistrera toutes les commandes passées via sudo, <color red>ces commandes (ou leurs sorties) peuvent contenir des données sensibles qui se retrouveront enregistrées en clair dans le fichier journal !</color> Gare aux permissions et à l'emplacement du fichier journal.

Pour connaître la liste complète des options globales supportées par votre version de “sudo”, utilisez :

$ sudo -L

Cette option n'est pas honorée par toutes les versions de sudo.

Un seul utilisateur, compte root actif

Ce cas est idem au précédent, si ce n'est que la directive “rootpw” ou “targetpw” permettra de demander le mot de passe “root”, et non celui de l'utilisateur (en général plus faible et facile à casser).
Avant d'écrire des règles pour “sudo” dans tous les sens, pensez aussi aux autres solutions, comme les groupes (“adm” ou “admin”, “lpadmin”…) qui permettent d'exécuter des tâches d'administration sans avoir besoin des droits “root”.

Système multi-utilisateurs

C'est là que “sudo” prend tout son sens, il va permettre de déléguer des droits précis et spécifiques aux utilisateurs, pour exécuter des tâches nécessitant des droits “root”, sans pour autant devoir leur communiquer le mot de passe “root” (s'il existe) ou celui de l'administrateur.

Dans ce contexte les “alias” seront très pratiques, ils permettront de définir des groupes de commandes qui seront rapidement réutilisables dans les règles, de définir des groupes d'utilisateurs par domaine d'activité (“Staff”, “Compta”, “IT”…), et l'origine des commandes par nom d'hôte des machines, réseau ou sous-réseau ip. Voyons quelques exemples d'alias :

#Alias
# À utiliser à la place du champ "utilisateur"
User_Alias     IT = tux, gnu, moss   #les noms d'utilisateurs des IT
User_Alias     Graphistes = monet, picasso, warhol  #les noms d'utilisateurs des graphistes
User_Alias     BOSS = chef, souschef, petitchef   #les noms d'utilisateurs des responsables

# À utiliser à la place du champ "origine"
Host_Alias  BOSSNET = 192.168.1.2, 192.168.1.3,192.168.1.4  #liste d'adresses ip des machines de responsables
Host_Alias  STAFFNET = localhost, 192.168.0.0/24   #adresses ip des machines des employés (ip/netmask)
Host_Alias  SERVER = tagada, tsointsoin   #noms d'hôtes (renvoyés par "hostname") des machines serveurs.\\
#Noms "fqdn" utilisables, résolution DNS nécessaire).
# À utiliser dans le champ "commande"
Cmnd_Alias     SAUVEGARDE = /usr/bin/rsync, /usr/sbin/partimage
Cmnd_Alias     EXTINCTION = /sbin/shutdown -h
Cmnd_Alias     REBOOT = /sbin/reboot, /sbin/shutdown -r
Cmnd_Alias     CDROM = /bin/mount /dev/cdrom, /bin/umount /dev/cdrom, /usr/bin/eject

Voilà pour quelques exemples de groupement grâce aux alias. Il est à noter que certaines versions de “sudo” demandent des noms d'hôtes qualifiés dans /etc/sudoers, c'est-à-dire le résultat de “hostname –fqdn” qui sera de la forme “tagada@bizness.com”.
Un exemple de réutilisation de ces alias dans des règles:

IT   BOSSNET, STAFFNET, SERVER = (root) NOPASSWD: SAUVEGARDE, REBOOT, EXTINCTION

Graphistes, BOSS    localhost = NOPASSWD: CDROM

Attention à ne pas vouloir en faire trop avec “sudo”, il ne faut pas oublier les groupes, les droits standards Unix, les permissions spéciales (setgid, setuid, sticky bit) et les “acl” qui sont des outils permettant de contrôler les actions des utilisateurs. Des règles trop complexes avec “sudo” peuvent avoir des effets non anticipés, permettre des escalades de droits, provoquer des erreurs chez des utilisateurs aux connaissances techniques limitées.

"sudo" et la sécurité

“sudo” a le potentiel d'être une passerelle vers des brèches de sécurité. Par exemple donner le droit aux utilisateurs d'utiliser “mount” peut entraîner des pertes de données ; les mots de passe des utilisateurs, si on les utilise pour exécuter “sudo”, sont en général plus faibles que celui que choisirait un administrateur pour un compte “root” et peuvent être “crackés”. Un utilisateur qui peut exécuter “visudo” peut se donner n'importe quels droits par la suite ; si les journaux de “sudo” font références uniquement à l'utilisateur cible, il sera possible d'usurper une identité pour exécuter des commandes néfastes…

“sudo” possède des mécanismes de protection contre les enchaînements de commandes pour provoquer des escalades de droits, les exports de variables d'environnement d'un compte d'utilisateur vers le compte root, les usurpations d'identité. Elle sont la plupart du temps disproportionnées pour une utilisation personnelle ou familiale, mais dès que l'on entre dans un cadre associatif ou d'entreprise il faut absolument étudier de près les implications des règles que l'on crée.

Par exemple utiliser l'opérateur de négation “!” pour empêcher un utilisateur d'exécuter une commande est une mauvaise méthode… exemple :

tux	localhost = ALL, !mount, !umount

Cela vise à autoriser “tux” à exécuter n'importe quelle commande depuis “localhost”, sauf “mount” et “unmount”. C'est complètement inefficace, “tux” pourra exécuter “sudo -s” pour ouvrir un shell “root” et exécuter n'importe quelle commande, ou copier et renommer /bin/mount en /home/tux/montage et exécuter “sudo montage”, ou encore utiliser “sudo -u” pour prendre l'identité d'un autre utilisateur…

“sudo” permet d'utiliser l'option NOEXEC: qui évite qu'un programme puisse être chaîné pour en appeler un autre. C'est relativement efficace sauf avec les programmes binaires qui n'utilisent pas de librairies partagées. Malheureusement le nombre de programmes qui permettent ce genre de comportement d'échappement est important, il sera facile d'en oublier un.

La règle de base sera donc de ne conférer un droit d'exécution par “sudo” qu'au strict minimum nécessaire, et d'utiliser “NOEXEC:” en conjonction.

Pour connaître l'ensemble des réglages par défaut de votre version de “sudo”, comme la disponibilité de “NOEXEC:” (cherchez “dummy exec functions”), les variables d'environnement qui ne sont pas conservées par “sudo”, la variable “PATH” de substitution lors de l'emploi de “sudo -u utilisateur”, …etc, utilisez :

# sudo -V

(en root, ou alors avec “sudo sudo -V” ;-) )

Comme avec toute commande, commencer par “man sudo” est une bonne idée : vous aurez en plus accès à la liste des options utilisables sur la ligne de commande.

commande/su_sudo.txt · Dernière modification: 2018/11/17 12:52 (modification externe)