Jonathan.Michalon.eu

$HOME de Jonathan

24 déc. 2015

Let's Encrypt

Let's Encrypt est une initiative visant à répandre le chiffrement des communications à base de certificat X.509 sur le net, en facilitant son déploiement.

Cette initiative a généré beaucoup de bruit, car comme toujours il y a du bon et du moins bon. Pour simplifier, je dirais que Let's Encrypt permet de générer des certificats (reconnus à peu près partout en utilisation web), valables 90 jours, permettant de définir plusieurs noms DNS (ou même un joker (wildcard)) et ce gratuitement et automatiquement. Plus d'informations sur leur site. Habituellement c'est un processus relativement ennuyeux, souvent payant ou sinon plus limité.

Essais

Au gré des lectures, j'ai vu passer un client non-officiel, et certaines personnes qui me semblaient sensées affirmaient qu'il était encore plus simple et efficace. Par hasard j'ai donc commencé à regarder le README, puis le code, et à tester…

Le README est très explicite, et globalement ça fonctionne effectivement bien. À part quelques détails et un bug (corrigé du coup :)) dans le domaine que j'ai pris comme cobaye, pas de soucis.

Mise en place

Voici comment j'ai mis en place tout cela, guidé par le README du client et un peu de pifomètre. Pour comprendre, vraiment, lisez le README…

Base

cd /usr/local/bin/
wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py
chmod +x acme_tiny.py

adduser --system --no-create-home acme

mkdir /etc/ssl/letsencrypt
cd /etc/ssl/letsencrypt

Ici le dossier /etc/ssl/letsencrypt est peut-être pas très malin : vu que certains fichiers vont être amenés à changer automatiquement c'est plutôt à caser dans /var… à améliorer un jour peut-être.

Suite, un peu de crypto (clef privée du compte à sauvegarder !) :

openssl genrsa 4096 > account.key
chown acme account.key
chmod 600 account.key

wget -O intermediate.pem https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem

Edit: passage au certificat X3, voir https://letsencrypt.org/certificates/

Scripts de déploiement

Globalement, pour chaque nouveau domaine :
  1. Créer une clef privée
  2. Générer la requête de signature (CSR)
  3. Préparer le terrain pour les fichiers de vérification du domaine (créer le dossier acme-challenge)

Pour moi ça se concrétise en :

#!/bin/bash

[ $# -eq 2 ] || exit

domain=$1
acmedir=$2

cd /etc/ssl/letsencrypt

openssl genrsa 4096 > $domain.key
chmod 600 $domain.key
openssl req -new -sha256 -key $domain.key -subj "/" -reqexts SAN -config <(cat ./openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:$domain,DNS:www.$domain")) > $domain.csr

mkdir -p $acmedir/.well-known/acme-challenge/
chown acme $acmedir/.well-known/acme-challenge/

echo "$domain $acmedir/.well-known/acme-challenge/" >> autoupdate

La dernière ligne ajoute une entrée dans un fichier spécial autoupdate, qui permet au script de renouvellement de savoir quels certificats renouveler et dans quel dossier mettre les fichiers de vérification.

Et donc, le script de (re)génération des certificats qui correspond (je l'ai mis dans /etc/cron.monthly/letsencrypt) :

#!/bin/bash

DIR=/etc/ssl/letsencrypt/
TODAY=$(date +%Y%m%d)

cat $DIR/autoupdate | while read -a data; do
  domain=${data[0]}
  acmedir=${data[1]}
  if [ -e $DIR/$domain.pem ] && [[ `date -d "now - $( stat -c "%Y" $DIR/$domain.pem) seconds" +%s` -lt 4320000 ]]; then
    echo "Skipping $domain as too young (less than 50 days)"
    continue
  fi
  if ! [ -d $acmedir ]; then
    mkdir -p $acmedir
    chown acme $acmedir
  fi
  sudo -u acme python /usr/local/bin/acme_tiny.py --account-key $DIR/account.key --csr $DIR/$domain.csr --acme-dir $acmedir > $DIR/$domain.crt-$TODAY
  if [ $? -eq 0 ]; then
    cat $DIR/$domain.crt-$TODAY $DIR/intermediate.pem > $DIR/$domain.pem
    chmod 600 $DIR/$domain.pem
  fi
  chmod 600 $DIR/$domain.crt-$TODAY
done

service apache2 reload

J'évite de générer si le fichier existe et a moins de 50 jours (90 jours de validité, en cron monthly au max donc tous les 31 jours, avec un peu de marge disons 40, donc on arrive bien à 90-40=50).

Le nouveau certificat, je le mets dans un fichier plus ou moins "versionné", avec la date dans le nom quoi. C'est pour éviter d'écraser le certificat précédent en cas de mauvaise manipulation (qui m'est arrivé pendant l'écriture du script) ou pour réparer rapidement au cas où une génération se passerait mal, en repartant sur le précédent.

Voila, pour l'instant j'ai 4 sites qui sont passés du snakeoil du paquet ssl-cert à un vrai certificat reconnu comme cela. Le dernier a été "TLSifié" en 3 minutes 30, ça va ! On verra maintenant au moment du renouvellement… ne pas oublier d'ajouter une vérification à son monitoring (auto-pub : picomon par exemple) si on tient à son site en TLS.

EDIT:

  • Dans le script, passage de l'opérateur < à -lt car « Lorsqu'ils sont utilisés avec [[, les opérateurs < et > ordonnent d'un point de vue lexicographique en utilisant les paramètres linguistiques régionaux actuels. ». Ceci faisant donc une exception à l'évaluation arithmétique…
  • Ajout de la création du dossier acmedir s'il n'existe plus (il peut avoir été écrasé comme par exemple avec make ssh_upload de Pelican qui fait un rsync avec l'option --delete).

Blue Penguin Theme · Powered by Pelican · Atom Feed · Rss Feed

Copyright © 2011-2021 Jonathan Michalon. Vous pouvez réutiliser tout contenu diffusé, sauf mention spécifique.