Les 3 S de l’administrateur UNIX, saison 2

le 26/04/2010 par Gabriel Guillon
Tags: Software Engineering

Nous avons vu dans l'article précédent deux outils bien pratique : ssh et sudo. L'un permet de chiffrer une connexion à une machine, le second permet d'exécuter une commande sous le nom d'un autre utilisateur.

Nous avons laissé Bob dans un état détresse insoutenable : un coup de pelleteuse a coupé ses précieuses connexions au serveur distant, lui faisant perdre 1h de compilation, sa vérification des mauvais secteurs sur un disque de 1Tio, son environnement calé aux petits oignons et sans doutes un miroir. Bob aurait pu éviter tout cela s'il avait connu le 3ème S de l'administrateur Unix.

Extrêmement utile et pourtant si peu connu, screen permet de multiplexer plusieurs de sessions shell dans un seul terminal.

S02E01 : Screen

"Aha", me faites-vous, "mais moi je lance plusieurs onglets dans mon gnome-terminal et j'ai la même chose".

gnome-terminalGnome-terminal (sous icewm). Remarquez que l'onglet de gauche porte le nom du serveur local, tandis que celui de droite celui du serveur distant

Bien entendu, ce serait trop simple.

Revenons à Bob. Après ce coup de pelleteuse en plein cœur, Bob, rentre chez lui et réfléchit à un moyen de ne plus perdre heures de compilations et environnements. Il passe un coup de fil à un collègue, qui, parce qu'il n'a pas que ça à faire, lui répond sèchement "man screen".

Une fois chez lui, Bob saute sur son ordi et tape "man screen". D'abord perplexe, Bob lit l'immeeeennnnse man page de screen, fait quelques essais et s'exclame "Ah OUAIS, quand même !". Il se connecte ni une ni deux depuis chez lui à son poste de travail, de là se connecte au serveur distant malade, lance sa compilation, la reconstruction des miroirs et le badblocks (retrouver les commandes avec les bons paramètres : 3 minutes), refabrique son environnement de test (retrouver les valeurs à mettre dans les variables : 15 minutes) et... Tue violemment son gnome-terminal, éteint sa machine et va se coucher (le sommeil, ça n'a pas de prix).

Quelle mouche a donc piqué Bob ? Pourquoi a-t-il éteint sa machine alors que les tâches distantes n'étaient pas terminées ? Aurait-il perdu l'esprit au bénéfice, certes, de son sommeil, mais tout de même ?

Un screen sur une machine (jhary), duquel part deux connexions à deux serveurs (rhynn et corum)

Screen, donc, est un multiplexeur de sessions : vous vous connectez à une machine distante, vous tapez screen, et vous avez une nouvelle session. De cette session vous pouvez en créer d'autres (Ctrl+a c), beaucoup d'autres, et ce sans avoir à vous connecter à nouveau à la machine. Vous pouvez passer rapidement de l'une à l'autre (Ctrl+a <espace>), les renommer (Ctrl+a A), remonter dans l'historique (Ctrl+a <escape>), et bien sûr y lancer des commandes.

Jusqu'ici, rien de mieux que gnome-terminal.

Il se trouve que si la connexion au serveur distant vient à être coupée, le screen distant, lui, vit toujours. Et vous pouvez vous (re)connecter plus tard à la machine, éventuellement d'un autre poste, et reprendre votre screen (screen -r). Vous êtes ainsi à l'abri d'une coupure réseau (mais pas d'une extinction de serveur : si ce dernier est éteint, votre screen meurt). Étant à l'abri lui aussi, et sachant qu'il pourrait regarder le résultat le lendemain, Bob a pu aller se coucher sans avoir à attendre la fin de la compilation.

Un petit dessin permet de vite appréhender le concept.

Connexions classique à un serveur distant. Une connexion => un shell

Connexion à un serveur distant avec screen . Une connexion => plusieurs shell

Voici un arbre de processus pour essayer de comprendre ce qui se passe :

root   ?        Ss   Feb28   0:00 /usr/sbin/sshd root   ?        Ss   09:50   0:00  _ sshd: arno [priv] arno   ?        S    09:50   0:00      _ sshd: arno@pts/1 arno   pts/1    Ss   09:50   0:00          _ -bash arno   pts/1    S+   09:51   0:00              _ screen root   ?        Ss   09:51   0:00                  _ SCREEN arno   pts/2    Ss   09:51   0:00                      _ bash root   pts/2    S+   09:51   0:00                      |   _ tail -F /var/log/everything.log arno   pts/4    Ss   09:51   0:00                      _ bash root   pts/4    S+   09:51   0:00                      |   _ vim /etc/ssh/sshd_config arno   pts/5    Ss   09:51   0:00                      _ bash arno   pts/5    R+   09:51   0:00                          _ ps afxu

La session SSH est dans le tty pts/1 et lance la partie client (screen en minuscules). Si la connexion ssh est coupée, c'est ce client qui va finir prématurément sa vie, mais la partie pur multiplexage (SCREEN en majuscules) n'est rattaché à aucun tty (fonctionne en mode démon) et va donc résister aux pannes réseau. C'est donc ce SCREEN qui va lancer d'autres commandes et shell (bash dans le cas présent, avec des tty différents) dans lesquelles on va alors pouvoir jongler avec sudo au besoin. Dans cet exemple, le tail -f et le vim sont lancés avec les droits de root, alors que le ps utilise un compte standard.

S02E02 : screen, encore

Le lendemain, fier, Bob se reconnecte à son serveur, reprend son screen et appelle un collègue.

Il lui fait part de sa découverte de la nuit. Son collègue est ébahit et teste screen sur le même serveur que Bob.

Vous pouvez avoir autant de screen en mémoire que le permet cette dernière, vous pouvez nommer les screen afin de ne pas prendre celui d'un collègue (screen -S <nom>, screen -rS <nom>), vous pouvez les imbriquer (d'un serveur vous connecter à un autre et y lancer screen, dans lequel vous pourrez lancer des commandes) (Ctrl+a a <commande pour le screen imbriqué>).

Après avoir mitonné un élégant .screenrc (fichier de configuration de screen propre à un utilisateur), Bob décide d'assener le coup fatal à son collègue : il lui dicte une commande à taper (screen -r bob/27518), et Bob et son collègue se retrouvent dans le même screen. Un screen, deux claviers, des milliers de possibilités. Tout ce que tape l'un, l'autre le voit et peux le corriger. Il y a évidemment possibilité de se marcher sur les doigts (l'un tape un caractère, l'autre tape <del>) mais surtout de montrer à l'autre ce que vous êtes en train de faire sans avoir à l'expliquer au téléphone, et ce même si vous êtes à 800km l'un de l'autre...

Raffinement suprême : vous pouvez ainsi taper un mot de passe pour votre collègue sans que celui-ci ne le voit ...

Ce qu'a fait Bob est activer le mode multi-utilisateur de screen ('multiuser on', dans son .screenrc) et autoriser son collègue à utiliser le même screen que lui (Ctrl+a : acladd <collègue>).

Fort de ces commandes, Bob décide de faire de la télégestion : il a un script (qu'il lance dans un screen pendant qu'il regarde les logs dans un autre) qui se connecte à ses serveurs pour y faire certaines choses (via sudo, notamment). Le problème est que son script doit se connecter 3 fois à chaque serveur. Bob, fainéant puisque Perliste, ne voit pas pourquoi il devrait le taper 3 fois son mot de passe alors qu'il se connecte à la même machine ; il voudrait ne le taper qu'une seule fois, voire pas du tout, mais sans toutefois laisser une clé ou un mot de passe en clair quelque part.

Nous verrons dans le dernier article comment aider Bob et lui indiquerons en prime comment faire passer tous les animaux de la savane par un trou de souris.

Conclusion

Screen est un multiplexeur de terminal. Il vous permet, avec un seul shell, d'avoir plusieurs sessions. 'screen' est la première commande que je tape en arrivant sur n'importe quel serveur Unix. Malheureusement elle est trop rarement installée, ce qui est extrêmement dommage vu l'utilité qu'elle a et le temps qu'elle fait gagner (ou plutôt : évite de faire perdre).

Quizzz

Plutôt qu'un bête bash (ou ksh) sauriez-vous faire en sorte que le nom du shell dans votre screen soit le nom du serveur auquel vous vous connectez ? (oui, comme gnome-terminal)

En ce qui concerne la quizzz du billet précédent :

Bravo à mangouste06 ! En effet vim est un outil qui a la fâcheuse fonction de pouvoir lancer des commandes externes (et donc par exemple un shell) avec la commande "!". Une fois un vim démarré, il suffit de taper "!bash". Une première étape consiste à utiliser rvim plutôt que vim qui interdit l'exécution de commandes externes. Malheureusement, il n'empêchera pas l'ouverture d'un autre fichier, comme un script lancé au redémarrage, ce qui laisse une grande place à l'imagination. Pour ce genre de contrôle d'accès, préférer une gestion serrée des droits sur le système de fichiers, à base de groupes par exemple, ou des solutions à base de SELinux/grsecurity.

C'est pour cette raison qu'en paramétrant sudo il vaut mieux tout interdire et n'autoriser que certaines commandes plutôt que tout autoriser et interdire les commandes dangereuses.

Un tips pour la route, en ce qui concerne sudo : avoir un shell sous le nom d'un utilisateur qui n'est pas censé pouvoir en avoir (nobody, pour l'exemple) : sudo -u nobody bash.

Et pour finir cet article, un exemple de .screenrc (celui d'Arnaud, un des auteurs de l'article) :

shell bash caption always "%{=b}%?%F%:%45=%n*%f %t%?%?%F%{r}%:%{s kk}%?%H%?%F%{-}%? %L=%-Lw%45L>%?%F%{g}%?%n*%f %t%?%F%{-}%?%+Lw%-17= %?%F%{y}%Y-%m-%d %c" defscrollback 2000 scrollback 2000

Ce qu'il donne dans la vraie vie :

Voici l'exemple d'une sesssion screen. On se retrouve dans un terminal classique. Seule la barre d'information en bas trahit de la présence de screen. Les onglets (ici au nombre de trois) ont été configurés pour avoir des titres explicites, l'onglet actif est en vert. en rouge à gauche, la machine sur laquelle on se trouve, ce qui devient vite impératif quand on est en train de jongler entre les machines et les imbrications de screen.