Passons à TLS

Bien que SSL soit supplanté par son successeur TLS, il reste quand même encore utilisable car bien des serveurs le garde comme protocole au cas où un client ne supporterait pas TLS. L’enfer est pavé de bonnes intentions…. si SSLv2 est aujourd’hui considéré comme défaillant, ce n’est pas le cas de SSLv3 qui reste encore dans les bonnes grâces de la configuration de apache2 sous Debian 7. En effet dans le fichier /etc/apache2/mods-enabled/ssl.conf on trouve:

SSLProtocol all -SSLv2

Ce qui indique l’utilisation possible de  TLS et de SSLv3. Malheureusement une information parue sur le site américain NVD qui recense les vulnérabilités des logiciels, SSL est intrinsèquement vulnérable (y compris SSLv3) à l’attaque de l’homme du milieu. Cela veut dire qu’il faut absolument ne plus utiliser SSL mais son successeur TLS.

La mise en place du banissement de SSL dans nos serveurs web consiste à le supprimer de la liste des protocoles utilisables par apache. Dans le fichier ssl.conf il suffit de mettre:

SSLProtocol all -SSLv2 -SSLv3

On pourra également en profiter pour hausser si n’est déjà fait le niveau de cryptage (algorithmes utilisés) que le serveur accepte de faire. Le monde libre (et donc gratuit) ne laisse aucune excuse au client qui n’utilise pas un logiciel récent et supportant les algorithmes de chiffrement les plus sûrs. Toujours dans le fichier ssl.conf il suffit de mettre:

SSLCipherSuite HIGH:!ADH:!MD5

Développement web rapide en python

Python logo
Image via Wikipedia

Java souffre d’une lourdeur incompatible avec le prototypage d’application web. En effet nous entendons par prototypage le fait de réaliser rapidement une application qui sera dans ce cas précis en mode web. Java impose une architecture robuste mais incompatible avec un développement rapide. Il oblige ainsi à “packager” l’application dans un war déployé dans un conteneur (ex: Tomcat). Java manque tout simplement d’agilité comparé à php pour le développement web.

Pour autant php est trop orienté web et ne va pas bien s’adapter en cas de monté en puissance. En effet comment partager le code en ayant la richesse du paradigme objet ou comment faire s’exécuter du code en dehors d’un contexte web ? Ce que Java propose…

Python peut être une alternative qui présente le meilleur des 2 mondes: puissance de l’objet pour la maintenabilité, la réutilisation et la rapidité du prototypage avec un langage de script. C’est ce que mod_python propose en ajoutant au serveur apache la capacité à exécuter du code python.

Le paquet mod_python est disponible depuis le dépôt officiel de Ubuntu 10.10. Une fois installé il faut déclarer dans apache une url qui va devenir python-aware. Pour cela il suffit de se rendre dans le répertoire de configuration de apache pour y créer le fichier /etc/apache2/con.d/replay en supposant que l’on veuille faire une application web qui s’appelle replay.

Alias /replay /home/thierry/Vidéos/n900
<Location /replay>
        Order Allow,Deny
        Allow from 192.168.0.0/255.255.0.0
        AddHandler mod_python .psp .psp_ .py
        PythonHandler mod_python.psp | .psp .psp_
        PythonHandler mod_python.publisher | .py
        PythonDebug On
</Location>

Ce fichier nous permet de déclarer l’url /replay qui devient pythonique ! Les url de la forme /replay/*.psp seront servies par le moteur de page Python Server Page (équivalent des JSP) tandis que celles de la forme /replay/*.py seront exécutées comme des scriptes pythons (équivalent des servlet).
Les url de la forme /replay/*.psp_ permettent d’afficher le code source des pages .psp à côté du scripye python généré à des fins de débogage. Étant donné qu’on active le mode debug, le fichier restreint l’accès aux url au réseau local.

Python Server Page

Voici un exemple de page PSP:

<html>
<table width="100%">
<tr bgcolor="grey">
<th>Queue</th>
</tr>
<tr>
<td>
<%
# Etat du processus de conversion
%>

<table width="100%">
<tr>
<th>Fichier</th><th>Taille</th><th>Etat</th><th>Action</th>
</tr>
<%
import os
import os.path
list = os.listdir("/home/thierry/Vidéos/n900")
work_in_progress  = ""
if os.path.exists("/home/thierry/Vidéos/n900/.work_in_progress") :
  f = open("/home/thierry/Vidéos/n900/.work_in_progress", "r");
  work_in_progress = f.read()
  f.close()
for f in list:
  if f.endswith(".ts"):
    filename = unicode(f,'utf')
    is_work_in_progress = work_in_progress.rpartition('.mp4')[0].endswith(f)
    etat = "En attente"
    if is_work_in_progress :
      etat = "En cours"
%>
<%
    # ferme le bloc if
%>

<tr>
<td><%=filename.encode('ascii','xmlcharrefreplace')%></td><td><%=os.path.getsize("/home/thierry/Vidéos/n900/" + f)%></td><td><%=etat%></td>
<td>
<form action="action.py/remove_queue" method="POST">
<input type="hidden" name="file" value="<%=filename.encode('ascii','xmlcharrefreplace')%>">
<input type="submit" value="supprimer">
</form>
</td>
</tr>
<%
# ferme le bloc for
%>

</table>

</td>
</tr>
</table>
</html>

Retenons que le code python s’écrit dans la page PSP comme les scriptlet java dans les pages JSP. On est loin de l’industrialisation de J2EE, il n’y a pas de notion de taglib, c’est du rustique ! Attention à l’indentation pour que le générateur de code ferme un bloc il est nécessaire d’avoir une instruction qui de-indente i.e ferme le bloc précédent. Pour cela il faudra parfois ajouter une code vide avec la nouvelle indentation ou mieux avec un commentaire qui explique notre intention.

Scripte .py

Il s’agit des actions de l’application web pour reprendre la terminologie Struts.  Le gstionnaire mod_python.publisher va interpréter une url telle que /replay/action.py/remove_queue comme devant être traitée par la fonction remove_queue du module action.py. Les paramètres passées lors de l’appel à l’url seront passés à la fonction.

Voici un exemple de “servlet python” à placer à l’url /replay/action.py:

# -*- encoding: UTF-8 -*-
import os
import os.path
from mod_python import util

def remove_queue(req,file=None):
  list = os.listdir("/home/thierry/Vidéos/n900")
  for f in list:
    if f.endswith(".ts"):
      if file:
        if file==unicode(f,'utf').encode('ascii','xmlcharrefreplace'):
          os.remove("/home/thierry/Vidéos/n900/" + f)
      else:
        os.remove("/home/thierry/Videos/n900/" + f)

  util.redirect(req,"../queue.psp")

La fonction doit se terminer par une redirection vers une vue qui n’est autre qu’une page PSP !

Synchronisation des fichiers multimedia du N900 avec un PC

Nokia N900 communicator/internet tablet
Image via Wikipedia

Dans la catégorie des smatphones le N900 fait figure d’ovni. Il ne jouit pas d’une réputation, justifiée, de machine grand public. La synchronisation des fichiers multimédia en est un exemple. Alors que la concurrences permet une synchronisation sans effort d’une bibliothèque de chansons avec le téléphone, le N900 manque d’application user-friendly . En effet avec un Iphone, on a ITune et même à l’époque des pocket PC, Windows Media Player permettait de garder la synchronisation.

La problématique exposée ici est celle d’amener avec soi sa bibliothèque multimédia afin d’en jouir en mobilité. Le N900 est sans doute la machine la plus à même de répondre à ce besoin avec ses 27 Go disponibles. La solution de la copie plus une synchronisation par rsync satisfont parfaitement mais de nos jours la bibliothèque des fichiers que les gens ont sur leur ordinateur peut dépasser les 27 Go ! Par ailleurs, on peut avoir besoin de place sur le N900 pour d’autre choses (enregistrement vidéo etc).

Le problème est donc de synchroniser un sous ensemble de sa bibliothèque multimedia PC. Bien entendu, cette synchronisation doit être automatique.

Les logiciels pour N900 tel que MediaBox permettent la sélection manuelle des certains fichiers stockés à distance par UPnP (via MediaTomb) mais il faut soi-même supprimer les fichiers obsolètes et en choisir de nouveaux. Le grand public est fainéant.

Heureusement que la solution n’est pas compliquée et facile à implémenter. L’idée est de fournir au N900 une liste de fichiers à prendre sur le PC. Cette liste doit changer car il serait dommage d’avoir toujours les mêmes chansons  à écouter…

L’utilitaire GoMedia écrit en python offre une commande en ligne paramétrable pour générer une liste de fichier. L’exemple suivant sélectionne aléatoirement pour 10 Mo max de fichier audio pris dans le répertoire spécifié par l’option -d et génère un fichier n900_playlist:

gomusic -m 10 -d /home/thierry/Musique/ -o /home/thierry/Musique/n900_playlist

Cette commande sera planifiée par un script /etc/cron.hourly/gomusic

#!/bin/sh
gomusic -m 10 -d /home/thierry/Musique/ -o /home/thierry/Musique/n900_playlist

La fréquence choisie permet de prendre en compte les nouveaux fichiers de la bibliothèque dans l’heure qui suit une modification.

Ensuite pour rendre ce fichier accessible au N900 qui sera l’initiateur de la synchronisation, on peut le mettre sur une url web accessible uniquement depuis le réseau interne en créant le fichier /etc/apache2/conf.d/gomusic

Alias /gomusic /home/thierry/Musique
<Location /gomusic>
 Order Allow,Deny
 Allow from 192.168.0.0/255.255.0.0
</Location>

Ainsi l’url //<mon_ip>/gomusic/n900_playlist ne sera accessible que depuis l’intranet. Lorsque le N900 sera dans le réseau local il suffira de lui faire faire un wget à cette url pour obtenir une liste de fichiers de musique. Le script suivant permet par exemple de synchroniser le répertoire /home/user/MyDocs/.sound/jesus avec cette liste

#!/bin/sh
wget -O /home/user/n900_playlist -T 10 -t 1 -q //192.168.0.12/gomusic/n900_playlist;
if [ $? -ne 0 ]; 
then
 exit 1
fi
rm -r /home/user/MyDocs/.sounds/jesus;
rsync --files-from /home/user/n900_playlist 192.168.0.12::musique  /home/user/MyDocs/.sounds/jesus

L’automatisation de cette tâche peut être faite avec l’outil Alarmed pour être déclenchée par exemple tous les soirs à 23h.

Comment faire passser les gros gateaux (Big cookies) ?

Au début de ma carrière en pleine bulle internet, tout le monde autour de moi pronait la gestion des sessions web des utilisateur par le serveur. L’utilisation de cookies n’était pas une pratique en odeur de sainteté à cause des limitations imposé par le navigateur. Ainsi les framework que j’ai utilisé ou développé se contentaient de laisser le conteneur web soit poser un cookie de session (quelques octets) soit si le client n’acceptait pas de cookie de passer une paramètre d’url.

J’ai trouvé à l’époque que la spécification des session par les Servlet était amplement suffisante dans la plupart des cas et que dans certaines circonstances, s’appuyer sur les mécanisme existant quitte à les étendre par des sessions en base de données, offrait une solution robuste et fiable.

De nos jours plus personne ne développe de framework propriétaire. Donc lorsque l’on rentre sur un nouveau projet soit il utilise un framework du marché qui est alors passé indubitablement par le choix des sessions côté serveur, soit on utilise un framework propriétaire. Dans ce dernier cas vous pouvez être amené à devoir utiliser massivement les cookies.

Voici donc quelque conseille pour faire passer les gros gâteaux.

Tout d’abord il faut augmenter la taille du header http que le serveur sera capable de gérer. Dans la configuration d’apache cela se traduit par la directive LimitRequestFieldsize dans le fichier httpd.conf . Si vous utililsez tomcat il faudra ajouter une valeur plus grande que les 4096 par défaut à l’attribut maxHttpHeaderSize du connecteur HTTP. Par contre si vous utilisez un connecteur AJP pour relier un apache à un tomcat, vous devrez sans doute jouer du paramètre packetSize du connecteur AJP pour spécifier une valeur supérieur aux 8192 par défaut. Pensez alors également à modifier également le fichier workers.properties de apache pour changer la valeur due paramètre max_packet_size du worker qui pointe vers le connecteur AJP.

Voilà en somme les quelques ingrédients essentiels qui donneront du goût à votre cuisine et fairont passer les gros gateaux !