SMailArchiver v0.4

26 janvier 2013

Il y a quelques semaines, j’avais présenté SMailArchiver, mon script de backup d’email sécurisés en python. Aujourd’hui un petit article pour les nouveautés de la nouvelle version 0.4.

Concernant les fonctionnalités, SMailArchiver permet désormais le stockage en clair si l’argument -e ou --encrypt n’est pas utilisé. Chaque email est toujours stocké individuellement pour faciliter l’incrémental mais la commande de restauration devient -r ou --restore pour plus de cohérence (précédemment -d ou --decrypt dans la version 0.3). Celle-ci se chargera de créer un seul fichier. Le format du fichier de configuration json a également légèrement été modifié en conséquence.

L’extension pour le stockage gagne également en cohérence. Un fichier anciennement nommé 42.gz.mbox deviendra désormais 42.mbox.gz.enc, ce qui indique : un email au format mbox compressé puis chiffré. Un mail non compressé et/ou non chiffré n’aura pas l’extension .gz et/ou .enc. La restauration se base sur ces extensions pour les manipulations à réaliser.

crowed

Un peu de patience, tout le monde aura sa mise à jour

Pour ceux ayant réalisé leurs backup avec la version 0.3, un script de migration a été créé pour régler le problème de changement de format. Renseignez le dossier contenant les mails (placez éventuellement le fichier de configuration dedans) ainsi que la version depuis laquelle vous arrivez (0.3 dans ce cas). Le script se chargera de renommer les fichiers et modifier le fichier de config.

$ python migrate.py -f backup_folder/ -v 0.3
Migration from 0.3 to 0.4…
1 valid config file migrated
42.gz.mbox -> 42.mbox.gz.enc

Done.

Le programme est désormais également accessible depuis github en plus de gitorious. En espérant que cela favorisera une éventuelle contribution (non ceci n’est pas du tout un appel caché).

Étant donné que je parle essentiellement de ce script sur un blog francophone, il me semblait normal de mettre les instructions en Français. Aux cotés du précédent README, se trouve maintenant un fichier LISEZMOI. Si des polyglottes me lisent, n’hésitez pas a me soumettre des traductions en Burgonde ou Klingon.

Last but not least, l’utilisation de la licence MIT. Jusqu’à présent il n’y avait pas de licence formelle ce qui était problématique pour l’utilisation du code dans d’autres programmes. Chose réglée, j’ai opté pour une licence permissive, je n’avais pas envie d’ennuyer avec les contraintes de la GPL pour un si petit bout de code, du code réutilisé est une reconnaissance en soit.

Mise à jour: le script a été mit à jour, les possibilités et commandes ont légèrement changé, lisez le README pour plus de détail ou suivez mes annonces avec le tag smailarchiver.

Faisant un peu le nettoyage dans mes boites à emails, j’ai voulu sauver tous mes vieux messages avant suppression. Cependant, je voulais un moyen de faire cela de manière automatisée (possible d’utiliser cron), incrémental (ne pas tout retélécharger à chaque fois), supportant la compression et surtout garder une certaine confidentialité (chiffrement).

J’ai trouvé des bouts de codes pour faire chaque partie séparément (ici et ici par exemple) mais pas de programme permettant de faire tout cela ensemble. A que cela ne tienne, j’ai donc créé un petit script python contentant mes besoins. Ainsi est né SMailArchiver (avec S pour Secured ou Suicide, question de point de vue) que je partage ici.

Ce petit bout de code (approchant des 400 lignes de python) permet facilement de faire des backup de plusieurs comptes emails avec toute une série d’option comme la compression des mails avant le chiffrement (une compression après le chiffrement pourrait également être utile mais est moins efficace) ou le choix d’une clef constituée uniquement de bytes aléatoires ou renforcée par un mot de passe de votre choix. Le chiffrement se fait avec AES 256 avec une signature HMAC-SHA256 histoire d’empêcher les manipulations. C’est pas Truecrypt mais ça suffit pour cacher les conversations avec votre maitresse des yeux indiscrets de madame votre femme (ou inversement).

big mess

Avant d’utiliser SMailArchiver, ma gestion des emails ressemblait à ça… et mes cheveux étaient secs et cassants.

Le programme peut recevoir les paramètres nécessaires par la console, via des arguments ou via un fichier de config (regardez le fichier d’exemple dans le dépot).

$ python smailarchiver.py 
Enter your email username: foo@bar.com
Enter your imap server: imap.bar.com
Enter your password: 
Enc key: 6MIiWqNiJ4h1qDmp5Z4OpWKRLst7eAbirWOPHIm9zqk=
Sig key: 9JmR0593CWwtnJhRWqdLHk7tXvX/h6l6A2GLKA4iVq4=
$ python smailarchiver.py --user foo@bar.com --imap imap.bar.com --passwd monkey1 --key foo@bar.com.keys --promp --compress
Enter your encryption/signature password: 
Enc salt: KNwhv7kuNs0/iCZZTUyd05IuOylzG/n2oBALj1UMJ0c=
Sig salt: A99CxfzwRbU4P4lse6eN5O+g2wethRzL4gMH7xqFkgE=
Hash: oNcX7GAyHsS+bNOT8UCYAYM/ltCmx34E9Gmmpky02AE=
$ python2 smailarchiver.py -c config.json
Enter your encryption/signature password: 
Enc salt: m87TeE9fmr5XPf7yvN0w3PYOv3ivlNKpKGp35hC+N/k=
Sig salt: 2k9Wu5HBEo7G0J0EzlglOqV0Zko1LmhfiGnxD2QEzhE=
Hash: FA3TdkhWNZqy9BjGOk2UVZ6AeqgHSrparH3ynHdvj38=
$ python2 smailarchiver.py --decrypt foo@bar.com/ --key foo@bar.com.keys --promp
Enter your encryption/signature password: 
Decrypting 16.gz.mbox
Decrypting 11.gz.mbox
Decrypting 45.gz.mbox
...

Code évidement open source que vous pouvez trouver le code sur mon dépot gitorious. C’est compatible python 2.7 et plus (python 3 c’est l’avenir !) et nécessite pycrypto (qui est compatible python 2.1 et 3.2, j’imagine même pas le bordel que ça doit être). Mes tests très scientifiques type àvuedenezçapasse montrent que le programme fonctionne mais on est jamais à une erreur prêt, n’hésitez pas à me communiquer vos idées d’améliorations ou corrections.

PS: fait amusant concernant AES 256, saviez vous que l’énergie contenue dans une supernova ne suffirait pas rien que pour énumérer les 2²⁵⁶ états possibles (calcul non compris donc). A moins de trouver une faille de sécurité, il est donc impossible, avec les notions de la physique actuelle, de faire un brute force sur une clef AES 256. Source: Applied Cryptography, Bruce Schneier (extrait en question).

Les nombreuses groupies qui visitent mon site par millions chaque jour (presque ça) ont sûrement remarqué que mart-e.be a été down pendant quelques jours, au grand désarrois de la touche F5 de leur clavier. La raison est simplement que mon blog et mes emails étaient hébergés chez Legtux, sur un serveur de online.net. Or ce week-end, Legtux ayant subit une attaque DDOS, online a eu la réaction très intelligente de bloquer le compte de Legtux. Ben oui, c’est évidement du à une mauvais gestion de la part de Legtux (alors que les solutions sont si simples -humour-). Situation désormais résolue avec une migration chez OVH (ça t’apprendra à mal traiter tes clients Online).

Bon pourquoi je vous raconte tout ça ? Parce que cet incident m’a poussé à faire quelque chose que j’aurais du faire depuis longtemps : gérer moi même mes mails (ce blog passera le cap dans un future plus ou moins proche)! J’ai prit il y a environ un an un serveur kimsufi chez OVH sur lequel j’héberge de nombreux services (XMPP, StatusNet, RSS, OpenID…), le but étant de gagner toujours plus d’indépendance, en particulier par rapport à Google. Et ce week-end, j’ai avancé d’un cran puisque j’ai configuré un beau serveur Postfix et Dovecot, le tout sans base de donnée.

Pour ceux qui aimeraient gérer eux aussi leurs emails, sachez qu’il existe énormément de méthodes. J’avais commencé en suivant la méthode de ®om (tutoriel de 2009 mais toujours valable) qui utilise également Postfix et Dovecot. Cependant, il y avait une chose qui me gênait : cette méthode était pensée pour la gestion d’un seul compte mail. On crée un utilisateur Unix, on stocke les emails dans ~/Maildir, on accède au compte mail avec ses identifiants. Je ne dis pas que cette méthode est mauvaise (elle est sans doute la meilleur si vous n’avez qu’un seul compte mail) mais je voulais quelque chose de plus souple qui me permette de gérer plusieurs noms de domaine sans devoir me rabattre sur MySQL.

Dovecot travaillant déjà de bon matin

La méthode que j’ai utilisée est assez proche de celle ®om mais utilise des adresses mail virtuelles. Tout est géré par un seul utilisateur selon une hiérarchie très simple: /home/vmail/example.com/bob pour bob@example.com, le mot de passes de bob étant géré par Dovecot dans un format similaire aux utilisateurs Unix (un fichier /etc/dovecot/passwd). Cela me permet facilement de créer des nouvelles adresses pour de nouveaux utilisateurs.

La méthode est très largement inspirée du tutoriel de ubuntu.com PostfixVirtualMailBoxClamSmtpHowto et j’ai traduite et ajoutée sur mon wiki tout neuf. Pour la marche à suivre, rendez vous donc sur wiki.mart-e.be/email. Si vous remarquez que j’ai oublié quelque chose, n’hésitez pas à me le signaler (ou contribuer, c’est un wiki après tout).

Cependant quelques limites à garder en tête en utilisant cette méthode :

  • Les mails sont stockés dans des fichiers texte lisibles par l’administrateur du serveur
  • La gestion des emails se fait par des scripts bash, pas pratique si vous voulez permettre la création de compte pour des externes (mais pas impossible)
  • Les mots de passes sont hashés mais pas salés (deux mots de passes égaux auront le même hash)

J’essayerai aussi d’ajouter la gestion du spam bientôt.

Il arrive souvent que l’on ai besoin de mettre une adresse email sur une page web. Que ce soit une grosse entreprise ou une page perso, il peut être utile de donner la possibilité aux lecteurs de nous contacter. Il est donc tentant de mettre un simple lien <a href="mailto:foo@bar.com">foo@bar.com</a>
Cependant, c’est sans compter les robots collecteurs d’emails attirés par le symbole @ tel la SABAM par une boum d’écolier. Si l’on ne veut pas se retrouver avec la boite mail remplie de courriers pour vous expliquer comment avoir un gros zizi pour 200 balles (retenez les enfants, l’amour c’est has been, c’est la taille qui importe), il vaut mieux éviter ces gens.

Il y a plusieurs techniques couramment utilisées qui sont, à mes yeux, à déconseiller :

Les mauvais exemples

foo[AT]bar.com : oui cette méthode arrêtera le robot de ma grand mère codé en Fortran (vous aimeriez avoir une grand mère qui code en Fortran hein ?) mais pas celui du mafieux russe qui fait de la collecte d’email son fond de commerce.

Il existe beaucoup de variations de cette technique qui rendent plus ou moins difficile la collecte (tel que le « REMOVETHIS » au milieu de l’adresse) mais sont aussi facilement contournables. Ça me scie à chaque fois de voir que cette technique est couramment utilisée sur les mailing lists avec des variations très simples, il suffit qu’un robot adapte un peu son algo et c’est toutes les adresses de la liste qui y passent… Un pattern assez compliqué peut être efficace mais sans doute pas très agréable pour l’utilisateur.

De plus ces emails ne sont pas cliquables et même un copier-coller nécessite un peu de retouche, pas très confortable pour les utilisateur.

L’image : l’on peut mettre l’adresse email dans une image et l’affichée sur la page. Il existe des techniques très efficaces de reconnaissance de caractère (du à la popularité des captchas) mais elles sont trop coûteuses en temps pour que le robot prenne la peine à essayer de le déchiffrer.
Cette technique est donc efficace mais très contraignante pour l’utilisateur qui ne peut ni cliquer ni faire de copier-coller et bloque les utilisateurs n’affichant pas les images (aveugles et browser en mode texte).

Le formulaire : plutôt que d’afficher l’adresse, on donne à l’utilisateur un formulaire à remplir. A cela je dis non aussi car :
– pas aussi confortable qu’un client mail
– mal construit, on peut l’utiliser comme relais pour spam (à éviter à tout prix!)
– on peut toujours vous spammer par formulaire (rhaa hors de ma vue toi avec ton captcha)

Bon maintenant qu’on a vu ce qu’il ne fallait pas faire, voici plusieurs techniques que je trouve plus intéressantes.

Pour donner un moyen de contact, je pense qu’il faut être le plus transparent possible avec la grande majorité des d’utilisateurs tout en restant possible dans les cas anormaux (un utilisateur de Lynx est un cas anormal).

HTML/CSS

Qu’est ce que la grande majorité des navigateurs comprennent : bravo le css (facile c’était marqué juste au dessus) ! Et ça tombe bien, il existe deux balises qui peuvent nous être utile :

:after : propriété pour afficher quelque chose après un élément
[cc lang= »html »].myemail:after { content: « foo40bar.com »; }
email: [/cc]
Simple et pratique mais ne fonctionne pas pour tout le monde. Une idée ? Et oui encore ce brave Internet Explorer qui ne le supporte qu’à partir de la version 8! Et évidement, marche pas du tout pour ceux sans CSS.
Remarquez aussi l’utilisation du 40 au lieu de @. Ce n’est pas infaillible mais rendra un peu plus difficile le boulot des vautours vendeurs de viagra.

direction : pas très connue (normal elle sert pas à grand chose), cette propriété permet de changer le sens d’affichage de gauche-à-droite pour de droite-à-gauche.
[cc lang= »html »].myemail { unicode-bidi:bidi-override; direction: rtl; }
moc.rab@oof[/cc]
Ça fonctionne avec Internet Explorer (alléluia) mais pose quand même 2, 3 problèmes avec ie6 si vous l’imbriquez avec d’autres propriétés (c’était trop beau).
J’aime beaucoup cette méthode car très efficace pour beaucoup de monde (à non pas ie4 déso) et même les gens qui n’affichent pas le css verront quelque chose. Bon il faut que les navigateurs texte comprennent qu’il faut inverser mais vous pouvez toujours expliquer cela dans une balise qui ne s’affichera que pour eux (en appliquant le style display:none).
Le risque que le robots inverse l’adresse n’est pas nul mais suffisamment faible.

foo<!– blabla –>@<span style="display:none;">bar.</span>com : variante de la première méthode déconseillée en cachant aux yeux de l’utilisateur certaines parties mais pas pour le robot. Le commentaire est facilement contournable pour le robot mais la deuxième partie beaucoup moins, avec un peu d’imagination on peut être paré. L’email est facilement déchiffrable pour ceux en mode texte si l’on connait un peu le html/css.

Bon par contre aucune des trois méthodes ne permet de rendre le lien cliquable

Javascript

Qu’est ce que presque autant de gens ont : le javascript! Via un petit bout de code, vous pouvez faire apparaitre dynamiquement l’adresse email.

[cc lang= »html »]

Contactez moi à activez le javascript pour lire l’adresse


[/cc]

Expliquer

Et qu’est ce que en principe tout le monde possède : un cerveau!
Pourquoi simplement ne pas expliquer comment former l’adresse email avec une phrase du style « pour me contacter, mon adresse est : foo, suivi d’un arobase, suivi de bar.com ». A varier selon votre imagination et faites le en alexandrins si possible.

C’est un peu extrême, pas très professionnel mais compréhensible par tous et si, un jour, un crawler est capable de déchiffrer ça, le spam ne sera pas votre plus gros problème.

Combiner

La technique que je considère comme la plus efficace est de mixer le tout! Du javascript pour avoir quelque chose de très compatible avec beaucoup de gens et être très confortable (lien cliquable) avec derrière du CSS et/ou du texte pour ceux qui ne supportent pas le javascript .
J’ai mis un exemple sur gitorious, n’hésitez pas a me proposer des améliorations.

Conclusion

Toutes ces méthodes sont évidement à adapter selon vos besoins et vos lecteurs, le cas d’un blog perso ou une mailing list est différent d’une entreprise. Il en existe d’autres également efficace, entre autre en travaillant coté serveur avec du php ou ajax.
Est-ce que vous éviterez tout le spam ? Bien sur que non, mais vous éviterez déjà une source…

Inspiration : Methods to hide email addresses from page source

css.php