Quelques digressions sous GPL...

Aller au contenu | Aller au menu | Aller à la recherche

mercredi, janvier 27 2010

Java pas marcher !

computer bug Rhodidiou ! Ca y est, je suis de mauvaise humeur... Alors que je commençais tout juste à me dire que Java ca pouvais être pas mal de temps en temps, voilà que je perd deux heures sur un problème à la con !

Je m'explique.

Aujourd'hui, mon serveur Alfresco arrive en production. Jolie petite machine sous Debian avec Tomcat dessus et tout et tout. Il démarre, le gars dans le datacenter m'annonce fébrilement qu'il a branché le cable, je test et hop je vois ma page s'ouvrir. La magie du moment m'émeut, alors empli de confiance je tente la page de login d'alfresco share. Et là, tout s'enchaine !

Java a la particularité de savoir vous insulter longuement et goulument dans un langage que vous ne comprendrez de toute façon jamais. Genre "j'ai pas pu ouvrir le fichier alors je te fait un dump complet des tes 4 GO de mémoires dans syslog". Sympa, mais pas pour le diagnostic. Alors tout bon sysadmin qui a déjà eu affaire à java sais qu'une trace de jvm c'est encore plus désagréable à contempler qu'un tableau de Joan Mitchell...

Celle qui m'agressait cette après-midi s'appelait, de son petit nom :

15:07:05,510 INFO  [org.alfresco.config.JndiPropertiesFactoryBean] Loading properties file from class path resource [alf
resco/repository.properties]                                                                                            
15:07:05,514 INFO  [org.alfresco.config.JndiPropertiesFactoryBean] Loading properties file from class path resource [alf
resco/domain/transaction.properties]                                                                                    
15:07:05,514 INFO  [org.alfresco.config.JndiPropertiesFactoryBean] Loading properties file from URL [file:/var/lib/tomca
t6/shared/classes/alfresco-global.properties]                                                                           
15:07:06,309 INFO  [org.alfresco.config.JndiPropertyPlaceholderConfigurer] Loading properties file from class path resou
rce [alfresco/alfresco-shared.properties]                                                                               
15:07:10,794 WARN  [org.hibernate.cfg.SettingsFactory] Could not obtain connection metadata                             
org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Communications link failure        
                                                                                                                        
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the
 server.)                                                                                                               
        at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1225)                          
        at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:880)                              
        at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionP
rovider.java:81)                                                                                                        
        at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:84)                                     
        at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2073)                                       
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1298)                                 
        at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:805
)                                                                                                                       
        at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:7
45)                                                                                                                     
        at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.j
ava:134)                                                                                                                
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowi
reCapableBeanFactory.java:1203)                                                                                         
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireC
apableBeanFactory.java:1172)                                                                                            
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapab
leBeanFactory.java:427)                                                                                                 
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:249)      
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegis
try.java:155)                                                                                                           
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:246)          
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)          
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueRes
olver.java:267)                                                       

et ça continue pendant des kilomètres... Faut savoir que, là dedans, ya une seule info intéressante, c'est ça :

Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure                         

Bon... Donc Tomcat se ramasse en douze façon Nikolay Davydenko en quart de finale d'un tournoi du grand Chelem. Reste à savoir pourquoi. Mon serveur tomcat est bien lancé, netstat -taupen|grep mysql me le montre bien en LISTEN sur 127.0.0.1.. donc j'en fait quoi moi, de ma tartine ?

Reste les grands moyen, obligé d'installé un tcpdump sur un serveur de prod tout propre... m'enfin bon, c'est ça ou l'aller-retour sur l'A86. Alors je branche mon port en écoute façon

tcpdump -w trace_tomcat_mysql.pcap -s 16436 -Svni lo tcp and port 3306

Et voilà qu'il me retourne le truc suivant :

wireshark tomcat

Faut cliquer sur l'image, sinon vous allez vous faire mal aux yeux. Bref, ce qu'il me dit mon wireshark, c'est que le Tomcat il essai de se connecter au Mysql en IPv6... Pourquoi il fait ça ? J'en sais rien... Est-ce qu'il le faisait déjà avant et que c'est coté MySQL que quelque chose à changé ? J'en sais rien. Ce qui est sur, c'est que MySQL ne bind pas son port en IPv6. Donc ça peut pas marcher...

2 heures de galères....

Ouaip, deux heures, ca explique le coté un peu nerveux du billet. Entre les redémarrages de tomcat en changeant les paramètres, les tentatives de modification du port coté MySQL, j'ai même pensé à un problème de security policy de Debian... niveau noeud aux cerveaux, on fait pas mieux.

Alors je vous fait pas attendre plus longtemps, le problème c'est apparemment une mise à jour de cette $%*££ù* de JVM qui fait privilégie maintenant les requêtes en IPv6 sur IPv4. Me demandez pas quel est l'@&%ù** qui a décidé ça sans prévenir personne, mais dans le genre belle bêtise, elle est pas mal.

Bref, ça se corrige en rajoutant le paramètre suivant dans les JAVA_OPTS du fichier /etc/default/tomcat6:

-Djava.net.preferIPv4Stack=true

Redémarrage fébrile du Tomcat.

Le regard figé sur mon tail -f /var/log/tomcat6/alfresco.log

Pas de message bizarre, cela marcherait-il ?

YES ! La page de login !!!!

Voilà, c'était 3615 mylife dans la catégorie mésaventures de sysadmin.

mercredi, janvier 20 2010

C'est pas faute de vous avoir prévenu !

Encore une piqure de rappel, cette fois chez facebook:

source: http://therumpus.net/2010/01/conversations-about-the-internet-5-anonymous-facebook-employee/?full=yes

vu chez: http://www.schneier.com/blog/archives/2010/01/privacy_violati.html

    Rumpus: You've previously mentioned a master password, which you no longer use.

    Employee: I'm not sure when exactly it was deprecated, but we did have a master password at one point where you could type in any user's user ID, and then the password. I'm not going to give you the exact password, but with upper and lower case, symbols, numbers, all of the above, it spelled out 'Chuck Norris,' more or less. It was pretty fantastic.

    Rumpus: This was accessible by any Facebook employee?

    Employee: Technically, yes. But it was pretty much limited to the original engineers, who were basically the only people who knew about it. It wasn't as if random people in Human Resources were using this password to log into profiles. It was made and designed for engineering reasons. But it was there, and any employee could find it if they knew where to look.

    I should also say that it was only available internally. If I were to log in from a high school or library, I couldn't use it. You had to be in the Facebook office, using the Facebook ISP.

    Rumpus: Do you think Facebook employees ever abused the privilege of having universal access?

    Employee: I know it has happened in the past, because at least two people have been fired for it that I know of.

    [...]

    Employee: See, the thing is -- and I don't know how much you know about it -- it's all stored in a database on the backend. Literally everything. Your messages are stored in a database, whether deleted or not. So we can just query the database, and easily look at it without every logging into your account. That's what most people don't understand.

    Rumpus: So the master password is basically irrelevant.

    Employee: Yeah.

    Rumpus: It's just for style.

    Employee: Right. But it's no longer in use. Like I alluded to, we've cracked down on this lately, but it has been replaced by a pretty cool tool. If I visited your profile, for example, on our closed network, there's a 'switch login' button. I literally just click it, explain why I'm logging in as you, click 'OK,' and I'm you. You can do it as long as you have an explanation, because you'd better be able to back it up. For example, if you're investigating a compromised account, you have to actually be able to log into that account.

    Rumpus: Are your managers really on your ass about it every time you log in as someone else?

    Employee: No, but if it comes up, you'd better be able to justify it. Or you will be fired.

    Rumpus: What did they do?

    Employee: I know one of them went in and manipulated some other person's data, changed their religious views or something like that. I don't remember exactly what it was, but he got reported, got found out, got fired.

mardi, décembre 8 2009

Du Chaos, mes amis, du Chaos !

Kitty evilL'inconvénient de vivre dans un appartement en plein Paris, c'est que l'espace manque rapidement. Moi, perso, tant que j'ai de la place pour brancher des machines à plus savoir quoi en faire, tout va bien, mais mademoiselle c'est une autre histoire. En fait, elle aimerait bien qu'on ai un chat à la maison. Vous savez ces trucs pleins de poils, au demeurant mignon et sympa mais, bon, je dois normalement pouvoir remplir ces fonctions. Sauf, peut être, pour le coté "laisse tes poils partout et surtout sous le lit". La dessus, je dois admettre que j'ai du mal.

Bref, je digresse.

Donc mademoiselle voudrait un chat, et elle a trouvé un parfait argument lorsque je lui ai parlé de mon projet d'acquérir une eKey. Selon ses dires, si l'objectif de l'objet est de générer du chaos, il serait tout autant efficace de disposer d'un de ces petits diables poilu et de le laisser toute la journée dans l'appartement.

Alors c'est quoi une eKey ? En fait, dans tout système Linux (et Unix souvent) existe un puit d'entropie nommé /dev/random. Le noyau collecte des bits un peu partout sur le système, dans les drivers des périphériques surtout, là ou l'activité est supposée difficile à deviner, et remplit le puit avec ces bits. Dés que l'on utilise un tant soit peu de crypto, OpenSSL, OpenSSH, etc..., on pioche dans ce puit. La problème est qu'il est pas bien grand notre puit, puisque sa taille se limite à 4KB. C'est d'ailleurs à cause de cette taille réduite que les systèmes disposent de deux périphériques: /dev/random et /dev/urandom. La différence entre les deux ? Ils fournissent les mêmes bits aléatoires collectés par le système mais, lorsque le puit est vide, /dev/random va bloquer jusqu'à ce qu'il se remplisse alors que /dev/urandom va bricoler pour renvoyer d'autres bits, moins aléatoires, mais sans bloquer le programme appelant.

Tout l'intérêt de l'eKey est donc de fournir une source externe d'entropie afin de s'assurer que ce puit n'est jamais vide, et que l'on peut donc utiliser /dev/random uniquement sans avoir à craindre de ralentir ses programmes. C'est particulièrement indispensables sur des serveurs réalisant un grand nombre de connexions SSL !

Revenons donc à notre Chaton Chaotique

Ma chère et tendre me propose donc d'utiliser l'incroyable capacité de ces petites bêtes à générer du chaos dans mon serveur (celui qui héberge ce site) plutôt que d'enrichir le britannique en important sa technologie. Elle n'a pourtant aucune famille du coté Napoléonien, mais je dois admette qu'elle marque un point.

Le pire, c'est que techniquement, c'est jouable. Une vieille webcam recyclée en caméra de surveillance du salon, un chaton qui passe sa journée à sauter du canapé à la table de cuisine, à fourrer ses pattes sur mes vinyles et à bouffer mes RJ45 ! En backend, un petit programme pour convertir les données reçues en bits à injecter dans /dev/random. Et en plus ça pourrait être rigolo à faire !

Bref, me voilà coincé. Mon argument principal de refus se retrouve confronté à la curiosité technique... Que faire ? Trouver une parade technologique sur laquelle ronger mon frein en attendant que l'espace vital du doux foyer conjugal soit compatible avec ledit prédateur de pelotes de laines.

cat /proc/sys/kernel/random/entropy_avail

Alors que je lisait un billet des plus intéressant sur planet.debian.org, j'ai réalisé que le niveau d'entropie disponible sous Linux était exporté dans /proc. C'est fou la quantité de choses que l'on trouve dans ce pseudo système de fichiers ! Curieux de voir si mon modeste système, qui n'est en fin de compte utilisé que pour des sites persos et des services à quelques personnes du domaines linuxwall.info, nécessitait réellement une source externe d'entropie, je me suis donc fendu d'un minuscule script bash et de quelques lignes de gnuplot.

Ca donne ça :

#! /bin/sh
while [ 1 ]
do
   DATE=`date +%s`
   ENTLVL=`cat /proc/sys/kernel/random/entropy_avail`
   echo "$DATE:$ENTLVL" >> entlvl.log
   sleep 1
done

Qui remplit gentillement un fichier entlvl.log avec des lignes du type :

julien@zerhuel:/$ tail entlvl.log
1260265664:177
1260265665:183
1260265666:191
1260265668:265
1260265669:265
1260265670:305
1260265672:322
1260265673:175
1260265675:199
1260265676:220

(le premier champ, c'est du temps Unix, le deuxième, c'est des octets).

Et que l'on va ensuite utiliser pour génerer des graphiques gnuplot avec le script suivant :

set title "Entropy level on zerhuel.linuxwal.info"
set xlabel "time"
set ylabel "bits"
set yrange [0:4200]

set terminal png
set output "/data/www/pki/entropy_level.png"

set xdata time
set timefmt "%s"
set format x "%d/%m/%y:%Hh%M"
set xtics nomirror rotate
set datafile separator ":"
plot '/data/julien/code/scripts/entropylevel/entlvl.log' using 1:2 with dots

Verdict ?

Tout cela a tourné sur ma machine pendant deux mois, en marquant une valeur toutes les secondes. La courbe en date de ce matin donne :

entropy level

Plus précisement, si on regarde une période de deux heures pendant laquelle je travaillais intensément sur la machine (HTTPS + 2*SSH), ca donne ça :

entropy level 2h

Ces deux graphs montrent bien qu'on est loin du niveau de famine nécessitant une source externe d'entropie. Ca se confirme à l'usage, je n'ai jamais ressenti de lenteur dans l'établissement de connexios (sauf quand je joue avec --limit et iptables, mais c'est autre chose :p ).

On peut également calculer les moyennes pour vérifier le niveau d'entropie. Si ça vous amuse de jouer en bash, ça se fait facilement de la façon suivante:

Changez juste le nom du fichier 'entlvl.log' deux fois dans la ligne suivante:

julien@zerhuel:/$ sum=0;for i in `cat entlvl.log |cut -d : -f2`;do sum=$(($sum+$i));done;echo $sum / `wc -l entlvl.log|awk {'print $1'}`|bc -l

Sur deux mois, j'ai 3106.80. Donc plutôt un puit d'entropie bien remplit.

En période de boulot (sur deux heures), j'ai 2336.70. Donc c'est plutôt bien plein également.

En gros, et pour finir

Ca veut dire deux choses, ces petites mesures (outre le fait que j'ai encore passé du temps à geeker sur un truc qui potentiellement ne sert à rien).

  1. Sur votre serveur perso, même avec une utilisation intensive, la collecte d'entropie mise en place par le noyau est suffisante. Maintenant ca peut varier selon la machine. Un collègue me parlait des mini-pc à base de mémoire flash sur lesquels l'ouverture de session SSH peut prendre assez de temps pour se repasser l'intégrale d'Annie Cordy.
  2. Sweetie, I'm afraid the chaotic kitty will not be needed anytime soon... :p

Ouf !

jeudi, novembre 5 2009

La DéGoogleisation a t'elle commencée ?

google girlJe sais pas si vous avez remarqués, mais ça fait maintenant quelques temps que les nouveaux produits de Google ne sont plus plébicités comme les messis de l'Internet. De mémoire (vive), il me semble que le dernier était Gmail, ou peut être GReader. Mais depuis Chrome, le navigateur qui espionnait, les nouveaux produits de Google semblent avoir le vent de face. J'imagine que c'est le pain noir de toute multinationale. Après tout, Microsoft a suivi le même chemin à la fin des années 80 et est maintenant au fond du trou technologique (il parait que ya un truc qui s'appelle seven et qui est censé les sauver.... mouai).

Pourquoi je vous parle de ça ? N'étant pas utilisateur outre-mesures des services Google autres que le moteur de recherche (ah si! j'ai encore un compte gmail mais comme il redirige sur mon compte linuxwall, est-ce que ça compte? note: un compte qui compte pas...désolé), on pourrait dire que les déboires du géant californien me grattent à peu près autant que ma chaussette droite. Mais voilà, en deux jours, je suis tombé sur deux articles qui démolissent deux technologies phares de(ux) Google.

Le premier nous raconte comment Wave va changer le monde, l'article est plutôt rigolo et j'imagine exagéré, mais bien symptomatique du problème: une société recrée la roue, mais avec tellement de hype autour que même si c'est pas mieux qu'avant, c'est vachement plus branché et donc forcément indispensable. (non, non je ne suis pas en train de parler d'Apple, on est toujours sur Google là).

Le second, pas un article mais les slides d'une conférence relayés par Harald Welte, est encore plus explicite sur la stratégie de Google en matière d'Open Source. J'utilise le code de linux, je communique sur le code de linux, j'en fait un OS pour téléphone portable ultra révolutionnaire (limite Iphone) parce que basé sur linux... sauf que voilà, quand quelques experts regardent à l'intérieur de la machine, c'est la surprise: code ravagé par modifications à la hache pour limiter l'ajout de device ou leurs initialisation, pans entier supprimés (udev quand même, et une partie du support des threads de la libc, les trucs pas utile quoi). Et pour le détail, lisez les slides, yen a une 20aine seulement et c'est éloquent.

Question: C'est quoi exactement, la stratégie de Google? Pour le moment, entre Chrome, Wave et Android, j'ai plutôt l'impression qu'ils essaient d'élargir la pieuvre et de proposer du service unifié au plus grand nombre. Pourquoi ça marche? Parce que Google, c'est quasiment la seule boite qui a réussi à tout unifier sous un seul login/mdp par utilisateur. Et ça, c'est de la Killer Features que toutes les boites essaient de mettre en place, moyennant des millions d'euros d'investissements, sous le nom de Single Sign On.

Super, donc Google ne serait pas si mauvais que ça sur le fond technique? Non, clairement pas. Mais dans la course au service, beaucoup oublient que la quantité ne fait pas la qualité. Suffit de pointer son regard vers Redmond pour ceux qui doutent encore.

Alors, au final, je m'en cogne un brin que Google fasse de la daube, vu que je n'utilise pas leurs services. Mais je trouve quand même cela dommage car ils ont tirés bon nombre d'innovations dans le domaine du net, surtout en termes d'ergonomie. Mais si les prochaines innovations de Google doivent se transformer en monstres baveux nécessitant une 50aines de patchs et une 10aine de release majeures pour ressembler au prince charmant (comme pour Chrome), je préfèrerais qu'ils arrêtent là, et on commencera alors tous à tourner la tête vers les outsiders qui montent.

vendredi, août 21 2009

Droper les réseaux indésirables avec Netfilter et SpamHaus

Un peu de bidouille netfilterienne pour bloquer les réseaux définit par spamhaus comme indésirables. On pourrait faire cela avec ipset, puisque l'outil est désigné pour, mais apparemment, il faut jouer un peu avec le noyau et recompiler iptables pour avoir une version qui marche sur Lenny.

Du coup, j'ai trouvé que ca aller plus vite de le faire directement dans netfilter, avec quelques lignes de bash.

L'idée est simple: on prend toutes les NOUVELLES connections entrantes et on les fait passer une fois par une chaine spéciale qui va vérifier que l'IP source n'est pas listée par spamhaus. Donc il nous faut cette chaine spéciale et un petit script qui va, tous les matins, récupérer la nouvelle liste de spamhaus et l'intégrer dans netfilter.

C'est parti.

Dans un premier temps, on va créer deux chaines : une CHECKDROPLIST qui va contenir les réseaux et une LOGCHECKDROPLIST qui va loguer avant de DROPer les paquets.

iptables -N CHECKDROPLIST
iptables -N LOGCHECKDROPLIST
iptables -A LOGCHECKDROPLIST -j LOG --log-prefix \
"SOURCE IN DROPLIST" --log-level debug
iptables -A LOGCHECKDROPLIST -j DROP

Pour le moment, on a rien mis dans CHECKDROPLIST, ca va venir après.

Maintenant, il faut que l'on filtre les paquets entrant. Mais ou ? En fait, cela dépend de l'utilisation que vous faites de la machine. Dans mon cas, je n'effectue pas de routage, et donc la chaine FORWARD n'est pas utilisée. Je vais donc pouvoir filtrer simplement dans la table "filter" de la chaine "INPUT".

Pour un récapitulatif des tables et chaines, voir ici : http://wiki.linuxwall.info/doku.php?id=ressources:dossiers:advanced_networking:1_netfilter_en_grand

Dans ma chaine INPUT, j'ai tout d'abord une règle pour accepter les connections ESTABLISHED, et juste après je vais ajouter ma règle de check de la droplist. Encore après, je peux positionner toutes mes règles de filtrage classiques.

La règle de filtrage ne va s'appliquer que sur les états NEW, pour pas alourdir le filtrage et impacter les perfs :

iptables -t filter -A INPUT -i eth0 ! -s 192.168.1.0/24 \
-m state --state NEW -j CHECKDROPLIST

OK, on est pret ! La configuration actuelle ne va pas perturber le fonctionnement normal du firewall, les nouvelles connections vont juste passer dans CHECKDROPLIST et comme rien n'y est fait pour le moment, vont continuer leurs chemin.

Maintenant, le script que l'on va mettre en place va récupérer le fichier sur spamhaus.org, le parser et injecter les adresses dans la chaine CHECKDROPLIST. On va faire passer ces adresses dans une regex pour éviter d'injecter n'importe quoi.


#! /bin/sh
# get the drop list from spamhaus
# and import it into netfilter
URL=http://www.spamhaus.org/drop/drop.lasso;
DEST=/root/droplist/drop.lasso.`date +%s`

wget $URL -O $DEST

IPT=/sbin/iptables

if [ -e $DEST ]
then
  # drop existing set of rules
  $IPT -F CHECKDROPLIST
  # add new rules
  for i in `cat $DEST | awk {'print $1'}|\
           grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]\
           {1,3}\.[0-9]{1,3}\/[0-9]{1,2}$"`
  do
      $IPT -A CHECKDROPLIST -s $i -j LOGCHECKDROPLIST
  done
fi

La regex pourrait être améliorée mais j'ai pas trop eu le temps de la paufiner (avis aux amateurs).

Je vous laisser tester ça chez vous. Au jour d'aujourd'hui, ça m'importe 158 réseaux dans la chaine CHECKDROPLIST. Je vais laisser tourner ça quelques jours puis je m'attarderais sur les stats pour voir si ya vraiment un intérêt à bloquer ces réseaux.

.

- page 1 de 18