Antoine Benkemoun

05 Fév, 2010

Récit d’une « petite » erreur

Posté par Antoine dans la catégorie Blog|Libre|Unix

Cette journée fut particulièrement mouvementée. Bien évidemment, ce n’était pas prévu et tout s’annonçait paisible tel un Vendredi classique. J’avais prévu deux transferts planifiés de sites dont le transfert avait été minutieusement préparé et répété. Une migration parfaitement classique.

Je me rends compte qu’il est nécessaire de modifier le fichiers de VirtualHost de tous les sites web du serveur Apache. Les Virtualhost sont les fichiers de configuration de site d’Apache. Au lieu de mettre « <Virtualhost IP> », il est nécessaire de mettre « <Virtualhost IP:port> ». Il n’était pas question de tout modifier à la main, il y a plus de 200 fichiers. Par sécurité, j’ai effectué une sauvegarde du répertoire sites-enabled. Dans ce cas, un script était nécessaire. Je code cela rapidement :

for i in `ls -1 .`; do cat $i | sed ‘s/<Virtualhost IP>/<Virtualhost IP:port>/g’ > $i; done

Et là, c’est le drame.

Ce petit script est, hélas, syntaxiquement correct. Il remplace bien les deux chaines de caractère comme je souhaitais qu’il le fasse. Il a été exécuté en root car je travaille toujours en root par simplicité. Si vous regardez de plus près, vous remarquerez qu’il écrit dans le même fichier qu’il lit. Erreur fatale. Ceci signifie la suppression de tous les fichiers du répertoire courant. Tous. Tous les Virtualhost disparus. Quant à la sauvegarde du répertoire sites-enabled ? Inutile car ce sont des liens symboliques.

Houston, we have a problem.

Quelques minutes suffisent pour se rendre compte de l’erreur commise par ce script en apparence anodin. Les sauvegardes, me diriez-vous. J’apprends qu’elles sont en erreur depuis longtemps. Par chance, une copie de la machine virtuelle était présente sur l’ancien serveur VMWare duquelle elle avait été migré avant-hier. La récupération d’une bonne partie des Virtualhost a été possible jusqu’à ce point. Sauf que nous avions transféré 120 sites hier. Cette erreur n’a pas créé d’indisponibilité car Apache mémorise la configuration. Un restart serait par contre fatal.

Il ne reste plus qu’une solution : créer un script à partir de la configuration de l’ancien serveur pour recréer tous les Virtualhost créés hier. Deux heures de développement d’un script pas si simple dans un des langages les plus moches sur Terre : Bash. Une heure de debug du script. Après trois heures de stress intense et d’activité cérébrale, les Virtualhost avaient été recréés. Quelques Virtualhost ont du être récréés à la main car le script n’avait pas fonctionné avec.

Finalement, Apache accepte les Virtualhost créés par mon script. Je suis sauvé.

Je pense qu’il est important de tirer les enseignements de ses erreurs. Dans ce cas, il va falloir que j’apprenne à utiliser sed et à ne plus jamais scripter sur un serveur de production. Nous faisons tous des erreurs et nous devons donc nous assurer que ces erreurs seront inoffensives. Dans ce cas, la protection face à l’erreur a été inutile à cause d’un élément technique dont j’avais parfaitement conscience. Un petit moment d’inattention a suffit pour tout faire basculer.

Au final, il y a deux types d’administrateurs système : ceux qui ont déjà tout cassé à cause d’une erreur de script et ceux qui vont le faire.

Tags: , , ,

18 Commentaires to "Récit d’une « petite » erreur"

1 | Aldevar

février 5th, 2010 at 17 h 25 min

Avatar

« Au final, il y a deux types d’administrateurs système : ceux qui ont déjà tout cassé à cause d’une erreur de script et ceux qui vont le faire. »

Excellent! A méditer :)

2 | Jack

février 5th, 2010 at 17 h 37 min

Avatar

L’option -i de sed aurait été pratique.

sed -i ’s///g’ *.conf

3 | madx

février 5th, 2010 at 17 h 41 min

Avatar

Tiens, ça m’est déjà arrivé aussi, j’ai effacé tout le code source d’un projet de cours. Résultat, j’ai du tout reprendre depuis le début.

Depuis, je mets tout systématiquement sous git !

4 | Antoine

février 5th, 2010 at 17 h 46 min

Avatar

@jack bien vu ! Je ne connaissais pas.

5 | Fred

février 5th, 2010 at 17 h 47 min

Avatar

@Aldevar

Ne pas oublier que l’appartenance à l’une des catégories n’exclut pas l’appartenance à la seconde également.

Pour en revenir à l’histoire, heureusement ça se finit bien et je pense que la leçon ne sera jamais oubliée :-)

6 | AP

février 5th, 2010 at 18 h 00 min

Avatar

sed… ou perl qui accepte aussi le « -i ». Les expressions régulières de perl vont un peu plus loin que celles de sed.

perl -i -ple ’s///g’ *.conf

sed et perl acceptent aussi la syntaxe : « -i » pour créer un fichier de sauvegarde. Exemple :

perl -i.orig -ple ‘s///g’ toto.conf

…créera un toto.conf.orig

7 | Pois

février 5th, 2010 at 18 h 04 min

Avatar

Le plus simple aurait quand même était de faire un cp du repertoires avant de tester sur ce rep …

8 | Antoine

février 5th, 2010 at 18 h 05 min

Avatar

Ce que j’ai fait mais vu que c’était un répertoire de liens symboliques, c’est inutile =)

Quant aux différentes options, je saurais pour la prochaine fois =D

@AP, effectivement il faudrait que je prenne le temps de me mettre au Perl =)

9 | ben

février 5th, 2010 at 18 h 39 min

Avatar

mieux que cp = rsync …

Avec l’option  » -L « , rsync copie les liens symboliques, et tout le contenu

10 | Zanko

février 5th, 2010 at 19 h 56 min

Avatar

Rassure-toi t’es pas le seul à t’être fait avoir avec sed ^^ (bon moi c’était dans un répertoire sous svn alors ça allait). Au moins ça marque et comme ça la prochaine fois tu te souviendras qu’il faut ajouter un -i.

11 | StalkR

février 5th, 2010 at 20 h 08 min

Avatar

De manière générale quand on a un « cat file | operations > file », il y a sponge du paquet moreutils qui sert comme son nom l’indique de tampon. On fait alors cat file | operations | sponge file et le tour est joué !
Et oui dans le cas de sed y’a tout simplement -i ;)
Enfin, le paquet moreutils contient d’autres petits outils bien pratiques qui valent le détour et dont on ne peut plus se passer (je renvoie à http://linux-attitude.fr/post/en-vrac-22 qui me les a fait connaître).
Bonne continuation.

12 | david

février 5th, 2010 at 23 h 25 min

Avatar

La citation est un grand classique. De toute façon on ne devient un bon admin qu’à force de bêtise de ce genre. Personnellement j’adopte 4 principales règles :
+ pas de modification en prod le vendredi => risque de gâcher le weekend et en général c’est toujours le vendredi que le responsable des sauvegardes est en RTT.
+ pas de modification en production sans avoir fais une recette en test. Si il n’y a pas de serveurs de test je ne fais pas la modification (après tout c’est ma responsabilité qui est impliquée).
+ Avant tout déploiement en production vérifier les sauvegardes et faire un tar.gz du répertoire sur lequel je travaille.
+ Ne jamais travailler en root ! sudo est la pour ça.

et pour info ces règles viennent de mon expérience personnelle au début de ma carrière. Oui j’en ai fais des conneries et je remercie les collègues plus expérimentés à l’époque qui ont su me tirer de l’embarras.

13 | JB

février 6th, 2010 at 1 h 04 min

Avatar

Sudo ne fait pas de grande différence fondamentalement : ici ça aurait peut-être fait gauffrer la redirection si c’était tapé en ligne de commande mais apparemment c’était dans un script..

Je ne peux qu’être d’accord avec les autres conseils et la morale :)

Par contre je suis curieux de savoir pourquoi il a fallu modifier tous les vhosts : n’était-il pas possible de modifier plutôt httpd.conf ? Question naïve hein, c’est toujours facile de venir proposer ça après..

14 | Gu!oN@*

février 6th, 2010 at 8 h 54 min

Avatar

La morale de cette histoire est qu’il faut toujours sauvegarder avant de faire quoique ce soit enfin l’essentiel est que tu t’en sois sortié (grâce à Apache qui garde tout en mémoire).

15 | Antoine

février 6th, 2010 at 12 h 40 min

Avatar

@JB, en fait quand tu ne spécifies aucun port, c’est par défaut le port 80 mais si tu veux faire plusieurs ports différents (80 et 443), il faut le spécifier. Dans mon cas, je voulais rajouter un vhost sur le port 443.

@david, je suis entièrement d’accord avec toi par rapport au serveur de recette sauf que j’en ai absolument jamais vu. Que ce soit dans une grosse boite, petite ou moyenne. Pour le Vendredi, ca avait été la première recommandation de mon prof de Linux :P

16 | Desidia

février 6th, 2010 at 14 h 19 min

Avatar

Hello,

Le piège, ici, c’est d’avoir compté sur une copie du répertoire, ce qui a été compromis par les liens symbolique.

Ce qui n’est pas mal, c’est de faire une archive du répertoire avant toute modification, avec tar et l’option -h, qui «ne sauvegarde pas les liens symboliques mais les fichiers pointés.» (page de man).

17 | Julito

février 8th, 2010 at 10 h 54 min

Avatar

C’est bien, c’est beau, c’est bash :p

18 | Mehdi GHEZAL

février 8th, 2010 at 11 h 51 min

Avatar

Pour l’option -i, attention cela dépend de la version de sed. J’ai déjà fait un script testé sur un serveur qui n’avait pas exactement la même version de sed et sur l’un -i fonctionnait sur l’autre…

Oupss ^^

Ajoutez votre commentaire

A propos de ce blog

Ce blog a pour objectif de partager des informations avec tous les internautes. Comme indiqué dans le titre, je traiterais de différrents sujets gravitant autour de la sécurité informatique, de la virtualisation, de la l'administration système et du réseau.