• chevron_right

      Cryptocat, ou le piège du client magique

      Timothée Jaussoin · Wednesday, 6 April, 2016 - 19:35 edit · 6 minutes

    Il y a quelques jours je suis tombé sur un article annonçant la sortie de la nouvelle mouture du client de messagerie sécurisé Cryptocat. Je ne m'étais jamais réellement penché sur ce client car il faisait, selon moi, partie des dizaines d'autres clients surfant sur la vague des messageries instantanées chiffrées sorties suite aux révélations d'E.Snowden. J'ai donc voulu creuser un peu et voir de quoi il était composé.

    Comme vous le savez peut-être, je travaille moi-même sur un client de messagerie "sociale" appelée Movim exploitant le protocole XMPP. J'essaye, au travers de ce projet, de montrer aux gens qu'il est parfaitement possible de créer une solution à la fois sécurisée, standard et décentralisée tout en offrant une interface agréable et simple à comprendre. Petite précision toutefois: Movim ne possède pas (encore, mais j'y travaille) de fonctionnalité de chiffrement de bout en bout. Néanmoins il est possible de faire ce genre de chiffrement sur XMPP de façon standard et compatible avec des technologies standardisées comme OTR et le récent OMEMO (c'est d'ailleurs cette norme que j'ai décidé d'implémenter dans Movim).

    La chose que je trouve dommage avec tous ces services et clients c'est qu'ils ne sont pas compatibles entre eux. Pourtant il existe aujourd'hui plusieurs clients XMPP proposant la norme OTR et OMEMO mais qui ne sont malheureusement pas si connus et médiatisés que les autres. Je mentionnerais en particulier l'excellent Conversations (sur Android) dont l'équipe est à l'origine de la norme OMEMO (qui est elle-même une implémentation de la norme Axolotl dans XMPP, notamment utilisée sur le client Signal).

    Étant un peu curieux par nature je me suis plongé dans le code source de la nouvelle version de ce cher Cryptocat pour regarder un peu ce qu'il a dans le ventre.

    Ni une, ni deux, je clone le dépôt sur ma machine et je commence à explorer le code.

    Première surprise !

    Avant même d'ouvrir le moindre fichier j'avais déjà un petit sourire en coin en voyant le nom de certains d'entre eux dans le répertoire src/js/.

    axolotl.js
    omemo.js
    xmpp.js
    

    Tiens, tiens, tiens. Un petit tour sur la page Security du site me confirme bien ça. Cryptocat utilise XMPP comme transport et OMEMO comme méthode de chiffrement. Le reste du blabla n'est rien d'autre qu'une réexplication de la norme Axolotl sans pour autant la mentionner.

    Donc Cryptocat est un client XMPP, en Javascript, avec la norme OMEMO par dessus.

    XMPP…

    Je ne me suis pas particulièrement penché sur la partie chiffrement du projet, j'avoue ne pas avoir assez de compétences en cryptographie pour offrir une critique constructive et je pense que l'auteur du projet est bien plus expérimenté que moi là dessus. Je salue par ailleurs sa volonté de transparence à ce propos. Néanmoins je commence à bien connaitre le protocole XMPP et je sais que son point fort est la possibilité d'interconnecter les serveurs entre eux et de laisser le choix du serveur à utiliser aux utilisateurs.

    L'interconnexion est une fonctionnalité que j'estime nécessaire car d'une part, elle permet aux utilisateurs d'avoir le choix du serveur sur lequel ils iront déposer leurs données et d'autre part, elle décentralise les points d'échange du réseau (et rend ainsi plus difficile la censure et l'écoute du réseau).

    Après avoir regardé plus en détails le fichier xmpp.js j'ai enfin la confirmation de ce dont je me doutais jusque là.

    jid: username + '@crypto.cat',
    server: 'crypto.cat',
    

    Oui, il y a bien un serveur XMPP écrit en dur dans le code source du projet.

    Explorons un petit peu le serveur crypto.cat

    Le site XMPP IM Observatory nous retourne une note de A pour la sécurité du serveur, ici rien à dire. Par contre je découvre que l'interconnexion avec les autres serveurs du réseau n'est pas autorisée. La connexion entre le client Javascript et le serveur se fait au moyen d'un Websocket et le serveur XMPP est un serveur Prosody tout bête.

    Cryptocat n'est donc pas qu'une application de chat offerte par Nadim Kobeissi, mais aussi un service centralisé auquel les utilisateurs sont contraints de se connecter (sauf s'ils changent le code source du client, ce qui est possible, mais combien le feront ?).

    Précisions sur le chiffrement de bout en bout dans XMPP

    Le chiffrement de bout en bout est une très grande avancée dans l'anonymisation des données échangées. Néanmoins il ne permet pas tout. Sur XMPP par exemple il faut savoir que OTR et OMEMO ne chiffrent que le contenu des messages et pas la signalisation qui les accompagne (certains diront les métadonnées). Mais que pouvons nous trouver dans ces métadonnées ? Et bien l'identifiant de l'émetteur et du destinataire du message mais aussi beaucoup d'autres choses pouvant êtres sensibles. Une page sur le Wiki de Reporters Sans Frontieres résume plutôt bien tout ça. Ces informations peuvent être conservées dans des historiques et journaux sur les serveurs XMPP.

    En choisissant de centraliser son service sur un seul et unique serveur (qui semble être hébergé dans le datacenter d'OVH à Roubaix) l'auteur de Cryptocat a aussi fait le choix de concentrer l'intégralité du trafic de sa plateforme sur un seul et unique point du réseau Internet.

    Cela me serait égal si toutes ces informations étaient précisées sur le site du projet, au moins de façon temporaire si l'objectif à terme était de permettre la connexion à d'autres serveurs XMPP. Mais je trouve vraiment dommage qu'il ait tu ces informations.

    Petit bonus, qu'en est-il de la v1 de Cryptocat ?

    Même si je salue le fait d'utiliser des normes comme XMPP et OMEMO dans Cryptocat, j'ai quand même jeté un œil à la première version du projet pour voir sur quelle architecture il s'était basé.

    Sans grande surprise la première version se base également sur XMPP et OTR. Néanmoins elle permettait de changer le serveur XMPP sur lequel le client se connectait. J'espère donc qu'il sera également possible de faire la même chose sur la seconde version.

    Pas de quoi s'inquiéter donc ?

    Oui, pour le moment pas de quoi crier au scandale mais je souhaiterais que Nadim soit aussi transparent sur l'architecture de son projet que sur les méthodes de chiffrement qu'il utilise au sein de son application.

    Je pense qu'il est aussi important d'informer les utilisateurs de comment sont protégées leurs messages mais aussi par où et comment ceux-ci sont acheminés.

    Dernière petite question, pourquoi vouloir à tout prix fermer la plateforme alors que XMPP permet nativement l'interconnexion avec les autres réseaux ?

    En bref, si vous voulez avoir les mêmes fonctionnalités que Cryptocat, plus tous les avantages de XMPP (interconnexion, gestion de l'historique, profiles, notifications, accusés de réception…) tournez vous vers des clients comme Conversations ou Gajim (et bientôt Movim concernant le chiffrement je vous promet !).

    That's all folks !

    • Ha chevron_right

      Édito #6 : This was a triumph

      raspbeguy · pubsub.gugod.fr / hashtagueule · Tuesday, 15 March, 2016 - 23:00 · 1 minute

    Aujourd'hui est un jour important : nous avons officiellement enfin fini la migration de tous nos services vers Marvin. Ce qui veut dire que nous allons dire adieu à GLaDOS. GLaDOS a été notre serveur pendant presque 6 mois. D'aucuns dirons que 6 mois ne représentent pas un grand intervalle de temps...

    Aujourd'hui est un jour important : nous avons officiellement enfin fini la migration de tous nos services vers Marvin. Ce qui veut dire que nous allons dire adieu à GLaDOS.

    GLaDOS a été notre serveur pendant presque 6 mois. D'aucuns dirons que 6 mois ne représentent pas un grand intervalle de temps pour un serveur. Et bien figurez-vous que ces 6 mois ont été, et seront probablement les mois les plus déterminants, tant pour le blog et l'établissement de son régime de croisière que pour l'épanouissement de ses chroniqueurs. D'ailleurs, cette migration en est le symbole : nous avons tellement appris, fait tellement d'expériences, ajouté tellement de services à notre cher serveur que nous avons dépassé ses limites de performances.

    GLaDOS a été notre premier serveur à nous. C'est grâce à lui que nous avons acquis nos habitudes et forgé notre volonté. C'est donc non sans une certaine pointe de tristesse que nous quittons ce partenaire, et c'est pourquoi nous tenions à lui rendre ce petit hommage.

    Mon cœur s'emplit de nostalgie et d'émotion lorsque je me remémore ce générique de fin, dernier message de notre ancien serveur.

    Ne vous inquiétez pas, le meilleur reste devant nous, nous continuerons notre combat pour vous et avec vous.

    Restez à l'écoute, séchez vos larmes, et restez gentils.

    • At chevron_right

      Édito #6 : This was a triumph

      raspbeguy · pubsub.gugod.fr / atomtest · Tuesday, 15 March, 2016 - 23:00 · 1 minute

    Aujourd'hui est un jour important : nous avons officiellement enfin fini la migration de tous nos services vers Marvin. Ce qui veut dire que nous allons dire adieu à GLaDOS. GLaDOS a été notre serveur pendant presque 6 mois. D'aucuns dirons que 6 mois ne représentent pas un grand intervalle de temps...

    Aujourd'hui est un jour important : nous avons officiellement enfin fini la migration de tous nos services vers Marvin. Ce qui veut dire que nous allons dire adieu à GLaDOS.

    GLaDOS a été notre serveur pendant presque 6 mois. D'aucuns dirons que 6 mois ne représentent pas un grand intervalle de temps pour un serveur. Et bien figurez-vous que ces 6 mois ont été, et seront probablement les mois les plus déterminants, tant pour le blog et l'établissement de son régime de croisière que pour l'épanouissement de ses chroniqueurs. D'ailleurs, cette migration en est le symbole : nous avons tellement appris, fait tellement d'expériences, ajouté tellement de services à notre cher serveur que nous avons dépassé ses limites de performances.

    GLaDOS a été notre premier serveur à nous. C'est grâce à lui que nous avons acquis nos habitudes et forgé notre volonté. C'est donc non sans une certaine pointe de tristesse que nous quittons ce partenaire, et c'est pourquoi nous tenions à lui rendre ce petit hommage.

    Mon cœur s'emplit de nostalgie et d'émotion lorsque je me remémore ce générique de fin, dernier message de notre ancien serveur.

    Ne vous inquiétez pas, le meilleur reste devant nous, nous continuerons notre combat pour vous et avec vous.

    Restez à l'écoute, séchez vos larmes, et restez gentils.

    • Ha chevron_right

      Sécuriser ses sites web avec Let's Encrypt

      raspbeguy · pubsub.gugod.fr / hashtagueule · Friday, 1 January, 2016 - 23:00 · 10 minutes

    Bonjour à tous ! Nous allons débuter l'année avec un tutoriel sur la prise en main de Let's Encrypt, l'autorité de certification censée révolutionner l'usage de la technologie SSL par sa facilité d'usage, et qui doit permettre à Madame Michu de sécuriser son petit blog de cuisine traditionnelle en t...

    Bonjour à tous ! Nous allons débuter l'année avec un tutoriel sur la prise en main de Let's Encrypt, l'autorité de certification censée révolutionner l'usage de la technologie SSL par sa facilité d'usage, et qui doit permettre à Madame Michu de sécuriser son petit blog de cuisine traditionnelle en toute simplicité et sans avoir besoin de faire perdre une après-midi à son petit neveux du côté de sa belle-mère, qui se trouve être administrateur système, afin qu'il lui répète une quinzaine de fois les étapes de création et de validation d'un certificat en bonne et due forme. Ah, la famille...

    Mais tout d’abord, je vous souhaite à tous une bonne année 211 - 25 ! Au niveau personnel, je vous souhaite tout le bonheur que vous méritez, tant sur le plan professionnel/scolaire qu'avec votre famille/amis/béguin divers. Instruisez-vous, soyez curieux, incitez vos proches à la sagesse, et bien sûr, restez vous-même gentils.

    Au niveau citoyen, je souhaite comme toujours une prise de conscience collective sur cette cage en or qu'est devenue aujourd'hui la vie sur les internets, et une plus grande sagesse de nos têtes décideuses (à défaut d'être pensantes) à propos de la réalité numérique, qu'elles n'ont toujours pas bien intégrée.


    Enfin, revenons à notre tutoriel. Au cours du mois dernier, vous l'avez peut-être remarqué, le certificat de notre blog (ainsi que les certificats de nos services internes, mais ça c'est nos oignons) ont changé d'autorité de certification. Nous sommes passés d'un certificat Gandi, offert avec notre nom de domaine, à un certificat Let's Encrypt, grâce à l'ouverture de ce service en bêta publique. Pourquoi avons-nous changé ? Et bien, d'abord, depuis le temps que nous vous en parlions, il aurait été ironique que nous n'utilisions pas le système Let's Encrypt. Ensuite, cette manière de procéder n'est pas sans avantages pour un administrateur système, principalement pour les raisons suivantes :

    • Gain de temps global, même pour la première utilisation ;
    • Possibilité de créer un seul certificat pour plusieurs domaines ;
    • Automatisation très poussée des différentes étapes, permettant l'écriture de scripts pour les renouvèlements.

    J'avoue qu'avant la bêta publique et la possibilité de mettre vraiment les mains dans le cambouis, je n'avais aucune idée du fonctionnement, même basique, de ce service. Je n'ai même jamais personnellement manifesté d'attirance particulière envers les technologies de sécurité. En fait, son fonctionnement théorique est très simple, et permet même, à mon sens, de se rendre bien compte du processus de certification SSL dans sa globalité.

    Principe de la vérification d'identité

    Lors de la création d'un certificat, on doit suivre un protocole invariant de l'autorité de certification :

    1. On crée une clef secrète (ou on utilise une clef générée antérieurement).
    2. À partir de cette clef secrète, on génère une demande de certification (contenant une clef publique et des informations sur l'identité de l'entité à certifier).
    3. On soumet cette demande à l'autorité de certification désirée, qui génère et signe un certificat, ce qui dit aux outils des utilisateurs de votre service qu'il s'agit bien de vous, car il fait confiance à l'autorité de certification.

    Les deux premières étapes sont instantanées ; cependant, la dernière étape prends traditionnellement plus de temps, car l'autorité de certification doit s'assurer de l'identité du domaine qu'elle doit certifier. Chez les autorités classiques, il s'agit souvent de fournir des pièces d'identités, ou de répondre à un mail auquel seul le possesseur du domaine peut accéder (du type admin@example.com).

    Let's Encrypt prends en charge ces 3 étapes (il faut reconnaitre que c'est très facile d'automatiser les 2 premières) en passant par un utilitaire chargé de communiquer avec le serveur de son autorité de certification.

    Schéma

    Processus de vérification d'identité

    1. Une fois la clef et la demande de certificat générées, l'exécutable local communique au serveur http un code de vérification à rendre accessible par le serveur de certification.
    2. L'utilitaire demande à l'autorité de certification de procéder à une vérification d'identité en envoyant la demande de certificat et lui communique le code servi par le serveur http à tester.
    3. Le serveur de certification accède au serveur http en utilisant le système DNS
    4. L'autorité de certification accepte l'identité et transfert le certificat.
    5. L'utilitaire met le certificat généré à disposition des services de l’utilisateur.

    Ainsi, le processus de création du certificat ne prends en tout et pour tout que quelques dizaines de secondes. Cependant, par cette méthode, on est contraint de mettre en service, au moins temporairement, un service web pour chaque domaine à tester, ce qui est gênant pour des domaines qui ne sont pas destinés à pointer sur un site web.

    Configurer son serveur web

    Let's Encrypt met à disposition des "extensions" lui permettant de communiquer tout seul au serveur web les informations pour l'étape de la vérification d'identité. Cependant, j'utilise Nginx, et à ce jour seul Apache dispose d'une extension stable. Il existe une extension expérimentale pour Nginx mais je n'ai pas su m'en servir convenablement, ou alors j'ai eu la flemme de comprendre comment elle marchait. De toute façon, selon les retours utilisateurs et les forums, la méthode générique (dite du webroot) est la plus utilisée, c'est donc celle qui sera présentée, et vous verrez, ce ne sera pas bien compliqué.

    Tout d'abord, il faut définir le dossier qui sera mis à disposition par le serveur web. Par exemple, pour pouvez créer et choisir l'emplacement /var/www/webrootauth.

    Vous devez ensuite modifier la configuration de chaque domaine que vous souhaitez faire certifier. Vous avez le droit à 100 domaines couverts par votre certificat, vous avez donc de la marge, et vous auriez tort de vous priver. Sous Nginx, vous devez ajouter au sein de chaque server block :

    location ~ ^/.well-known/acme-challenge(/.*)?$ {
        root /var/www/webrootauth;
        default_type text/plain;
    }

    Sans oublier de recharger Nginx :

    service nginx restart

    ou bien, selon votre distribution Linux :

    systemctl restart nginx

    Pour information, cela demande à Nginx de servir le contenu de /var/www/webrootauth à l'adresse http://example.com/.well-known/acme-challenge/, adresse qui sela utilisée par l'autorité de certification.

    Installer l'utilitaire

    EDIT : C'était prévisible, maintenant quelques distributions intègrent Let's Encrypt dans leurs dépôts. Cette méthode est donc à privilégier par rapport à la méthode ci dessous.

    Il faut maintenant télécharger l'exécutable mis à disposition par Let's Encrypt. Pour cela, vous allez avoir besoin de Git, veillez donc à ce qu'il soit installé sur votre machine.

    Devenez super-utilisateur :

    sudo su -

    Puis clonez le dépôt du projet :

    git clone https://github.com/letsencrypt/letsencrypt /root/letsencrypt

    Configurer Let's Encrypt

    Il est possible d'exécuter Let's Encrypt à la sauvage sans fichier de configuration, uniquement avec des paramètres long comme mon bras. Il est néanmoins plus propre d'écrire son fichier de configuration, cela donne des scripts plus propres et un historique bash plus clair. Et comme ça vous n'avez pas des tonnes de lignes de commandes à retenir en cas de perte de vos scripts :)

    Un fichier de configuration Lets Encrypt ressemble à ceci :

    rsa-key-size = 4096
    server = https://acme-v01.api.letsencrypt.org/directory
    email = votreadresse@domaine.truc
    authenticator = webroot
    webroot-path = /var/www/webrootauth
    text = True
    renew-by-default = True
    agree-tos = True
    domains = hashtagueule.fr,mail.hashtagueule.fr,wiki.hashtagueule.fr,mysql.hashtagueule.fr,znc.hashtagueule.fr,ttrss.hashtagueule.fr

    Petite explication :

    • rsa-key-size : la taille de la clef, on l'a mis au maximum, parce qu'on est des gros bourrins. Sachez que la génération d'une clef 4096 bits prends plus de temps, mais elle n'est générée qu'à la première exécution.
    • server : l'adresse du serveur de certification. Ça ne sert à rien de le changer.
    • email : l'adresse e-mail de votre compte Let's Encrypt (s'il n'existe pas, il sera créé automatiquement, pas d’inquiétude).
    • authenticator : la méthode de vérification d'identité, on a dit qu'on choisissait la méthode webroot.
    • webroot-path : doit correspondre au chemin choisi précédemment.
    • text : indique que l'on souhaite exécuter l'outil en lignes de commandes, pratique pour les scripts et permet de tout exécuter sans intéraction (un mode pseudo-graphique existe mais n'est pas pratique).
    • renew-by-default : indique que les certificats existants doivent être renouvelés.
    • agree-tos : indique que vous acceptez la paperasse lié à l'utilisation des certificats, à lire quelque part sur leur site, mais bon, rien de bien méchant.
    • domains : là, vous devez indiquer tous les domaines que doit couvrir le certificat qui va être généré, séparés par une virgule.

    Vous placerez ce fichier quelque part d'accessible. Par exemple, vous pouvez le placer dans /root/le-config/cli.ini.

    Générer ponctuellement le certificat

    Tout est en place pour la génération de votre premier certificat, la tension monte, je vous sens tout excité. Allez, lancez-vous, en voiture Simone. Pour générer votre certificat, en tant que super-utilisateur, exécutez la commande suivante :

    /root/letsencrypt/letsencrypt-auto certonly --config /root/le-config/cli.ini

    Laissez mijoter quelques instants. La première fois, des dépendances nécessaires vont s'installer, il va configurer deux trois trucs, et finalement faire le boulot.

    Normalement, à la fin, vous allez avoir un message vous félicitant du succès de l'opération. Bravo, vous avez un certificat Let's Encrypt :)

    Vous pourrez ensuite configurer votre serveur web pour utiliser ce certificat. Sous Nginx, vous préciserez dans vos server blocks :

    listen 443;
    listen [::]:443;
    ssl on;
    ssl_certificate /etc/letsencrypt/live/hashtagueule.fr/fullchain.pem;
    ssl_certificate\_key /etc/letsencrypt/live/hashtagueule.fr/privkey.pem;

    Bien sûr, vous remplacerez hashtagueule.fr par le nom de votre domaine principal. Vérifiez en regardant le nom du dossier à cet emplacement.

    Vous pouvez ensuite recharger Nginx, et si tout ce passe bien, vous avez un site sécurisé Let's Encrypt.

    Renouvellement automatique

    Les certificats générés par Let's Encrypt ont une validité de 90 jours. C'est court, et c'est un fil à la patte de devoir tous les 3 mois demander un renouvellement de certificat. Heureusement, il y a Cron.

    Cron est un service sur votre machine qui va se charger d'exécuter des tâches à intervalle régulier. Tous ce que vous avez à faire, c'est d'écrire un script à fournir à cron. Ce script ressemblera à ça :

    #!/bin/bash
    
    la_cert_dir=/etc/letsencrypt/live/hashtagueule.fr
    
    /root/letsencrypt/letsencrypt-auto certonly --config /root/le-config/cli.ini 1> /dev/null
    
    # nginx
    service nginx reload
    
    # Vous pouvez également scripter les opération à suivre
    # pour d'autres services, par exemple votre serveur mail.
    
    # Envoi d'un mail de notification à l'administrateur
    mail -a "From: Agent de certification Hashtagueule <letsencrypt@hashtagueule.fr>" -a "Content-Type: text/plain; charset=UTF-8" -s "Renouvellement des certificats" votreadresse@domaine.truc << EOF
    Bonjour,
    
    Le certificat des services Hashtagueule a été renouvelé et couvre actuellement les domaines suivants :
    
    $(openssl x509 -in /etc/letsencrypt/live/hashtagueule.fr/cert.pem -noout -text | grep DNS | sed 's/, /\n/g' | cut -d: -f2)
    
    Dates de validité :
    
    $(openssl x509 -in /etc/letsencrypt/live/hashtagueule.fr/cert.pem -dates -noout | cut -d= -f2)
    
    Pour rappel, les certificats délivrés par Let's Encrypt ont toujours une validité de 3 mois. Tâchez donc de définir une période de renouvellement inférieure à cette durée.
    Il est à noter également que l'autorité Let's Encrypt ne délivre qu'un maximum de 5 certificats pour le même domaine par semaine. Renouvelez donc avec précaution.
    
    Bonne journée.
    EOF

    Ce script va renouveler le certificat et vous envoyer un mail de notification comportant les nouvelles dates de validité et les domaines concernés. Classe, non ?

    Il vous reste à rendre ce script exécutable et à le placer dans /etc/cron.monthly afin de l'exécuter tous les mois.

    Limitations

    Comme indiqué précédemment, les domaines à certifier doivent être servis par un serveur web, au moins pour la durée de la vérification d'identité.

    D'autre part, évitez de générer trop de certificats, car vous êtes limités à 5 renouvèlements par semaine. En régime permanent ça ne pose pas de problème, mais je me suis déjà fait avoir lors de mes tests...

    Voilà, j'espère que ce tutoriel vous aura été utile, et j'espère aussi voir fleurir une multitude de sites sécurisés.

    Désormais, vous n'avez plus aucune excuse.

    • At chevron_right

      Sécuriser ses sites web avec Let's Encrypt

      raspbeguy · pubsub.gugod.fr / atomtest · Friday, 1 January, 2016 - 23:00 · 10 minutes

    Bonjour à tous ! Nous allons débuter l'année avec un tutoriel sur la prise en main de Let's Encrypt, l'autorité de certification censée révolutionner l'usage de la technologie SSL par sa facilité d'usage, et qui doit permettre à Madame Michu de sécuriser son petit blog de cuisine traditionnelle en t...

    Bonjour à tous ! Nous allons débuter l'année avec un tutoriel sur la prise en main de Let's Encrypt, l'autorité de certification censée révolutionner l'usage de la technologie SSL par sa facilité d'usage, et qui doit permettre à Madame Michu de sécuriser son petit blog de cuisine traditionnelle en toute simplicité et sans avoir besoin de faire perdre une après-midi à son petit neveux du côté de sa belle-mère, qui se trouve être administrateur système, afin qu'il lui répète une quinzaine de fois les étapes de création et de validation d'un certificat en bonne et due forme. Ah, la famille...

    Mais tout d’abord, je vous souhaite à tous une bonne année 211 - 25 ! Au niveau personnel, je vous souhaite tout le bonheur que vous méritez, tant sur le plan professionnel/scolaire qu'avec votre famille/amis/béguin divers. Instruisez-vous, soyez curieux, incitez vos proches à la sagesse, et bien sûr, restez vous-même gentils.

    Au niveau citoyen, je souhaite comme toujours une prise de conscience collective sur cette cage en or qu'est devenue aujourd'hui la vie sur les internets, et une plus grande sagesse de nos têtes décideuses (à défaut d'être pensantes) à propos de la réalité numérique, qu'elles n'ont toujours pas bien intégrée.


    Enfin, revenons à notre tutoriel. Au cours du mois dernier, vous l'avez peut-être remarqué, le certificat de notre blog (ainsi que les certificats de nos services internes, mais ça c'est nos oignons) ont changé d'autorité de certification. Nous sommes passés d'un certificat Gandi, offert avec notre nom de domaine, à un certificat Let's Encrypt, grâce à l'ouverture de ce service en bêta publique. Pourquoi avons-nous changé ? Et bien, d'abord, depuis le temps que nous vous en parlions, il aurait été ironique que nous n'utilisions pas le système Let's Encrypt. Ensuite, cette manière de procéder n'est pas sans avantages pour un administrateur système, principalement pour les raisons suivantes :

    • Gain de temps global, même pour la première utilisation ;
    • Possibilité de créer un seul certificat pour plusieurs domaines ;
    • Automatisation très poussée des différentes étapes, permettant l'écriture de scripts pour les renouvèlements.

    J'avoue qu'avant la bêta publique et la possibilité de mettre vraiment les mains dans le cambouis, je n'avais aucune idée du fonctionnement, même basique, de ce service. Je n'ai même jamais personnellement manifesté d'attirance particulière envers les technologies de sécurité. En fait, son fonctionnement théorique est très simple, et permet même, à mon sens, de se rendre bien compte du processus de certification SSL dans sa globalité.

    Principe de la vérification d'identité

    Lors de la création d'un certificat, on doit suivre un protocole invariant de l'autorité de certification :

    1. On crée une clef secrète (ou on utilise une clef générée antérieurement).
    2. À partir de cette clef secrète, on génère une demande de certification (contenant une clef publique et des informations sur l'identité de l'entité à certifier).
    3. On soumet cette demande à l'autorité de certification désirée, qui génère et signe un certificat, ce qui dit aux outils des utilisateurs de votre service qu'il s'agit bien de vous, car il fait confiance à l'autorité de certification.

    Les deux premières étapes sont instantanées ; cependant, la dernière étape prends traditionnellement plus de temps, car l'autorité de certification doit s'assurer de l'identité du domaine qu'elle doit certifier. Chez les autorités classiques, il s'agit souvent de fournir des pièces d'identités, ou de répondre à un mail auquel seul le possesseur du domaine peut accéder (du type admin@example.com).

    Let's Encrypt prends en charge ces 3 étapes (il faut reconnaitre que c'est très facile d'automatiser les 2 premières) en passant par un utilitaire chargé de communiquer avec le serveur de son autorité de certification.

    Schéma

    Processus de vérification d'identité

    1. Une fois la clef et la demande de certificat générées, l'exécutable local communique au serveur http un code de vérification à rendre accessible par le serveur de certification.
    2. L'utilitaire demande à l'autorité de certification de procéder à une vérification d'identité en envoyant la demande de certificat et lui communique le code servi par le serveur http à tester.
    3. Le serveur de certification accède au serveur http en utilisant le système DNS
    4. L'autorité de certification accepte l'identité et transfert le certificat.
    5. L'utilitaire met le certificat généré à disposition des services de l’utilisateur.

    Ainsi, le processus de création du certificat ne prends en tout et pour tout que quelques dizaines de secondes. Cependant, par cette méthode, on est contraint de mettre en service, au moins temporairement, un service web pour chaque domaine à tester, ce qui est gênant pour des domaines qui ne sont pas destinés à pointer sur un site web.

    Configurer son serveur web

    Let's Encrypt met à disposition des "extensions" lui permettant de communiquer tout seul au serveur web les informations pour l'étape de la vérification d'identité. Cependant, j'utilise Nginx, et à ce jour seul Apache dispose d'une extension stable. Il existe une extension expérimentale pour Nginx mais je n'ai pas su m'en servir convenablement, ou alors j'ai eu la flemme de comprendre comment elle marchait. De toute façon, selon les retours utilisateurs et les forums, la méthode générique (dite du webroot) est la plus utilisée, c'est donc celle qui sera présentée, et vous verrez, ce ne sera pas bien compliqué.

    Tout d'abord, il faut définir le dossier qui sera mis à disposition par le serveur web. Par exemple, pour pouvez créer et choisir l'emplacement /var/www/webrootauth.

    Vous devez ensuite modifier la configuration de chaque domaine que vous souhaitez faire certifier. Vous avez le droit à 100 domaines couverts par votre certificat, vous avez donc de la marge, et vous auriez tort de vous priver. Sous Nginx, vous devez ajouter au sein de chaque server block :

    location ~ ^/.well-known/acme-challenge(/.*)?$ {
        root /var/www/webrootauth;
        default_type text/plain;
    }

    Sans oublier de recharger Nginx :

    service nginx restart

    ou bien, selon votre distribution Linux :

    systemctl restart nginx

    Pour information, cela demande à Nginx de servir le contenu de /var/www/webrootauth à l'adresse http://example.com/.well-known/acme-challenge/, adresse qui sela utilisée par l'autorité de certification.

    Installer l'utilitaire

    EDIT : C'était prévisible, maintenant quelques distributions intègrent Let's Encrypt dans leurs dépôts. Cette méthode est donc à privilégier par rapport à la méthode ci dessous.

    Il faut maintenant télécharger l'exécutable mis à disposition par Let's Encrypt. Pour cela, vous allez avoir besoin de Git, veillez donc à ce qu'il soit installé sur votre machine.

    Devenez super-utilisateur :

    sudo su -

    Puis clonez le dépôt du projet :

    git clone https://github.com/letsencrypt/letsencrypt /root/letsencrypt

    Configurer Let's Encrypt

    Il est possible d'exécuter Let's Encrypt à la sauvage sans fichier de configuration, uniquement avec des paramètres long comme mon bras. Il est néanmoins plus propre d'écrire son fichier de configuration, cela donne des scripts plus propres et un historique bash plus clair. Et comme ça vous n'avez pas des tonnes de lignes de commandes à retenir en cas de perte de vos scripts :)

    Un fichier de configuration Lets Encrypt ressemble à ceci :

    rsa-key-size = 4096
    server = https://acme-v01.api.letsencrypt.org/directory
    email = votreadresse@domaine.truc
    authenticator = webroot
    webroot-path = /var/www/webrootauth
    text = True
    renew-by-default = True
    agree-tos = True
    domains = hashtagueule.fr,mail.hashtagueule.fr,wiki.hashtagueule.fr,mysql.hashtagueule.fr,znc.hashtagueule.fr,ttrss.hashtagueule.fr

    Petite explication :

    • rsa-key-size : la taille de la clef, on l'a mis au maximum, parce qu'on est des gros bourrins. Sachez que la génération d'une clef 4096 bits prends plus de temps, mais elle n'est générée qu'à la première exécution.
    • server : l'adresse du serveur de certification. Ça ne sert à rien de le changer.
    • email : l'adresse e-mail de votre compte Let's Encrypt (s'il n'existe pas, il sera créé automatiquement, pas d’inquiétude).
    • authenticator : la méthode de vérification d'identité, on a dit qu'on choisissait la méthode webroot.
    • webroot-path : doit correspondre au chemin choisi précédemment.
    • text : indique que l'on souhaite exécuter l'outil en lignes de commandes, pratique pour les scripts et permet de tout exécuter sans intéraction (un mode pseudo-graphique existe mais n'est pas pratique).
    • renew-by-default : indique que les certificats existants doivent être renouvelés.
    • agree-tos : indique que vous acceptez la paperasse lié à l'utilisation des certificats, à lire quelque part sur leur site, mais bon, rien de bien méchant.
    • domains : là, vous devez indiquer tous les domaines que doit couvrir le certificat qui va être généré, séparés par une virgule.

    Vous placerez ce fichier quelque part d'accessible. Par exemple, vous pouvez le placer dans /root/le-config/cli.ini.

    Générer ponctuellement le certificat

    Tout est en place pour la génération de votre premier certificat, la tension monte, je vous sens tout excité. Allez, lancez-vous, en voiture Simone. Pour générer votre certificat, en tant que super-utilisateur, exécutez la commande suivante :

    /root/letsencrypt/letsencrypt-auto certonly --config /root/le-config/cli.ini

    Laissez mijoter quelques instants. La première fois, des dépendances nécessaires vont s'installer, il va configurer deux trois trucs, et finalement faire le boulot.

    Normalement, à la fin, vous allez avoir un message vous félicitant du succès de l'opération. Bravo, vous avez un certificat Let's Encrypt :)

    Vous pourrez ensuite configurer votre serveur web pour utiliser ce certificat. Sous Nginx, vous préciserez dans vos server blocks :

    listen 443;
    listen [::]:443;
    ssl on;
    ssl_certificate /etc/letsencrypt/live/hashtagueule.fr/fullchain.pem;
    ssl_certificate\_key /etc/letsencrypt/live/hashtagueule.fr/privkey.pem;

    Bien sûr, vous remplacerez hashtagueule.fr par le nom de votre domaine principal. Vérifiez en regardant le nom du dossier à cet emplacement.

    Vous pouvez ensuite recharger Nginx, et si tout ce passe bien, vous avez un site sécurisé Let's Encrypt.

    Renouvellement automatique

    Les certificats générés par Let's Encrypt ont une validité de 90 jours. C'est court, et c'est un fil à la patte de devoir tous les 3 mois demander un renouvellement de certificat. Heureusement, il y a Cron.

    Cron est un service sur votre machine qui va se charger d'exécuter des tâches à intervalle régulier. Tous ce que vous avez à faire, c'est d'écrire un script à fournir à cron. Ce script ressemblera à ça :

    #!/bin/bash
    
    la_cert_dir=/etc/letsencrypt/live/hashtagueule.fr
    
    /root/letsencrypt/letsencrypt-auto certonly --config /root/le-config/cli.ini 1> /dev/null
    
    # nginx
    service nginx reload
    
    # Vous pouvez également scripter les opération à suivre
    # pour d'autres services, par exemple votre serveur mail.
    
    # Envoi d'un mail de notification à l'administrateur
    mail -a "From: Agent de certification Hashtagueule <letsencrypt@hashtagueule.fr>" -a "Content-Type: text/plain; charset=UTF-8" -s "Renouvellement des certificats" votreadresse@domaine.truc << EOF
    Bonjour,
    
    Le certificat des services Hashtagueule a été renouvelé et couvre actuellement les domaines suivants :
    
    $(openssl x509 -in /etc/letsencrypt/live/hashtagueule.fr/cert.pem -noout -text | grep DNS | sed 's/, /\n/g' | cut -d: -f2)
    
    Dates de validité :
    
    $(openssl x509 -in /etc/letsencrypt/live/hashtagueule.fr/cert.pem -dates -noout | cut -d= -f2)
    
    Pour rappel, les certificats délivrés par Let's Encrypt ont toujours une validité de 3 mois. Tâchez donc de définir une période de renouvellement inférieure à cette durée.
    Il est à noter également que l'autorité Let's Encrypt ne délivre qu'un maximum de 5 certificats pour le même domaine par semaine. Renouvelez donc avec précaution.
    
    Bonne journée.
    EOF

    Ce script va renouveler le certificat et vous envoyer un mail de notification comportant les nouvelles dates de validité et les domaines concernés. Classe, non ?

    Il vous reste à rendre ce script exécutable et à le placer dans /etc/cron.monthly afin de l'exécuter tous les mois.

    Limitations

    Comme indiqué précédemment, les domaines à certifier doivent être servis par un serveur web, au moins pour la durée de la vérification d'identité.

    D'autre part, évitez de générer trop de certificats, car vous êtes limités à 5 renouvèlements par semaine. En régime permanent ça ne pose pas de problème, mais je me suis déjà fait avoir lors de mes tests...

    Voilà, j'espère que ce tutoriel vous aura été utile, et j'espère aussi voir fleurir une multitude de sites sécurisés.

    Désormais, vous n'avez plus aucune excuse.