Envie partout, temps nulle part

Ça fait assez longtemps que j’ai pas posté ici, j’en suis bien conscient, et j’écris donc ce petit post pour dire que c’est le cas, pourquoi c’est le cas, et que ça va pas durer.

J’ai beaucoup de choses qui me prennent pas mal de temps en ce moment, notamment:

  • un boulot, je suis en stage
  • la rédaction d’un rapport, puisque… je suis en stage
  • la recherche d’une alternance, pour l’an prochain
  • un bon nombre de démarches administratives variées
  • insert autre raison here.

par contre, j’ai /énormément/ de choses dont j’aimerais parler, notamment:

  • de la redondance de routeurs, avec CARP, PfSync, dhcpsync et ifstated
  • du backup de confs réseau avec Oxidized
  • des mésaventures avec debian et nvidia
  • du junk hacking sur une liseuse ukrainienne
  • des backups automatisés via puppet
  • encore d’autres trucs, que j’ai oublié la comme ça mais ça va revenir

Du coup, vous inquietez pas, j’ai pas oublié ce blog, et je reviens vite.


Let's Encrypt, enfin

Vous avez peut être vu que ce blog, entre autres sites que j’administre, n’est disponible depuis quelques jours qu’en HTTPS, et avec un certificat valide. Bon, si vous êtes là, vous avez déjà entendu parler de Let’s Encrypt, mais pour les deux trois du fond on va résumer:

LE est une nouvelle autorité de certification (ceux qui valident les certificats SSL), basée sur une organisation, et dont le but est de fournir des certificats valides, automatiquement et gratuitement. Leur certificat racine est signé par IdenTrust, et est donc considéré valide par tous les navigateurs modernes.

Bon, maintenant qu’on est tous au même point, voyons comment ça marche. Depuis dix jours LE est ouvert en bêta publique, donc il n’est plus nécessaire de préciser les domaines pour lesquels on veut un certificat sur un formulaire, comme c’était le cas pendant la période de bêta fermée. Le système qui est utilisé repose sur le protocole ACME (Automatic Certificate Management Environment), qui automatise complètement la signature des certificats. Du coup, les certificats que délivre LE ne sont valides que 90 jours, ce qui serait super chiant avec une autorité de certification classique, mais qui la veut simplement dire qu’il faut mettre un cron en place.

Bref, comment mettre en place vos certificats? On va faire ça sans trop modifier vos sites, et en automatisant au maximum. LE utilise, dans son système par défaut, un fichier sur le site web, dont le serveur de certification vérifie l’existence lors de la requête (si le fichier est présent avec le bon contenu, c’est que le client tourne bien sur ce domaine, et donc que la personne qui a demandé le certificat contrôle bien le domaine). Ce fichier est situé dans un dossier dans la racine, .well-known. Plutôt que de se faire chier a gérer ce dossier pour tous nos vhosts nginx, on va simplement créer un alias vers un dossier commun sur le système de fichier, que tous les vhosts partagerons, et qui permettra aussi de valider tous les domaines pour lesquels on veut un certificat à la fois (avec un AltName) (sur un seul serveur, par contre. Enfin si vous voulez vraiment vous pouvez faire des mounts cross-serveurs (avec du sshfs ou des trucs du genre), mais c’est un peu sale quand même. Et faudra quand même distribuer le certificat après, donc bon…).

Donc, on va rajouter ça dans nos blocs server :

location /.well-known {
    alias /srv/letsencrypt/.well-known;
}

(bien sûr il faut créer le dossier, hein.)
Après, on git clone https://github.com/letsencrypt/letsencrypt, dans /opt/ ou dans /usr/local/, peu importe, on le clone quelque part, et on cd dans le dossier en question. Une fois là, on demande un certificat :

sudo ./letsencrypt-auto certonly \
    -a webroot \
    --webroot-path /srv/letsencrypt/ \
    -d <domaine> \
    -d <altName1> \
    -d <altName2> \
    --server https://acme-v01.api.letsencrypt.org/directory

Normalement, maintenant, on a un certificat valide dans /etc/letsencrypt/live/<domaine>/. Reste à configurer nginx pour qu’il serve nos sites en https en utilisant notre nouveau certificat. Perso, j’utilise une template qui ressemble à ça :

server {
    listen 80;
    listen [::]:80;
    server_name SERVERNAME;
    return 302 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    ssl_certificate /etc/letsencrypt/live/DOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/DOMAIN/privkey.pem;
    ssl_dhparam /etc/nginx/dhparams.4096;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";
    ssl_prefer_server_ciphers on;
    add_header Strict-Transport-Security "max-age=15552000; includeSubDomains; preload";

    root SERVERROOT;

    index index.html index.htm;

    server_name SERVERNAME;

    server_tokens off;
    client_max_body_size 5m;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location /.well-known {
        alias /srv/letsencrypt/.well-known;
    }

    location / {
        try_files $uri $uri/ =404;
    }
}

Alors c’est pas /tout à fait ça/ d’un point de vue parano du TLS (genre je devrais désactiver TLS 1.0 et EECDH+aRSA+RC4, notamment) mais ça marche pas trop mal et c’est plus compatible comme ça (mon telephone est sous Android 4.4, donc je suis content d’avoir encore TLS 1.0 par exemple).

Vous pouvez ajouter votre domaine à la liste préloadée dans Chrome/ium, Firefox, IE, Edge, Safari, le Tor Browser Bundle, etc…ici (oui ça fait clairement site de phishing, mais apparemment c’est serieux…)

Enfin, il nous faut un renouvellement automatique, puisque notre certificat ne sera valide que 90 jours. On va utiliser un cron tout con, avec un script :

00 01 */14 * * /usr/local/bin/cert-renew 2>&1 | mail -s "certificates renewal report" <votre email>

(oubliez pas que ça doit aller dans le crontab du root) Et le script qui va bien :

#!/bin/bash

if [[ $UID != 0 ]]; then
    echo "please run as root"
    exit 1
fi

cd /opt/letsencrypt/

git pull 2>&1 >> /dev/null


# Renewing the cert
./letsencrypt-auto certonly \
    -a webroot --webroot-path /srv/letsencrypt \
    -d <domaine> \
    -d <altName1> \
    -d <altName2> \
    --server https://acme-v01.api.letsencrypt.org/directory \
    --renew \
    2>&1

systemctl restart nginx
exit 0

Notez bien le --renew qui spécifie qu’on renouvelle le certificat, le git pull qui met à jour le client, et le systemctl restart nginx qui prend en compte le nouveau certificat automatiquement

Et puis voilà, normalement avec ça vous devriez pouvoir chopper des certificats valides. C’est plutôt cool, en pratique.

Merci Let’s Encrypt


OpenWRT, l'USBNet, et l'histoire des 4Mo

Donc, j’ai récemment obtenu un TP-Link TL-MR12U, qui est vendu comme “routeur 3G portable”, mais qui est en réalité une grosse batterie avec une antenne wifi, un port USB, et un port Ethernet. Perso, ça me va, vu que je comptais de toute façon pas prendre un deuxième abonnement 3G juste pour ce truc là (surtout vu la couverture 3G qu’on se tape en France…)

Bref, tout ça pour dire : quand j’ai reçu ce truc, j’ai tout de suite commencé par y installer OpenWRT (parce que de 1, je parle pas chinois, et de 2, j’aime bien avoir des firmwares corrects sur mes routeurs). Bon, c’est super simple, il suffit de chopper ce fichier [binaire] la, et de trouver la page d’update (pas forcément super simple en chinois, mais avec un peu de temps, ça se fait. C’est celle avec un bouton upload). Ensuite on upload l’image sur le bouzin, et c’est parti. Pas de signatures, pas de vérifications, osef total, mais bon pour le coup ça m’arrange.

Une fois ceci fait, je me trouva bien démuni de ne pas pouvoir utiliser le partage de connexion USB de mon intelliphone android, car l’image OpenWRT par defaut ne comprend pas USBNet, et ne peut donc pas créer de réseau sur de l’USB. Qu’à cela ne tienne, me dis-je! Je vais l’installer! Je courra donc installer le package grâce à opkg. Las! Le système n’avait plus de place.

… Atta. Le système avait plus de place? J’ai encore rien mis dessus!

Eh bah ouais. Il se trouve que TP-Link, en 2015, trouve que 4Mo de flash sur un routeur, c’est largement suffisant, et que de toute façon personne aura jamais besoin de plus.

Serieux, mettre 8Mo c’était tellement plus cher? u_u

Bon, bref, je vais pas m’étendre la dessus. J’ai décidé de saisir mes petits bras, et de tenter de pousser bien fort pour convaincre OpenWRT qu’il était tout a fait possible de faire rentrer à la fois le système de base avec LuCi, uhttpd, un serveur DHCP, etc; et USBNet, dans 4Mo. Ça à pas été vraiment facile, et j’ai du virer pas mal de trucs, mais… ça fonctionne!

Bon, alors, comme je suis quelqu’un de sympa, je vais vous filer à la fois le fichier de config et l’image finale. Si vous voulez pas utiliser une image qui vient d’un mec que vous connaissez pas, vous pouvez toujours la rebuilder vous même. Mais avant ça, je vais vite fait expliquer ce qui est dans l’image et ce qui n’y est pas

Alors, pour faire rentrer tout ça, vous vous doutez que j’ai du faire quelques concessions. J’ai donc viré tout ce qui a trait à PPP, PPPoE, le client DHCPv6, tous les outils de debug, quelques fonctionnalités de busybox, et bien sûr opkg. Dans ce qui à été ajouté, simplement ce qui est nécessaire au fonctionnement de l’USBNet.

Une petite modification doit être effectuée pour que le tout fonctionne : le fichier package/feeds/luci/luci/Makefile doit être modifié pour que la dépendance sur luci-proto-ppp ne soit plus présente. Ainsi, on passe de

LUCI_DEPENDS:= \
    +uhttpd +uhttpd-mod-ubus +luci-mod-admin-full +luci-theme-bootstrap \
    +luci-app-firewall +luci-proto-ppp +libiwinfo-lua +IPV6:luci-proto-ipv6

à

LUCI_DEPENDS:= \
    +uhttpd +uhttpd-mod-ubus +luci-mod-admin-full +luci-theme-bootstrap \
    +luci-app-firewall +libiwinfo-lua +IPV6:luci-proto-ipv6

Une fois que c’est fait, ça devrait mieux marcher (et ça sauve un peu d’espace…)

Bon. Le fichier de config est , l’image finale est , et j’ai une petite surprise.

Bien sûr, le switch situé sur le côté du TL-MR12U ne fonctionne pas sous OpenWRT de base, parce que c’est un truc lié au hardware et que du coup c’est assez compliqué à gérer sur une base de matos aussi grande que celle d’OpenWRT. Bah j’ai à peu près trouvé comment le faire fonctionner. Voilà le code :

#!/bin/sh
if [ $ACTION == "released" ]; then
    if [ $BUTTON == "BTN_0" ]; then
        # Position is 3G
        logger "slider 3G"
    elif [ $BUTTON == "BTN_1" ]; then
        # Position is Router
        logger "slider Router"
    fi
elif [ $BUTTON == "BTN_1" ] || [ $BUTTON == "BTN_0" ]; then
    if grep -qe "sw1.*in  hi" /sys/kernel/debug/gpio\
    && grep -qe "sw2.*in  hi" /sys/kernel/debug/gpio; then
        # Position is AP
        logger "slider AP"
    fi
fi

Et ça va dans /etc/hotplug.d/button/00-buttons (créez le chemin, il existera pas à la base). Du coup là comme ça ça fait rien, ça loggue juste les events. Mais comme vous êtes pas cons vous avez peut être deviné qu’on pouvait très bien activer l’USBNet que quand l’interrupteur est en position 3G, le wifi et l’ethernet quand il est en position AP, et juste la batterie quand il est en position Router. Par exemple.

Tiens, d’ailleurs. Pour activer le partage de connexion, suffit pas d’ajouter le support USBNet. Il faut aussi configurer le système pour qu’il demande un lease DHCP, toussa. Du coup vous pouvez (peut être, j’ai pas testé) le faire par LuCi, mais sinon vous pouvez le faire en CLI :

uci del network.wan
uci set network.wan=interface
uci set network.wan.ifname=usb0
uci set network.wan.proto=dhcp
uci commit network
ifup wan

Et pouf, ça marche.

Voilà. Amusez vous bien avec votre grosse batterie portable, qui fait maintenant point d’accès wifi/partage de connexion 3G/whatever.


les NUCs et le HDMI-CEC

J’ai récemment récupéré une télé. Ce post ne se centrant pas sur cette télé, passons rapidement sur ce qui y est lié : ne souhaitant pas “profiter” du paysage audiovisuel français (ou PAF), et ayant nombre de films et séries acquis tout a fait légalement (hmm hmm) stockés sur mon serveur local, je souhaitais brancher sur ma télévision un système me permettant de regarder ces films et séries, et possiblement quelques sources de vidéos en ligne (Youtube, Netflix, etc…) simplement.

Ayant un Raspberry Pi 1 qui trainait, j’ai décidé d’installer OpenELEC dessus et de voir ce que ça donnait. Le résultat n’étant pas satisfaisant (a cause des difficultés du RPi a faire fonctionner tout ça), j’ai décidé d’upgrader le système.

J’ai donc acquis un NUC D34010WYK (attention, les nouveaux modèles ne fonctionnent pas pour ce qui suit), un adaptateur HDMI-CEC pour celui-ci, et un SSD mSATA, en me disant que je pourrais sans trop de problème faire tourner Kodi sur un debian, avec en plus Steam pour faire du streaming depuis mon desktop. L’autre avantage de tourner sur du Intel, c’est de pouvoir mater Netflix (puisque le plugin kodi approprié utilise chrome, et ne fonctionne (a ma connaissance) que sur x86).

J’ai donc reçu après un certain temps le matériel sus cité, que j’ai avidement monté, avant de me rendre compte que le manuel de l’adaptateur Pulse-Eight était [PDF]assez médiocre. J’ai donc cherché plusieurs heures, avant de trouver [DE]ce post expliquant comment brancher l’adaptateur. Je vais donc résumer ici le processus, ce qui devrait rendre la tache a la fois plus simple pour les autres personnes cherchant l’information, et pour moi si je dois remonter ce système.

Pour faire simple, le NUC présente trois headers séparés : un dual-USB, un dit “Front Panel”, et un appelé “Custom Solution Header”. Les trois sont utilisés ici. La première chose a faire est de brancher les fiches grises et rouges sur le Custom Solution Header: le branchement doit être fait ainsi :

Custom Solution
  ┌─┬─┬─┬─┬─┐
  │g│ │·│r│·│
  ├─┼─┼─┼─┼─┤
  │·│·│·│·│·│
  └─┴─┴─┴─┴─┘

  g ➔ fiche grise
  r ➔ fiche rouge
  · ➔ pin inutilisé
    ➔ espace vide (sans pin)

Une fois cela fait, il faut brancher le Front Panel. Heureusement, c’est plus facile, puisqu’il n’y a qu’une seule fiche a brancher ici : la orange.

  Front Panel
  ┌─┬─┬─┬─┬─┐
  │·│·│·│·│·│
  ├─┼─┼─┼─┼─┤
  │ │·│o│·│·│
  └─┴─┴─┴─┴─┘

  o ➔ fiche orange
  · ➔ pin inutilisé
    ➔ espace vide (sans pin)

Enfin, il faut encore brancher les fiches restantes sur le header dual-USB. Étant donné que ce header contient deux fois les pins nécessaires a un branchement USB, il est possible de brancher les cables de plusieurs façons.

   Dual-USB
  ┌─┬─┬─┬─┬─┐
  │b│B│v│n│·│
  ├─┼─┼─┼─┼─┤
  │·│·│·│·│ │
  └─┴─┴─┴─┴─┘

  b ➔ fiche bleue
  B ➔ fiche Blanche
  v ➔ fiche verte
  n ➔ fiche noire
  · ➔ pin inutilisé
    ➔ espace vide (sans pin)

Tous les branchements étant effectués, il faut maintenant remonter la bête (attention a ne pas déranger les branchements avec les antennes Wifi, par exemple), la brancher, et vérifier que tout démarre bien. Il faut aussi changer un paramètre dans le BIOS intel : dans Power➔Secondary Power Settings, il faut que “Deep S4/S5” soit désactivé. Ceci permettant a la connection HDMI-CEC de démarrer et le NUC.

Ne reste plus ensuite qu’a installer un système digne de ce nom dessus!


SSL - STARTTLS

Le chiffrement SSL pour les services en ligne est un problème relativement récent, par rapport a l’histoire d’Internet. Sa mise en place pose problème : les protocoles existants ne s’accommodent qu’assez mal de recevoir soudainement un flot de données chiffrées, mais développer de nouveaux protocoles est complexe et n’apporte rien d’intéressant. Pour palier a ce problème, deux solutions sont apparues.

Le première consiste à faire écouter les services sur un autre port, dans un tunnel SSL. De cette façon, le service existant écoute normalement, mais il ne répond pas directement aux requêtes. A la place, un tunnel SSL est mis en place, et les requêtes et les réponses passent dans le tunnel (ou elles apparaissent donc chiffrées pour l’extérieur). Cela permet de proposer un service chiffré en modifiant de façon minimale le programme, au prix de devoir aussi changer tous les clients, et de devoir les orienter sur un autre port.

L’autre approche qui a été utilisée est une approche d’upgrade. La communication commence en mode non chiffré, puis le client demande l’upgrade de la connexion vers le mode chiffré s’il le supporte, les deux machines machines font un handshake SSL et la communication continue a travers le tunnel SSL. Le service peut continuer a écouter sur son port habituel, et seuls les clients capables de passer en SSL le feront, ce qui permet de faire la “mise a jour” en douceur.

Il est souvent demandé quelle est la meilleure méthode pour mettre en place un service – laisser un port pour le SSL et un pour le trafic non chiffré, ou bien un seul, avec STARTTLS, qui upgrade les connexions si nécessaire.
La réponse est que STARTTLS est plus interessant, pour plusieurs raisons. Tout d’abord, il permet de n’utiliser qu’un seul port : ça permet de simplifier la configuration du firewall. En plus de ça, il permet aux clients “anciens” (ceux qui ne supportent pas SSL, donc ceux qui devraient être changés) de toujours se connecter, même si cela signifie que leurs informations seront transmises en clair. Surtout, il permet d’éviter aux utilisateurs d’avoir a configurer leurs clients. Si le client supporte le chiffrement, il l’activera de lui même s’il voit qu’il est disponible.
Bref, mettez en place du STARTTLS, et pas du SSL. C’est mieux pour la sécurité de tout le monde.


Manettes : Hori vs. PDP

Si vous avez comme moi une Wii U et Smash 4, vous vous êtes probablement rendus
compte de quelques petits trucs : tout d’abord, Smash est bien plus drôle
a plusieurs. Ensuite, la Wii U peut être contrôlée avec énormément de “choses”
sans trop réflechir, il y a le Wii U Gamepad, les Wiimotes, les Pro Controllers pour Wii et Wii U, et d’autres. Vous aurez aussi remarqué que le Gamepad n’est pas du tout un moyen de jouer a Smash acceptable, ni les wiimotes. Les pro controllers fonctionnent, mais ne valent pas les bonnes vieilles manettes Gamecube.

Cela étant, si comme moi vous avez, euh, “ouvert” le mode vWii de votre Wii U, vous avez surement un disque dur/une clé USB connecté au dos de votre Wii U, et donc pas assez de ports libres pour connecter l’adaptateur GC pour Wii U a votre console.

Heureusement pour vous, Nintendo a pensé a une solution (et comme d’habitude avec Nintendo, c’est une solution a moitié satisfaisante…) : les classic controller, mais en forme de manettes Gamecube.

Nintendo a donc filé ses licences et ses designs a deux boites, qui se sont empressées de faire des manettes et de ramasser des brouettes d’argent, en faisant des manettes Gamecube qui se connectent a des Wiimotes.

Nous allons ici voir deux modèles, un de chacune des boites en question
PDP et Hori.

Toutes les photos présentes dans cet article sont disponibles en plus grande taille en cliquant dessus

Commençons par le modèle de chez Hori :

Hori_face

Comme vous pouvez le voir, la manette ressemble beaucoup a une véritable manette de Gamecube : a part le bouton Turbo et le bouton Home, le reste est parfaitement identique a une véritable manette Gamecube. A noter que les boutons centraux (Home, Start, Select, et Turbo) sont en caoutchouc mou et pas en plastique dur.

Hori_dos

Nous voyons déjà le premier gros problème de cette manette : les gâchettes ne sont en réalité que des boutons : c’est logique puisque c’est comme ça que les classic controller sont faits, mais c’est décevant tout de même

Hori_CM

On peut voir ici que la qualité de l’assemblage n’est pas extraordinaire, et on remarque une soudure mal faite a l’emplacement du stick gauche.

Hori_Cstick

Le stick c n’est pas fixé au reste de la manette. J’ai essayé de démonter plus avant les différentes parties de la manette, mais les câbles n’avaient pas l’air de très bonne qualité, et j’ai préféré abandonner l’idée plutôt que de casser la manette.

Hori_coque

On peut voir que la coque est complètement vide, et que les gâchettes sont bien en réalité de simple boutons. Il y aurait presque la place de mettre la carte mère d’une Wiimote entière la dedans…


Passons maintenant a la manette PDP.

PDP_face

Au premier coup d’œil, on remarque que la manette PDP ressemble beaucoup moins a une manette gamecube. Cependant, la prise en main est exactement la même. On regrettera tout de même les sticks, pas aussi agréables que ceux de la Gamecube, et les boutons transparents (mais c’est un problème de goût).

PDP_dos

Les gâchettes sont des vraies gâchettes! C’est impossible normalement, mais PDP a été très intelligent sur le coup, comme on va le voir juste après.

PDP_CM

Comme vous pouvez le voir, la qualité générale est bien meilleure, avec bien moins de colle, et pas de soudage raté. Toutes les cartes filles sont bien attachées a la carte mère, et la structure en plastique est renforcée. Mais surtout, on peut voir deux cartes filles qui sortent de façon étrange de la carte mère, de façon péremptoire perpendiculaire…

PDP_CF

Vous l’avez deviné, ces deux “cartes filles” servent en réalité de connecteurs aux boutons situés sur les gâchettes, qui sont de “vraies” gâchettes en cela qu’elles sont faites de la même manière que les vraies (avec un ressort, etc) mais qui sont en réalité des boutons (évidemment, puisque cette manette est en fait un classic controller), par opposition aux véritables gâchettes analogiques.

Quelques photos des gâchettes en question :

PDP_G_1

PDP_G_2

PDP_G_3

PDP_G_4


Vous l’aurez compris, je préfère la version PDP de ces “Fight Pad”, la finition semble plus solide, les gâchettes sont parfaites, les boutons centraux ne sont pas en caoutchouc cheap, et bien que les sticks soient moins confortables, le reste est parfait. Si vous préférez avoir une manette dont la prise en mains esttotalement identique a celle des manettes Gamecube, cependant, la version Hori vous conviendra probablement mieux, a part les gâchettes, malheureusement.


Docker et les ebooks sur Twitter

Date Sat 28 February 2015
By Wxcafe
Category Note

Vous avez peut être déjà entendu parler de Docker. Si ce n’est pas le cas, voila les bases : Docker est un système de containers. Les containers sont une forme particulière de virtualisation, ou le kernel n’est pas virtualisé, mais ou les processus du système hôte sont séparés de ceux des systèmes invités. Cela est possible depuis longtemps sous FreeBSD avec les Jails, mais n’est devenu possible sous linux que récemment grâce aux cgroups, qui permettent justement de séparer des groupes de processus. Le principe de Docker est donc d’avoir une machine hôte sur laquelle s’exécutent plusieurs conteneurs Dockers, chacun séparé des autres et de l’hôte, mais utilisant tous le même kernel. Cela pose quelques questions en terme de sécurités, puisque la séparation est bien plus fine qu’avec de la virtualisation classique. En effet, ici, en trouvant un exploit kernel, un attaquant aurait potentiellement la capacité de remonter jusqu’à l’hôte, puisqu’il n’est pas vraiment séparé des invités.

Quoi qu’il en soit, Docker permet donc de virtualiser a moindre coût des systèmes GNU/Linux. “Mais pourquoi utiliser Docker, dans ce cas”, vous demandez-vous peut être, “puisque Xen peut faire la même chose, et plus (notamment, Xen est capable de virtualiser autre chose que GNU/Linux)?”. Et bien c’est très simple : Docker apporte la simplicité de déploiement d’applications. Les conteneurs Dockers peuvent être décrit en un fichier, nommé Dockerfile, qui permet de répliquer un conteneur en quelques minutes sur un autre hôte, en une commande. Le Docker Hub permet aussi de récupérer rapidement et facilement un grand nombre d’images déjà configurées.

Maintenant que nous avons expliqué rapidement ce qu’était Docker, voyons le rapport avec les ebooks et Twitter.

Les comptes dits “ebooks” (le nom vient a l’origine de horse_ebooks, voir ici pourquoi) sont des bots twitter utilisant des Chaines de Markov, avec les tweets d’un utilisateur “source” comme corpus, pour produire des tweets ressemblant a ceux de l’utilisateur source. Nous allons voir maintenant comment en installer un.

C’est, comme disent certaines personnes, “fun”.

Il existe de nombreuses librairies écrites pour créer ce genre de bots, cependant dans ce cas nous nous concentrerons sur celle-ci, qui est une lib ruby créée par @m1sp, qui gère pour nous a la fois l’API twitter et la génération des messages.

Cependant, cela n’explique toujours pas le lien avec Docker. Ce lien est très simple : nous utilisons un container pour faire tourner les bots. Depuis la version 3, la gem twitter_ebooks permet de faire tourner plusieurs bots dans une seule instance. Cependant, il est toujours plus sûr d’isoler les bots, et les containers dockers permettent de les déployer sur n’importe quelle machine (celleux qui ont déjà tenté de mettre en place une application basée sur ruby sauront le problème que cela pose habituellement). Pour ce faire, j’ai créé un repo github qui contient toutes les pièces nécessaires pour mettre cela en place : le bot en lui même, les deux Dockerfiles, etc.

Le fonctionnement du bot est simple : après avoir installé la gem twitter_ebooks, vous archivez le corpus de l’utilisateur source avec ebooks archive <username> <filename> (c’est du json) , puis vous convertissez le json en fichier utilisable par le bot : ebooks consume <filename>. Cela fait, démarrer le bot revient a lancer le container : docker run -d <container name> Pour plus d’informations, allez voir la documentation Docker

Bien entendu, dans l’idéal il faudrait mettre a jour les corpus de chaque utilisateur régulièrement. Cela est très simple a mettre en place avec un simple script cron :

00 00 * * *    /usr/local/bin/ebooks archive username /usr/local/ebooks/main/corpus/username.json >> /var/log/ebooks/update.log 2>&1
00 05 * * *    cd /usr/local/ebooks/main/ && /usr/local/bin/ebooks consume corpus/username.json >> /var/log/ebooks/update.log 2>&1
00 10 * * *    docker rm -f bots >/dev/null 2>&1
00 15 * * *    docker rmi bots  > /dev/null 2>&1
00 20 * * *    cd /usr/local/ebooks/main/ && docker build --rm -t bots . >> /var/log/ebooks/build.log 2>&1
00 25 * * *    docker run -d --name bots bots >> /var/log/ebooks/run.log 2>&1

Les 5 minutes entre chaque commande sont laissées pour empécher que deux commandes ne s’executent en même temps.

Et voila, vous avez un container Docker qui fait tourner une application en ruby toute sale, et votre système hôte reste propre. Bien sûr, ce n’est qu’un exemple des possibilités de Docker : par exemple, on peut aussi faire tourner des applications “usuelles” dedans, puisque l’overhead de Docker est minimal, et beaucoup d’autres applications existent.


OpenSMTPd comme serveur mail sous debian

J’avais dit il y a un certain temps que j’allais écrire un tutoriel expliquant comment gérer ses mails soi-même. Il se trouve que j’ai récemment décidé de changer le serveur qui héberge (entre autres) ce blog, et que ce dernier héberge aussi mes emails. J’ai donc totalement changé d’infrastructure quand a la gestion de mon système de mails.

Ainsi, j’ai décidé de passer de Postfix a OpenSMTPd, changement que je voulais effectuer depuis un certain temps. OpenSMTPd est un projet originaire d’OpenBSD qui a pour but de fournir un serveur SMTP fiable, simple, rapide, et surtout sécurisé (les même buts que ceux qu’a le projet OpenBSD, globalement).

Pour rappel, le système d’emails fonctionne d’une façon très simple : votre MUA (Mail User Agent, ou client email) contacte le MTA (Mail Transport Agent, ou serveur SMTP) de votre fournisseur email, qui contacte le MTA du fournisseur du destinataire, qui lui même contacte le MDA (Mail Delivery Agent) qui délivre le mail au destinataire.

Si vous avez bien suivi, vous pouvez voir que je n’ai pas parlé de récupération ni de lecture des mails. C’est pour une raison simple, qui est que ces taches sont remplies par d’autres services encore (IMAP/POP pour la récupération depuis le serveur, des yeux pour la lecture).

Or ce qui nous intéresse ici, ce n’est pas simplement d’envoyer et de recevoir des emails mais bien aussi de pouvoir les récupérer et les lire, et c’est pour ça que ce tutoriel ne parlera pas que d’OpenSMTPd mais aussi de Dovecot qui fait office de serveur IMAP et amavis/spamassassin pour filtrer les mails entrants et sortants. Le schéma suivant explique la façon dont les mails sont gérés sur le système

            ╭────────────────╮                    ╭──────────╮
            │╭──────────────>│────> to filter ───>│─╮        │
  mail in   ││               │                    │ │ amavis │
───────────>│╯ OpenSMTPd  ╭──│<─── from filter<───│<╯        │
            │             │  │                    ╰──────────╯
  mail out  │             │  │                    ╭──────────╮
<───────────│<────────────┴─>│─────> to MDA ─────>│─────────>│──> to user's
            │                │                    │ dovecot  │     mailbox
            ╰────────────────╯                    ╰──────────╯

Normalement, ceci devrait être a peu près clair. Pour expliquer vite fait, les emails entrants (venant des utilisateurs mais aussi d’autres correspondants) sont transmis a OpenSMTPd, qui envoie tout aamavis, qui vérifie a la fois les spams et les malwares pour les mails venants de l’exterieur, et qui signe avec DKIM pour les mails venants de nos utilisateurs, puis qui rentransmet les mails filtrés/signés a OpenSMTPd, qui a ce moment-ci trie en fonction de la destination : les mails gérés par le domaine vont via dovecot dans les boites mail des destinataires locaux, les mails exterieurs vont directement vers le MTA du serveur distant.

Voyons comment mettre cela en place. Tout d’abord, il faut décider de la façon dont les différents services vont communiquer.

Déjà, amavis étant configuré par défaut pour écouter (en SMTP) sur le port 10024 et répondre sur le port 10025 quand il s’agit de filtrer et écouter sur le port 10026 et répondre sur le port 10027 quand il s’agit de signer, nous allons profiter de cette configuration et donc lui parler en SMTP sur ces ports.

Quand a Dovecot, nous allons lui transmettre les emails en LMTP (Local Mail Transfer Protocol), non pas sur un port mais via un socket (dans ce cas précis, /var/run/dovecot/lmtp).

Ainsi, pour reprendre le schéma présenté plus haut :

            ╭───────────────╮                    ╭───────────╮
            │╭─────────────>│──> SMTP (10026) ──>│─╮         │
  SMTP in   ││              │                    │ │ amavis  │
────────> 25│╯ OpenSMTPd ╭──│<── SMTP (10027) <──│<╯ (sign)  │
            │            │  │                    ╰───────────╯
  SMTP out  │            │  │
25 <────────│<───────────╯  │
            ╰───────────────╯

Pour les mails sortants; et

            ╭───────────────╮                    ╭────────────╮
            │╭─────────────>│──> SMTP (10024) ──>│─╮          │
  SMTP in   ││              │                    │ │ amavis   │
────────> 25│╯ OpenSMTPd ╭──│<── SMTP (10025) <──│<╯(filter)  │
            │            │  │                    ╰────────────╯
            │            │  │                    ╭────────────╮
            │            ╰─>│──> LMTP (socket) ─>│───────────>│──> to user's
            │               │                    │  dovecot   │     mailbox
            ╰───────────────╯                    ╰────────────╯

Pour les mails entrants.

Maintenant que la théorie est claire, mettons en place tout cela. Je me baserai ici sur le fait que vous utilisiez une plateforme Debian ou OpenBSD. Pour d’autres plateformes, la configuration devrait être sensiblement la même

(Vous aurez besoin de certificats SSL pour ce guide, même auto-signés. Si vous ne savez pas comment en créer, vous pouvez aller voir ce post)

Tout d’abord, commençons par installer les programmes nécessaires :

sudo apt-get install opensmtpd dovecot dovecot-pigeonhole amavisd-new dovecot-managesieved
sudo pkg_add dovecot dovecot-pigeonhole amavisd-new

Continuons en configurant OpenSMTPd tel que nous avons vu plus haut :

/etc/smtpd.conf

# This is the smtpd server system-wide configuration file.
# See smtpd.conf(5) for more information.

## Certs
pki exem.pl certificate "/etc/certs/exem.pl.crt"
pki exem.pl key         "/etc/certs/exem.pl.key"

## Ports to listen on, and how to listen on them
listen on eth0 port 25 tls pki exem.pl hostname exem.pl auth-optional
listen on eth0 port 465 tls-require pki exem.pl hostname exem.pl auth mask-source
listen on eth0 port 587 tls-require pki exem.pl hostname exem.pl auth mask-source

## Aliases
table aliases file:/etc/aliases

# coming from amavisd, checked for spam/malware
listen on lo port 10025 tag Filtered
# coming from amavisd, signed with DKIM
listen on lo port 10027 tag Signed

## Receiving
# if the (incoming) mail has been through amavisd, then we can deliver it
accept tagged Filtered for any alias <aliases> deliver to lmtp "/var/run/dovecot/lmtp"
# we directly tranfer incoming mail to amavisd to be checked 
accept from any for domain "exem.pl" relay via "smtp://localhost:10024"
# we have to put these lines in this order to avoid infinite loops

## Sending
# if the (outgoint) mail has been through amavisd, then we can deliver it
accept tagged Signed for any relay
# we tranfer the outgoing mail to amavisd to be signed
accept for any relay via "smtp://localhost:10026"
# same, we have to put these lines in this order or infinite loops...

Expliquons un peu ce fichier de configuration :

  • Tout d’abord, le paragraphe nommé “Certs” contient les déclaration d’emplacement des certificats SSL.
  • Ensuite, le paragraphe contenant les ports externes sur lesquels nous écoutons : port 25 avec TLS optionel et ports 465 et 587 avec TLS obligatoire
  • Les alias sont définis juste après
  • Le paragraphe suivant contient les ports locaux sur lesquels nous écoutons : 10025 (port de sortie du filtre de amavis) dont on taggue les mails sortants comme “Filtered” et 10027 (port de sortie des mails signés par amavis) dont on taggue les mails sortants comme “Signed”
  • Nous avons ensuite le paragraphe qui traite les mails rentrants. Si le mail traité est taggué comme Filtered, alors il a été vérifié par amavis, et on peut donc le transmettre au destinataire. Sinon, c’est qu’il n’a pas encore été vérifié par amavis, donc on lui transmet pour analyse (sur le port 10024 donc). Il est important de mettre les déclarations dans ce sens, car la première règle qui matche l’état du paquet est appliquée. Ici, la deuxième ligne matchant tous les mails arrivant et la première seulement ceux filtrés, inverser leur sens voudrait dire que les mails seraient toujours renvoyés a amavis
  • Enfin, le dernier paragraphe traite les mails sortants. De la même façon que pour le paragraphe précédent, si le mail sortant est déjà taggué comme Signed on le transmet au MTA du destinataire, sinon il n’a pas encore été signé par DKIM par amavis et on le transmet donc a amavis pour qu’il le signe. Le problème de l’ordre des lignes se pose encore, pour la même raison qu’au dessus.

Nous allons maintenant configurer dovecot. Comme nous l’avons vu, dovecot doit écouter en LMTP via la socket /var/run/dovecot/lmtp et transmettre les emails a la boite email de l’utilisateur. Il serait aussi interessant qu’il nous permette de récuperer les mails. Pour cette configuration, on ne mettra en place que du IMAPS. Cependant, si vous voulez mettre en place du POP3[s], différents guides sont trouvables facilement sur internet.

/etc/dovecot/dovecot.conf

## Dovecot configuration file

# basic config
info_log_path = /var/log/dovecot-info.log
log_path = /var/log/dovecot.log
log_timestamp = "%Y-%m-%d %H:%M:%S "
mail_location = maildir:%h/mail

# authentication
passdb {
    driver = pam
}
userdb {
    driver = passwd
}

# the protocols we use
protocols = imap lmtp sieve

# ssl config
ssl_cert = </etc/certs/exem.pl.cert
ssl_key = </etc/certs/exem.pl.key
ssl_cipher_list = HIGH+kEDH:HIGH+kEECDH:HIGH:!PSK:!SRP:!3DES:!aNULL
ssl = yes

## configuring services 
# disables imap login without SSL (yes dovecot is dumb that way)
service imap-login {
    inet_listener imap {
        port=0 
    }
}

service lmtp {
    unix_listener lmtp {
        mode = 0666
    }
}

## configuring protocols
# the dovecot lda, we set it to use sieve
protocol lda {
    mail_plugins = $mail_plugins sieve
}

protocol lmtp {
    postmaster_address =  whoever@exem.pl
    mail_plugins = $mail_plugins sieve
}

plugin {
    sieve = ~/.dovecot.sieve
    sieve_dir = ~/sieve
}

ATTENTION: Sous OpenBSD, remplacez

passdb {
    driver = pam
}

par

passdb {
    driver = bsdauth
}

pour identifier les utilisateurs système

Ici aussi, voyons comment ce fichier est structuré :

  • Tout d’abord, les configurations de base : ou iront les logs, comment formater leur datation, et l’endroit ou seront stockés les mails des utilisateurs.
  • Nous configurons ensuite la gestion de l’authentification des utilisateurs. Ici nous identifions les utilisateurs avec le fichier /etc/passwd et leurs mots de passe avec PAM (ou BSDAuth)
  • Nous configurons ensuite les protocoles que nous servons. Ici, nous voulons de l’IMAPS, du LMTP local et Sieve (qui sert pour trier les messages).
  • Nous configurons le SSL
  • Le section suivante contient la configuration des services. Nous avons en premier lieu le service IMAP, dont la configuration sert uniquement a désactiver IMAP. En effet, dovecot ne permet d’activer IMAPS qu’en activant IMAP avec. Comme nous ne voulons pas d’IMAP sans SSL, nous le désactivons. La configuration de lmtp sert a attribuer des permissions plus correctes au fifo qu’il utilise
  • Nous configurons maintenant les protocoles, pour faire fonctionner Sieve
  • enfin, nous configurons le plugin sieve en lui indiquant quel fichier et quel dossier utiliser pour sa configuration.

Enfin, il nous reste a configurer amavis. Comme expliqué, amavis va nous servir a deux choses : signer les emails sortants, et filtrer les emails entrants. Il doit donc écouter sur les port 10026 pour les signatures et 10024 pour le filtrage, et répondre respectivement sur les ports 10027 et 10025 (le tout, en SMTP. Comme toutes les transactions se font sur le loopback, il n’y a aucun risque a utiliser des protocoles non chiffrés. Pour OpenBSD, pensez a copier la configuration par défaut depuis/usr/local/share/examples/amavisd-new/amavisd.conf et ajoutez les modifications nécessaires a la fin du fichier.

/etc/amavis/conf.d/99-local.conf (debian) /etc/amavis.conf (OpenBSD)

use strict;

$enable_dkim_verification = 1;
$enable_dkim_signing = 1;
dkim_key("exem.pl", "main", "/etc/certs/dkim.key" );

@dkim_signature_options_bysender_maps = (
    { '.' =>
        { ttl => 21*24*3600, c => 'relaxed/simple' }
    }
);

$inet_socket_port = [10024, 10026];
$policy_bank{'MYNETS'} = {
        originating => 1,
        os_fingerprint_method => undef,
};

$interface_policy{'10026'} = 'ORIGINATING';

$policy_bank{'ORIGINATING'} = {
        originating => 1,
        allow_disclaimers => 1,
        virus_admin_maps => ["root\@$mydomain"],
        spam_admin_maps => ["root\@$mydomain"],
        warnbadhsender => 1,
        forward_method => 'smtp:localhost:10027',
        smtpd_discard_ehlo_keywords => ['8BITMIME'],
        bypass_banned_checks_maps => [1],
        terminate_dsn_on_notify_success => 0,
};

#------------ Do not modify anything below this line -------------
1;  # ensure a defined return

A nouveau, expliquons ce fichier : - le premier paragraphe définit que nous voulons qu’amavis signe les emails sortants, vérifie la signature DKIM des emails rentrants, et l’endroit ou se trouve la clé privée servant a signer les emails. - le second définit les options DKIM que nous souhaitons utiliser comme défaut. Je vous invite a consulter la RFC 4871 - nous définissons ensuite les ports sur lesquels nous allons écouter, puis les paramètres que nous utiliserons pour les emails venant de nos utilisateurs : ils seront traités comme “originating” et nous ne vérifierons pas l’OS duquel ils viennent. - nous savons que les emails venants du port 10026 sont sortants, nous les traitons donc comme tel - le paragraphe suivant décrit le traitement que nous faisons subir aux emails sortants : tout d’abord, nous réaffirmons qu’ils viennent bien de notre serveur. Nous autorisons les disclaimers (voire encore une fois la RFC 4871. Nous déclarons l’adresse a prévenir en cas de spam/virus venants de notre système, et que nous voulons être prévenus. Nous déclarons ou envoyer les mails une fois signés et filtrés, puis qu’il est nécessaire de convertir les emails au format 7 bits avant de les envoyer au MTA, que nous autorisons tous les types et noms de fichiers, et les notifications de succès d’envoi. Et voila!

Vous avez pu remarquer qu’a aucun moment nous ne configurions ni la signature des emails sortants ni le filtrage des emails entrants. Ces paramètres sont en fait inclus par défaut dans amavis.

Il nous reste cependant quelques opérations a faire, encore. Tout d’abord, il nous faut générer notre clé DKIM. Pour cela, il existe différentes méthodes, j’ai personnellement utilisé opendkim (un tutorial) mais de nombreuses autre méthodes existent. Il nous reste encore a configurer spamassassin :

#rewrite_header Subject *****SPAM*****
# report_safe 1
required_score 2.0
# use_bayes 1
# bayes_auto_learn 1
# bayes_ignore_header X-Bogosity
# bayes_ignore_header X-Spam-Flag
# bayes_ignore_header X-Spam-Status
ifplugin Mail::SpamAssassin::Plugin::Shortcircuit
# shortcircuit USER_IN_WHITELIST       on
# shortcircuit USER_IN_DEF_WHITELIST   on
# shortcircuit USER_IN_ALL_SPAM_TO     on
# shortcircuit SUBJECT_IN_WHITELIST    on
# shortcircuit USER_IN_BLACKLIST       on
# shortcircuit USER_IN_BLACKLIST_TO    on
# shortcircuit SUBJECT_IN_BLACKLIST    on
shortcircuit ALL_TRUSTED             off
# shortcircuit BAYES_99                spam
# shortcircuit BAYES_00                ham

endif # Mail::SpamAssassin::Plugin::Shortcircuit

Comme vous pouvez le voir, les modifications se résument globalement a baisser le required_score pour ma part.

Pour finir, activez les services nécessaires : opensmtpd, dovecot, amavisd, et spamassassin, et tout devrait fonctionner parfaitement

Bon courage pour votre hosting de mail ensuite…


Installer FreeBSD sur un serveur Online avec MfsBSD

J’ai récemment eu l’occasion de louer un serveur chez Online.net (filiale de Illiad) Voulant depuis pas mal de temps gérer un serveur sous FreeBSD (et tester bhyve) et n’ayant pour différentes raisons pas eu l’occasion de le faire sur mon serveur auto-hebergé ni sur ce serveur ci, j’ai commencé a chercher comment le faire sur ce serveur.

Étant donné que Online ne propose pas directement d’image FreeBSD sur ses serveurs, il m’a fallu chercher un peu plus loin. Il se trouve que ce post sur les forums d’online explique une procédure, mais celle-ci ne fonctionnait pas pour mon serveur en particulier.

J’ai donc cherché un peu sur internet, puis demandé sur irc (#freebsd-fr@freenode), ou l’on m’a dirigé vers mfsbsd, un projet d’installeur alternatif, minimaliste et simplifié pour FreeBSD.

Pour installer FreeBSD sur votre serveur, donc, il vous faudra accéder a une console KVM (dans mon cas personnel, iLO). Cela doit être faisable depuis le panel Online. Une fois cela fait, lancez une console, puis téléchargez l’image mfsbsd. Dans la console iLO, choisissez de booter sur une image CD/DVD, puis choisissez l’image mfsbsd. Ensuite, rebootez le serveur. Choisissez de booter sur l’image CD/DVD (F11 puis 1). Une fois ceci fait, un FreeBSD a l’air tout a fait classique va démarrer. Une fois ceci fait, la partie importante arrive: mfsbsd contient un script d’installation root-on-zfs, nommé logiquement zfsinstall, qui va se charger de tout le travail pour nous.

Utilisez donc ce script ainsi :

# tout d'abord, wipons le MBR :
dd < /dev/zero > /dev/da0 count=1
# maintenant, installons le système
zfsinstall -g da0 -u ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/10.0-RELEASE/ -s 2G -p root -c

Avec -g da0 votre disque dur principal, -s 2G la quantité de swap désirée, -p root le nom du zpool, et -c pour activer la compression. D’autres options sont disponibles, je vous invite a faire un zfsinstall -h si mon setup ne vous convient pas.

Une fois ceci fait, faites un chroot dans /mnt (ou doit se trouver le nouveau système) et éditez /etc/rc.conf :

zfs_load="YES"
sshd_load="YES
hostname="whatever"
ifconfig_igb0="DHCP"

Remplacez whatever par votre hostname, et igb0 par le nom de votre interface physique connectée a internet. Quittez le chroot, rebootez, et voila, vous avez maintenant un système FreeBSD tout propre installé sur zfs a découvrir et utiliser!

Voila, c’est la fin de ce tutoriel. (Cela dit, bon courage pour tester bhyve, vu que l’IPv6 chez online est… peu crédible, disons)

Bon sinon sur d’autres sujets, j’ai mis en place des bots twitter : wxcafe_ebooks, petitefanfare, capet_ebooks, zengisse, et kim_ebooks. Ils sont tous basés sur ce code, qui vient de @m1sp (github.com/twitter_ebooks). Donc voila.

A plus


SSL ou la sécurité sur l'internet

Disclaimer: Ce billet est écrit après le visionnage de la conférence de Moxie Marlinspike suivante: More Tricks for Defeating SSL, présentée a la DefCon 17 (en 2011), et la lecture du billet suivant: A Critique of Lavabit, ce qui peut avoir l’effet de rendre légèrement parano. Si vous considérez que c’est le cas ici, veuillez ne pas tenir compte de ce billet (et vous pouvez dès a présent dire coucou aux différentes personnes qui écoutent votre connection)

Si vous venez ici souvent (vous devriez), et que vous utilisez SSL pour vous connecter a ce site (vous devriez, vraiment, dans ce cas), vous avez peut être remarqué quelque chose récemment : il se trouve que le certificat qui permet de desservir ce site a changé.

Cela fait suite aux évènements évoqués dans le Disclaimer, mais aussi a des doigts sortis d’un endroit particulier du corps de l’admin/auteur de ce “blog”, qui a pris enfin les 5 minutes nécessaires a la compréhension superficielle du fonctionnement de SSL, et les 10 nécessaires a la mise en place d’un système fonctionnel utilisant cette compréhension récemment acquise.

Bref, le certificat a changé. Mais de quelle façon, vous demandez vous peut être (ou pas, mais bon, je vais expliquer de toute façon). Et bien c’est très simple : il existait auparavant un certificat pour wxcafe.net, un pour paste.wxcafe.net, un pour mail.wxcafe.net, etc… Bref, un certificat différent pour chaque sous-domaine.

Il s’avère que c’est a la fois très peu pratique a utiliser (les utilisateurs doivent ajouter chaque certificat a leur navigateur séparément, chaque changement de sous-domaine conduit a un message d’erreur, etc) et pas plus sécurisé que d’avoir un seul certificat wildcard. J’ai donc généré un certificat pour *.wxcafe.net hier, et il sera dorénavant utilisé pour tous les sous-domaine de wxcafe.net; et un certificat pour wxcafe.net, qui ne matche pas *.wxcafe.net, et qui sera donc utilisé… bah pour wxcafe.net.

Il serait préférable de faire des redirections automatiques des adresses http vers les adresses https, cependant, étant donné que le certificat est self-signed, il me semble préférable que l’arrivée sur le site ne commence pas par une page firefox disant “Something’s Wrong!”, et ces redirections ne seront donc pas mises en place.

De plus, après la lecture de l’article de blog sur Lavabit dont le lien est plus haut, il semble intéressant (et assez important) de faire en sorte que le serveur utilise en priorité (et si possible, uniquement) des ciphers supportant PFS, soit EDH et EECDH (Ephemeral Diffie-Helmann et la version Elliptic Curves de ce même algorithme). Cela permet de faire en sorte que toutes les communications avec ce serveur soient future-proof, c’est a dire que, même si quelqu’un récupérait la clé privée, elle ne serait pas utile pour déchiffrer les communications passées.

Bon, maintenant que les explications basiques sont faites, voyons l’implémentation :
Pour générer la clé, tout d’abord, il convient d’utiliser les commandes suivantes:

sudo openssl genrsa -out example.key 4096
# nous utilisons ici une clé de 4096 bits, la taille est laissée a votre appréciation
sudo openssl req -new -key example.key -out example.csr
# OpenSSL va ici vous demander de nombreuses informations, "Common Name" devant contenir le FQDN
sudo openssl X509 -req -days 1095 -in example.csr -signkey example.key -out example.crt
# enfin, nous générons la clé, d'une durée de vie de 3 ans

Bien entendu, si vous voulez utiliser une clé wildcard, il vous faut préciser *.example.com comme common name. Une fois la clé générée, il faut dire aux différents services de l’utiliser, et de n’utiliser que des ciphers PFS. La méthode dépend donc du service. Je vais lister ici les methodes pour quelques services que j’utilise :

apache :

# /etc/apache2/mods_enabled/ssl.conf
# [...]
SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 \
  EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 \
  EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"
# [...]
# /etc/apache2/sites-enabled/default-ssl
# [...]
SSLEngine on
SSLCertificateFile /etc/certs/example.com.crt
SSLCertificateKeyFile /etc/certs/example.com.key
# [...]

nginx :

# /etc/nginx/nginx.conf 
# [...]
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 \
  EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 \
  EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";
# [...]
# /etc/nginx/sites-enabled/default-ssl
# [...]
ssl on;
ssl_certificate /etc/certs/example.com.crt
ssl_certificate_key /etc/certs/example.com.key
# [...]

prosody (jabber) :

# tout d'abord, lancez la commande suivante :
sudo openssl dhparam -out /etc/prosody/certs/dh-2048.pem 2048
# ensuite, pour chaque VirtualHost dans /etc/prosody/prosody.conf :
ssl = {
  dhparam = "/etc/prosody/certs/dh-2048.pem";
  key = "/etc/certs/example.com.key";
  certificate = "/etc/certs/example.com.crt";
}
# la cipher suite de prosody utilise par défaut EDH et EECDH

postfix (email) :

# /etc/postfix/main.cf
# [...]
smtpd_tls_cert_file = /etc/certs/example.com.crt
smtpd_tls_key_file = /etc/certs/example.com.key
tls_preempt_cipherlist = yes
smtpd_tls_eecdh_grade = strong
smtdp_tls_mandatory_ciphers = high
smtpd_tls_mandatory_exclude_ciphers = aNULL, eNULL, MD5, LOW, 3DES, EXP, PSK, SRP, DSS
smtpd_tls_security_level = encrypt
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
smtpd_use_tls = yes
# [...]

dovecot (imap) :

# /etc/dovecot/dovecot.conf 
# [...]
ssl_cert = </etc/certs/example.com.crt
ssl_key = </etc/certs/example.com.key
ssl_cipher_list = HIGH+kEDH:HIGH+kEECDH:HIGH:!PSK:!SRP:!3DES:!aNULL

Voila. Pour d’autres protocoles/services, je vous invite a RTFM^W vous reporter au manuel approprié.

Cela étant dit, je conseille a tout le monde d’aller voir la conférence dans le disclaimer, et tant qu’a faire la conférence du même hacker SSL and the future of Authenticity qui parle de son implémentation d’une technologie “remplaçant” le système de CAs qui existe actuellement.