lundi 26 octobre 2009

Cluster Tricks: cycle reboot

Au LACAL, nous avons récemment reçu notre nouveau cluster équipé d'Infiniband, qu'il a fallu mettre en place. Pour des raisons de convenance, rien n'est installé sur les disques des noeuds (qui servent uniquement au swap et au stockage temporaire), et le boot se fait via le réseau.

Problème 1: le BIOS est idiot - si le netboot échoue, la séquence de boot continue, puis s'arrête. Autrement dit, si un noeud tente de booter alors que le serveur est indisponible, il ne réessaie pas, il s'arrête. Ce qui serait absolument sans conséquence, s'il n'y avait le:

Problème 2: suite a un glitch administratif, nos noeuds ne sont pas équipés d'IPMI. Impossible donc de les redémarrer à distance.

Solution sympathique: puisque le disque local n'est pas utilisé pour booter, installons-y un système qui va redémarrer la machine. Il ne reste alors plus qu'a ajouter le disque à la fin de la séquence de boot, et le redémarrage sera automatique. Mais comment ?

Pour une opération aussi simple qu'un reboot, inutile de charger un système complet. On sait que, pour booter sur un disque, le BIOS vérifie d'abord la validité de la table de partitions, puis charge et exécute le code situé dans le MBR, soit le premier secteur du disque. Le code est exécuté en mode réel.

Jetons un coup d'oeil rapide dans la documentation de Linux. Elle nous apprend l'existence d'une technique primitive de redémarrage, utilisée en dernier ressort: le Triple-Fault.

Wikipedia contient une page à ce propos, et mentionne son utilisation par Linux. La technique consiste en "installer une table de vecteurs d'interruption vide, puis déclencher une interruption". Quelques recherches sur google indiquent que ceci se fait via l'instruction x86 LIDT. L'argument contient a la fois un pointeur vers la base de la table, et sa longeur; une valeur constante de 0 fonctionne pour créer une table vide.

Je crée donc un fichier reboot.asm:

lidt [0]
int 3

Que j'assemble simplement avec nasm:

max@node ~$ nasm reboot.asm
max@node ~$ hexdump reboot
0000000 010f 001e cd00 0003
0000007

Merveilleux. reste à écrire ce fragment dans le MBR de mon disque:

max@node ~ $ sudo dd if=reboot count=1 conv=notrunc of=/dev/sda

Presto !

jeudi 1 octobre 2009

Cluster Tricks: copie en masse

Dans un cluster, la vitesse des disques ou du réseau peut être un facteur limitant critique pour la performance. Considérons le scénario suivant, qui a été rencontré en pratique au Lacal:
  1. Une première phase de calcul est lancée sur chaque noeud, et produit plusieurs GB de données par noeud (stockées dans l'espace de travail sur le disque local)
  2. Une deuxième phase de calcul est lancée, et elle a besoin de toutes les données précalculées sur tous les autres noeuds.
Les disques sont assez gros pour acueillir chacun une copie du dataset intermédiaire complet (quelques centaines de GB). Mais comment les distribuer efficacement ?

Evidemment, un bête SCP ferait l'affaire, mais il serait impensable de le lancer a la main entre les différentes machines suivant un ordonnancement précis (ou alors, trop emmerdant, et pas assez réutilisable).

Un bête scp de toutes les machines vers un noeud "principal", puis de ce noeud vers les autres, ferait aussi l'affaire. Mais terriblement lent.

Au moment ou je suis intervenu sur le problème, la copie sur un noeud maître avait déja été faite, mais le scp séquenciel était hors de question (trop lent).

Une première solution intéressante s'est révélée en Bittorrent. Les outils pour cela sont disponible dans portage (nous avons utilisé BitTornado, qui est un peu plus pratique que le client original "mainline" tout en étant très similaire d'utilisation). Une fois le hash initial accompli sur le noeud maitre (ce qui prend toutefois beaucoup de temps), la copie s'est faite relativement efficacement.

Mais on est encore très en dessous du maximum théorique, ce qui m'a amené a découvrir la solution idéale pour le job: uftp (http://www.tcnj.edu/~bush/uftp.html), un système ftp-like over udp, supportant le multicast.

Avec le multicast, chaque noeud peut envoyer un seul paquet de données au switch, le paquet sera répété sur toutes les interfaces (ou seulement sur les interfaces utiles si le switch gère le Multicast Snooping, ce qui n'était pas notre cas), et chaque machine pourra réceptionner le paquet simultanément, ce qui génère un gain très appréciable de vitesse (dans notre cas, vitesse de copie globale d'environ 400MB/s, au lieu des 6MB/s offerts par scp, et des 150MB/s offerts par bittorrent.)

L'utilisation est très simple, même si manquant un peu de flexibilité. Le recepteur est un daemon tournant sur chaque machine, qui stockera tous les fichiers reçus dans un répertoire public sur le disque local. L'émetteur est un client lancé par un utilisateur, qui prendra simplement un nom de fichier en argument.

Evidemment, ce système est totalement abusable et n'intègre absolument aucune sécurité. et ne doit être employé qu'a l'intérieur d'un réseau de confiance. L'ebuild est disponible ici (https://xolus.net/~max/uftp-ebuild.tar.gz) en attendant qu'elle fasse son chemin dans Sunrise.

mardi 9 juin 2009

Contrôler le crédit sur une carte SIM avec Nagios

Il est inutile de présenter Nagios, un système de monitoring très populaire et flexible.

J'ai la chance d'avoir a disposition, depuis mon serveur Nagios, un modem GSM très pratique pour envoyer des SMS d'alerte en cas de problème sur un service quelconque. Pour l'envoi de SMS, j'utilise SMSTools, qui s'installe sous la forme d'un daemon prenant le contrôle
du modem, et d'un répertoire de spooling (/var/spool/sms) dans lequel on dépose les messages sortants, au format adéquat.

Pour rendre la chose plus facile, il existe également un script d'envoi simple (sendsms) qui a l'avantage d'éviter les problèmes classiques aux répertoires de spool (conditions de course, etc..). Nagios se configure très simplement pour envoyer des notifications:

define command{
command_name notify-host-sms
command_line /usr/local/sbin/sendsms $CONTACTPAGER$ "'Host $HOSTNAME$ is $HOSTSTATE$'"
}

define command{
command_name notify-service-sms
command_line /usr/local/sbin/sendsms $CONTACTPAGER$ "'Service $SERVICEDESC$ @ $HOSTALIAS$ is $SERVICESTATE$'"
}


C'est parfait, tout va bien. Mais la carte SIM installée dans le modem est une carte prépayée. Comment faire si le crédit sur cette carte s'épuise ? nous allons justement utiliser Nagios pour surveiller le crédit sur la carte, et émettre un avertissement s'il tombe trop bas.

Avec mon opérateur téléphonique, on peut contrôler son crédit restant depuis le téléphone, en entrant une commande de service au clavier: *130#. Le téléphone répond avec un message indiquant le crédit restant.

Quelques recherches sur google indiquent que ce type de commandes s'envoie au modem au moyen de la commande AT CUSD. On teste immédiatement avec minicom:

AT+CUSD=1,*130#,15
OK

+CUSD: 2,"Credit actuel: CHF -0,44; 25 SMS gratuits jusqu'au 01.10.2009",15


Reste a interagir correctement avec le modem, ce qui n'est pas totalement trivial a cause de quelques détails pratiques. J'utilise pour piloter le terminal un obscur outil appelé comgt, un équivalent de "chat" (le système de script utilisé par ppp) mais en plus flexible. Voila le script (a mettre dans /etc/comgt/credit):

set com 115200n81
set senddelay 0.05
send "AT+CUSD=1,*130#,15^m"
waitfor 60 "+CUSD:"
get 10 "^m" $s
print "Reply: ",$s,"\n"


On teste avec comgt:

gate # comgt -d /dev/ttyS0 credit
SIM ready
Waiting for Registration..(120 sec max)
Registered on Home network: "Swisscom"
Signal Quality: 21,99
Got: " 2,"Crdit actuel: CHF -0,44; Xtra-liberty: 25 SMS gratuits jusqu'au 01.11.2009.",15


Reste à traiter la sortie pour l'envoyer vers nagios (exercice pour le lecteur parce que je suis paresseux).

lundi 25 mai 2009

Gare au Hadophishing !

J'ai discuté récemment avec un internaute français, téléchargeur occasionnel, qui était persuadé d'avoir reçu un mail d'avertissement Hadopi.

Le mail en question est arrivé sur la mailbox de son ISP, "contre-signé par la gendarmerie", et incluait des prétendues preuves sous la forme d'une liste de téléchargements avec dates et heures.

J'ai hésité un instant. Pour autant que je sache, l'infrastructure Hadopi est loin d'être opérationnelle, cet e-mail était donc selon toute vraisemblance une tentative de phishing.

Comment la liste de téléchargements a-elle été produite ? Etait-ce simplement une liste aléatoire de titres populaires ? Comment un phisher pourrait-il relier une liste de téléchargements à une mailbox d'ISP ? Il est sûrement assez facile de moissonner des adresses IP sur un réseau P2P public, mais le lien avec les mailboxes correspondantes ne devrait être connu de personne hormis l'ISP.

Faut-il donc voir une brèche de sécurité chez son ISP ? un employé mécontent aurait-il pu revendre ces informations à un phisher ? ou pire, l'attaque pourrait-elle directement émaner d'un insider ?

Tout ceci fait réfléchir aux implications du processus prévu par la loi Hadopi. Les mails de phishing de ce genre sont une deuxième attaque évidente contre ce processus (la première est l'envoi de plaintes arbitraires et invérifiables a l'encontre d'inconnus)