sudo su –

À chaque fois que je vois cette commande, je m’énerve. Et d’autant plus quand c’est quelqu’un de compétent en unix. Méconnaissance ? Flemme de man sudo ? Un challenge pour la rubrique “Noob” 🙂

root or not root

Sous unix, root est l’utilisateur qui a tous les pouvoirs et, comme le dit oncle Ben (le tonton de Peter Parker/Spiderman), de grands pouvoirs appellent de grandes responsabilités. Mais root n’existe pas. root est un costume de super-héros que vous portez quand un grand devoir vous appelle et que vous devez quitter dès votre mission accomplie. Ainsi, si un méchant prend possession de vous, il n’a que des pouvoirs limités.

Il existe trois façons d’enfiler le costume de root : se logger root et les commandes su et sudo.

login as root

C’est la pire des idées bien sûr puisque vous allez être tenté(e) de tout faire en étant root. Les fichiers que vous allez créer (n’importe où puisque vous avez le droit d’en créer à peu près partout) appartiendront à root et ne seront vraisemblablement visibles que par root, ce qui est rarement ce que vous voulez. Et chacune des commandes que vous pourrez taper pourra potentiellement détruire tout votre système.

Ce qui n’est pas pratique, c’est que pour redevenir vous-même, vous devrez vous dé-logger et vous re-logger.

su

La façon la plus courante d’enfiler le costume : vous tapez su, vous saisissez le mot de passe de root et voilà, ça lance un nouveau shell (bash par exemple) qui a les super-pouvoirs (su signifie substitute user). En fait, normalement vous devriez taper su -c commande pour exécuter simplement une commande en tant que root et redevenir vous-même immédiatement après. Par exemple su -c "apt-get update". Par défaut (et c’est une erreur à mon avis), si vous ne précisez pas de commande avec -c, su lance votre shell.

Souvent, vous verrez la commande su - (notez le tiret). Il signifie que vous voulez un “login shell” c’est à dire un nouveau shell avec les variables d’environnement, le .bash_profile et autres scripts de login de l’utilisateur root. C’est ce qui simule un “login as root”.

Une précision, si vous êtes déjà root et que vous lancez une commande avec su, aucun mot de passe ne vous est demandé (c’est inutile et un gâchis de ressources mais c’est le principe de fonctionnement, vous allez voir l’effet de bord un peu plus bas).

Beaucoup d’inconvénients toutefois :

  • vous devez donner un mot de passe à root
  • la syntaxe (avec les guillemets qu’il faudra échapper une ou plusieurs fois selon le contexte) n’est pas pratique
  • si vous voulez prêter le costume à quelqu’un, vous devez lui donner le mot de passe de root
  • à chaque fois que vous changez le mot de passe de root, vous devez le redonner à tous ceux à qui vous l’avez prêté (par voir sécurisée bien sûr donc pas par mail, encore moins par le chat de facebook…)
  • à chaque fois que vous ne voulez plus que quelqu’un aie les super-pouvoirs, vous devez changer le mot de passe root et le re-communiquer à tous les autres
  • c’est tout ou rien : quand vous donnez le mot de passe root à quelqu’un, il peut tout faire en tant que root
  • si vous voulez qu’un script s’exécute en tant que root même si c’est vous qui le lancez, vous devez le définir comme setuid root (voir man chmod). C’est hyper dangereux (si quelqu’un modifie le script), impossible à maintenir, une vraie bombe à retardement.
  • il faut retaper le mot de passe de root à chaque utilisation

sudo

sudo (ou calife son ancêtre) est un petit bijou, son principe est le suivant : vous pouvez configurer qui a le droit de devenir root (on les appelle les sudoers). La personne tape une commande comme sudo apt-get update, tape son propre mot de passe et la commande est exécutée avec les droits root.

Premières conséquences immédiates :

  • Pas besoin de définir un mot de passe pour root (à part initialement pour définir un premier sudoer). C’est une faille de sécurité inutile.
  • Facile de donner ou reprendre les droits à quelqu’un
  • Pas besoin de communiquer le mot de passe
  • La syntaxe est très simple : la commande normale précédée de sudo (à part une petite exception)

Quelques notes :

  • Taper simplement sudo ne lance pas automatiquement un shell root.
  • Pour lancer un login shell, on tape simplement sudo -i.
  • Quand on utilise sudo, on acquiert une accréditation pendant 15 minutes (par défaut) qui n’oblige pas à re-taper son mot de passe. Chaque nouvelle commande sudo exécutée pendant ce délai prolonge de 15 minutes l’accréditation. Donc si on fait de la config de façon presque ininterrompue pendant 2 heures on ne tapera in fine qu’une fois son mot de passe. Pas une grosse contrainte donc.
  • su comme sudo permettent de prendre l’identité de n’importe quel utilisateur, pas forcément root : sudo -u toto commande exécute commande sous l’identité de l’utilisateur toto.

Les plus de sudo

Les sudoers

On définit les sudoers dans le fichier /etc/sudoers. Toutefois, sur les distributions récentes, il suffit de mettre quelqu’un dans le groupe sudo pour qu’il soit sudoer.

Des droits plus fins

sudo permet de configurer assez précisément qui a le droit de faire quoi. Par exemple, vous pouvez autoriser quelqu’un à exécuter uniquement sudo ls, toutes les autres commandes sudo échoueront. Vous pouvez également décider quelle(s) identité(s) un utilisateur pourra prendre. Vous pouvez enfin décider qu’un utilisateur pourra utiliser des commandes sudo sans taper de mot de passe.

Dit comme ça, ça semble idiot.

Imaginez maintenant que vous créez un utilisateur backup auquel vous donnez uniquement le droit d’exécuter pg_dump (la commande pour effectuer des dumps PostgreSQL) en tant qu’utilisateur postgres et sans taper de mot de passe. Vous avez alors un compte sans droit particulier qui peut effectuer des tâches de sauvegarde via une cron sans compromettre la sécurité si, par malheur, quelqu’un parvenait à se connecter avec son compte.

Un autre exemple fréquent est le fait de donner des droits limités à www-data (l’utilisateur qui exécute Apache sous Debian/Ubuntu) sans mot de passe.

sudo su –

Alors que fait cette commande ? Elle demande le mot de passe de l’utilisateur pour exécuter su qui lui-même va appeler un shell :

$ sudo su -
# ps --forest
  PID TTY          TIME CMD
14587 pts/14   00:00:00 sudo
14588 pts/14   00:00:00  \_ su
14596 pts/14   00:00:00      \_ zsh
14601 pts/14   00:00:00          \_ ps

sudo -i fait la même chose en évitant d’utiliser des ressources pour exécuter (inutilement) su :

$ sudo -i  
# ps --forest
  PID TTY          TIME CMD
14610 pts/14   00:00:00 sudo
14611 pts/14   00:00:00  \_ zsh
14616 pts/14   00:00:00      \_ ps

sudo et les redirections

Le seul cas où sudo semble ne pas fonctionner c’est avec les redirections, par exemple :

sudo echo "test" >/root/test

La raison est que la redirection est effectuée par le shell appelant (le shell courant, celui qui exécute sudo). Pour contourner le problème, il faut explicitement exécuter un shell root qui fera la redirection :

sudo sh -c 'echo "test" > /root/test'

Ici, c’est sh qui crée le fichier /root/test. Comme c’est un shell root, il a le droit.

Ça a l’air ennuyeux au premier abord mais, replacé dans le contexte de notre exemple d’utilisateur backup ça devient très intéressant :

sudo -u postgres pg_dump mabase > /home/backup/mabase.sql

Si c’était postgres qui exécutait la redirection, il n’aurait pas le droit d’écrire dans /home/backup.

C’est beau non ?

Postface

J’ai pu lire (sur diaspora notamment) quelques commentaires très constructifs du genre “j’ai entendu dire que sudo avait des failles de sécurité donc c’est nul”. Comme cela venait des rageux habituels, je ne me suis pas inquiété plus que ça mais je me suis quand même renseigné.

Alors oui, comme tout logiciel, il y a eu quelques failles détectées dans sudo (une quinzaine ces quinze dernières années). Le site du projet documente les failles en question, indique les corrections appliquées, bref, un suivi sérieux.

Mais je me suis surtout rendu compte que sudo a une toute autre envergure que su. On peut définir des policies (des règles) pour tout un parc de machines, des groupes d’utilisateurs, de commandes, ces policies peuvent être distribuées, interrogées via différents canaux (comme ldap). Par exemple, on peut définir un groupe d’utilisateurs “DBA”, un groupe de machines “DBServers”, un groupe de commandes comprenant “pg_dump”, “mysql_dump”, un groupe de “Run as” (d’identités de substitutions) et autoriser tous les DBA à utiliser ces commandes en tant que “postgres”, “mysql”, etc. sur tous les DBServers et cette gestion fine des droits peut être distribuée, répliquée, etc.

Si vous voulez vous faire une idée de l’étendue des possibilités, vous pouvez regarder cette mini conférence sur le sujet par l’auteur de “Mastering sudo” (seules les 30 premières minutes sont intéressantes, le reste est une série de questions autour de ssh qui vous paraîtront bien fades si vous avez lu un accès ssh sécurisé).

5 réflexions sur « sudo su – »

  1. Merci pour les précisions ! Et en plus, tu viens de résoudre un bug* qui me gonflait depuis 2-3 jours 🙂

    *par bug j’entends un “Meh. Pourquoi ça ne fonctionne pas ?!” avec sourcils hauts et grattage de tête.

  2. Cool ! Merci de ton retour (tu es un de mes seuls commentateurs, pour ne pas dire le seul, peut-être mon seul lecteur ?), ça fait toujours plaisir de savoir qu’on a pu être utile 🙂

  3. On dirait bien que SpF vient de te recruter de nouveaux lecteurs.
    Bien intéressant en tout cas.
    Mais du coup, je me dis que j’ai raison de ne pas m’embeter à créer de compte root dans ma Debian comme cela est devenu la norme dans Ubuntu.

    • Ouahou, 3 commentaires sur un même article, mais c’est Noël ! 🙂 Merci de vos retours, ça fait vraiment plaisir (et merci SpF).

      Oui, pour une fois, je trouve le choix d’Ubuntu de se reposer, par défaut, exclusivement sur sudo excellent car ça permet de faire “comme il faut” sans que ce soit une contrainte. Et puis si ssh prévoit une option spéciale PermitRootLogin et que rkhunter considère que quand c’est “oui” c’est dangereux, ça me conforte dans cette idée que le compte root avec lequel on peut se logger est une mauvaise idée, ou au moins une façon de faire obsolète.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *