On m’a fait lire hier un article, « Bourne Into Oblivion« , dans lequel l’auteur explique comment ce qu’il nomme une bombe à retardement a eu des conséquences gravissimes pour le système informatique d’une société. En résumé, un script d’administration faisait le ménage après avoir terminé sa tâche grâce à un rm -rf $var1/$var2. Mais ce script s’est vu exécuté avec $var1 et $var2 non définis, et s’est donc terminé avec un rm -rf /, en root, sur un NFS (pour les non unixiens, cela signifie effacer l’intégralité des systèmes de fichiers du réseau, avec le droit de le faire). Autant dire que c’est une catastrophe sans nom pour la société, surtout lorsque l’on ajoute que c’est à ce moment que les backups se révèlent être inutilisables.
Cette histoire qui ferait froid dans le dos à tout administrateur système m’a plongé dans une réflexion, que voici, sur la liste finalement assez importante d’erreurs ayant conduit à cet accident. Le but n’est pas de critiquer, mais de voir ce qu’il est possible d’apprendre de tout cela.
Tout d’abord, il est clair que ce script était exécuté avec des privilèges bien trop importants. Il n’y a que peu de choses qui puissent justifier qu’un script doive être lancé en tant que root. Il aurait dû être lancé en tant que simple utilisateur sans privilège, éventuellement avec un compte créé spécialement dans ce but. Les opérations nécessitant réellement des droits de super utilisateur auraient dû être isolées et appelées avec un sudo ou encore disposer d’un bit suid. Pour le reste, et notamment tout ce qui s’apparente à de la lecture, des droits correctement affectés avec des groupes auraient dû suffire. D’une façon générale lancer un script en root n’est absolument pas anodin, et au delà du problème rencontré ici, se pose celui de la possibilité d’une faille de sécurité.
L’article mentionne de plus le fait d’avoir lancé un script pour le week-end, autrement dit pour une durée d’exécution a priori relativement longue. Si le fait de laisser une tâche d’administration sans surveillance est courant, le fait que ce soit en tant que root change la donne et vient aggraver, s’il était besoin, le point précédent.
La justification de l’exécution en tant que super utilisateur mise de côté, ce bout de script n’était manifestement pas assez défensif étant donné ce contexte particulièrement dangereux. Son auteur n’aurait jamais dû laisser un tel appel se faire sans un test des deux variables. Cela dit le script n’était peut-être pas prévu à l’origine pour être lancé en tant que root, ce qui amène donc à considérer comme règle qu’un code faisant ce type de manipulation doit être défensif quoi qu’il arrive, dans la mesure où l’on ne sait pas dans quelles conditions il peut-être amené à être utilisé par la suite.
On peut de plus remarquer que le fait d’utiliser un répertoire à la racine est déjà discutable. Si cette remarque peut sembler être un pinaillage purement cosmétique, on s’aperçoit que si en pratique les répertoires utilisés avaient été /tmp/$var1/$var2 ou encore /usr/src/$var1/$var2 par exemple, un tel drame ne serait pas survenu.
Pour finir sur l’aspect purement administration, ce script aurait dû être documenté. D’après l’article, l’absence de définition des variables est la conséquence du fait que l’opérateur ne savait pas qu’il y avait des opérations à effectuer au préalable. Ce point aurait donc dû être documenté. Cependant l’expérience montre que documenter n’évite pas les accident, et reste donc insuffisant (d’ailleurs le script était peut-être même déjà documenté) : j’ai l’exemple d’un script qui servait à envoyer un mail informatif à une base d’utilisateurs, et qui portait le nom pour le moins clair de spam.sh. Il avait pourtant fallu commenter la commande essentielle du script depuis que quelqu’un l’avait lancé par erreur, n’ayant apparemment pas considéré son nom comme un avertissement suffisamment clair sur l’effet du script. Un autre exemple amusant est le message d’avertissement du système Debian en cas de apt-get jugé un peu trop violent : il demande alors de taper en toutes lettres « Oui, faites ce que je vous dis ! ». Quoi qu’il en soit, il faut d’une façon ou d’une autre, mais par un moyen technique, mettre une commande dangereuse hors de portée de toute personne qui n’est pas parfaitement renseignée.
Accessoirement, Joel Spolsky explique au deuxième point de son célèbre article, « The Joel Test« , que d’après lui l’opération de compilation et livraison d’un projet doit pouvoir être faite en une seule action, car toute étape supplémentaire entraîne la possibilité d’une erreur. L’erreur dont il est question ici et les conséquences qu’elle a eu montrent que finalement, la règle peut être étendue à toute opération d’administration.
D’autres erreurs, de nature plus humaine, sont également à l’origine de cet accident. Comme le souligne l’auteur de l’article, le passage de compétences ne s’est pas fait correctement par exemple, et la gravité de la tâche d’administration a été négligée en étant affectée à un novice. Je ne m’étendrai pas plus sur ce sujet, qui n’est plus celui de ma réflexion.
Aussi pour conclure, on se rend compte que cet incident, qui est extrêmement grave pour une société puisqu’il peut lui être fatal si les données ne sont pas récupérées, aurait pu être évité par de simples précautions. Pour la plupart d’entre elles, une seule de ces précautions aurait suffit à éviter cela. Mais peut-être que parce que ces précautions semblent dérisoires, elles sont négligées. Paradoxalement elles semblent tellement évidentes que les rappeler peut également paraître dérisoire.
Voilà en substance la réflexion que m’inspire cette histoire. N’ayant pas la prétention d’avoir plus de quelques notions d’administration système, je suis peut-être passé à côté de points importants. Si vous en voyez, n’hésitez pas à en faire part en commentaires.