Let's Encrypt utilisation

De wikiGite

Let's encrypt : https://letsencrypt.org

Letsencrypt uses a protocol called ACME (Automated Certificate Management Environment) for determining if you are really the owner of the domain for which you're requesting a cert. The basic way it works is that it will genreate some files that you post to a directory on your server which it (letsencrypt) can access over port 80 on your domain. If you're able to do that, then you must be the owner of that domain.

NOTE importante : le nom du script a été modifié dans les dernières versions. "letsencrypt-auto" existe encore pour compatibilité, mais on doit lancer désormais "certbot-auto". Ce changement a été voulu afin de ne pas confondre Let's Encrypt (autorité de certification) et letsencrypt (scripts indépendants qui créent et renouvellent des certificats de cette autorité).

Procédure créée à partir de :

http://linuxfr.org/news/reparlons-de-let-s-encrypt

https://www.upcloud.com/support/install-lets-encrypt-apache/

https://www.grafikart.fr/formations/serveur-linux/apache-ssl-letsencrypt

https://vincent.composieux.fr/article/install-configure-and-automatically-renew-let-s-encrypt-ssl-certificate

https://nikhilthedev.com/ssl/how-to-install-lets-encrypt-free-ssl-certificate-on-vestacp-domains/

http://www.servermom.org/install-lets-encrypt-certificate-vestacp/3208/

INSTALLATION

ATTENTION, alors que python-virtualenv et python-pip sont disponibles dans les dépôts de base sur Centos7, ils sont dans le dépôt EPEL sur Centos6. Il faut donc les installer préalablement si EPEL est désactivé par défaut (ce que je vous conseille !).

yum install --enablerepo=epel python-virtualenv python-pip
cd /opt
git clone https://github.com/letsencrypt/letsencrypt
ln -s /opt/letsencrypt/certbot-auto /usr/local/bin/certbot-auto
certbot-auto register # installe les dépendances par yum et réalise une connexion avec la CA. Enregitre notamment l'adresse mail de notifications. Vérifier que les paquets installés n'entrent pas en conflit avec d'autres logiciels

UTILISATION

certonly

le module "--apache" de letsencypt ne fonctionne pas avec certaines implémentation d'apache SSL, par exemple Blueonyx parce qu'elle gère ssl avec un ssl_perl.conf qui n'est pas un fichier de configuration standard. Le client letsencrypt ne peut pas modifier lui-même les fichiers de configuration apache comme il le fait par défaut. On créera donc dans la première partie de cette procédure les certificats avec "certonly" pour qu'il ne fasse que générer et télécharger les certificats, pour une installation manuelle ensuite.

La seconde partie, dédiée à Vesta Control Panel, utilise un script spécifique qui enregistre lui-même les certificats dans le bon répertoire. Ce script utilise donc aussi certonly.

mode test

TIP: commencer en ajoutant "--test-cert" (ou "--staging") sur toutes les commandes certbot-auto ci-dessous, afin de ne générer que des certificats "fake" qui n'incrémentent pas le compteur chez Let-s Encrypt. En effet, si plusieurs tests échouent pour un domaine, ils finissent par bloquer les demandes.

WEBROOT

le client crée un flag dans le site, lu par Let's Encrypt pour valider qu'on est sur le bon serveur.

 ./certbot-auto certonly -d monsite.domain.fr

Dans les écrans suivant, indiquer

  • Place files in webroot directory (webroot)
  • email de l'admin
  • Agree (terms of service)
  • Enter a new webroot
  • choisir le webroot HTTP (pas https) du site

Ou avec une fichier de configuration :

 ./certbot-auto certonly -d monsite.domain.fr --config /opt/letsencrypt/monsite.domain.fr.ini

créer /opt/monsite.domain.fr.ini

# We use a 4096 bit RSA key instead of 2048
rsa-key-size = 4096

email = admin@domain.fr
domains = monsite.domain.fr

authenticator = webroot

# This is the webroot directory of your domain in which
# letsencrypt will write a hash in /.well-known/acme-challenge directory.
webroot-path = /var/www/monsite.domain.fr/web

Réponse si OK :

Version: 1.1-20080819
Version: 1.1-20080819

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/monsite.domain.fr/fullchain.pem. Your cert
   will expire on 2016-09-07. To obtain a new or tweaked version of
   this certificate in the future, simply run letsencrypt-auto again.
   To non-interactively renew *all* of your certificates, run
   "letsencrypt-auto renew"

Le pem peut être installé dans la configuration SSL de monsite.domain.fr

 # add ssl protocol
 SSLEngine On
 SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
 SSLCertificateFile  /etc/letsencrypt/live/monsite.domain.fr/fullchain.pem
 SSLCertificateKeyFile /etc/letsencrypt/live/monsite.domain.fr/privkey.pem

STANDALONE

letsencrypt lance son propre serveur web. Aucun autre service web ne doit être lancé sur le même port sur le serveur. Arrêter le service web en cours si nécessaire.

Selon le port disponible au moment de la génération sur le serveur (derrière un firewall par exemple), ajouter :

  • --standalone-supported-challenges http-01 # to use port 80
  • --standalone-supported-challenges tls-sni-01 # to use port 443
 ./certbot-auto certonly --standalone -d monsite.domain.fr

Les certificats sont créés dans /etc/letsencrypt/live/monsite.domain.fr, à placer dans la configuration SSL.

MANUEL en dehors du serveur de production

Pour utiliser un autre serveur que le serveur qui héberge le site (et donc doit normalement répondre), on peut lancer la client en manuel et répondre soi-même au challenge (création du .well-known/acme-challenge avec le token attendu). Donc sur un serveur tierce, sans apache qui tourne :

 ./certbot-auto certonly --manual -d monsite.domain.fr

Accepter le fait que l'IP sera logguée par Let's Encrypt. C'est un moindre mal pour ce qu'ils apportent !

Réponse :

Make sure your web server displays the following content at
http://monsite.domain.fr/.well-known/acme-challenge/iAV8OLYoNPchaClyvLx4J6-DDkymW3EmBzg3icUlEeg before continuing:

iAV8OLYoNPchaClyvLx4J6-DDkymW3EmBzg3icUlEeg.VM6IgnRLoxo484hbGGHHhnQHuWeAwzIbkt9IoX7HsK8

If you don't have HTTP server configured, you can run the following
command on the target server (as root):
mkdir -p /tmp/certbot/public_html/.well-known/acme-challenge
cd /tmp/certbot/public_html
printf "%s" iAV8OLYoNPchaClyvLx4J6-DDkymW3EmBzg3icUlEeg.VM6IgnRLoxo484hbGGHHhnQHuWeAwzIbkt9IoX7HsK8 > .well-known/acme-challenge/iAV8OLYoNPchaClyvLx4J6-DDkymW3EmBzg3icUlEeg
# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer((, 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()" 

A ce stade, le client letsencrypt attend notre décision

Traduction : soit on crée ensuite manuellement .well-known/acme-challenge/iAV8OLYoNPchaClyvLx4J6-DDkymW3EmBzg3icUlEeg sur le serveur de production (qui a le site), soit on lance un serveur web temporaire sur notre serveur tierce comme indiqué après "you can run the following..." (dans une autre console ssh).

Une fois qu'un des serveurs est paramétré, appuyer sur un touche pour que le client letsencrypt termine.

Le certificat est créé sur le serveur tierce dans /etc/letsencrypt/live/monsite.domain.fr/, à installer dans la configuration SSL du serveur de production.

TIP : Pour VESTACP, manuellement dans le webui, mettre le contenu de "cert1.pem" dans la case certificat, de "privkey1.pe" dans la case clé, et de "chain1.pem" dans la case autorité/intermédiaire.


OU : automatisation par le script letsencrypt-vesta :

Letsencrypt-vesta

script spécifique

Interbrite a eu la bonne idée de développer un script d'automatisation spécialement pour VestaCP.

 yum install git
 cd /opt
 git clone https://github.com/letsencrypt/letsencrypt.git
 git clone https://github.com/interbrite/letsencrypt-vesta.git
 mkdir -p /etc/letsencrypt/webroot

modifier le chemin du client letsencrypt dans le script letsencrypt-vesta :

LETSENCRYPT_COMMAND='/opt/letsencrypt/certbot-auto ...(etc)...'

puis

 ln -s /opt/letsencrypt-vesta/letsencrypt.conf /etc/httpd/conf.d/letsencrypt.conf

Pour faciliter le lancement des scripts :

 ln -s /opt/letsencrypt/certbot-auto /usr/local/bin/certbot-auto
 ln -s /opt/letsencrypt-vesta/letsencrypt-vesta /usr/local/bin/letsencrypt-vesta

ATTENTION, s'assurer que tous les alias DNS du domaine pour lequel on veut créer les certificats pointent bien vers le même serveur (letsencrypt teste tous les alias !)

Relancer Apache, et lancer letsencrypt-vesta une première fois pour installer les dépendances.

 service httpd restart
 letsencrypt-vesta user domaine

Si aucun domaine ne doit passer en SSL pour le moment, on peut tout de même installer les dépendances et s'assurer que tout va bien en lançant certbot-auto sans paramètre et "Annuler" le dernier écran listant les domaines:

 certbot-auto

Création des certificats pour d'autres domaines :

 letsencrypt-vesta username domain

le premier lancement installe les dépendances. Il crée les certificats, et modifie tout seul la configuration VestaCP pour le domaine donné.

Redirection https

Si une redirection du http vers le https est paramétré sur le site, il est nécessaire de la désactiver car ce script s'appuie sur http.

Le plus simple est de paramétrer la redirection dans un fichier inclus, de dupliquer le script letsencrypt-renew.sh (voir ci-dessous) pour le site en question (ex: letsencrypt-renew-monsite.sh), et d'ajouter avant la commande letsencrypt-vesta :

mv /chemin-du-site/chemin-conf-nginx/nginx.redirssl.conf /chemin-du-site/chemin-conf-nginx/nginx.redirssl.conf.disable
systemctl reload nginx

et après la commande :

mv /chemin-du-site/chemin-conf-nginx/nginx.redirssl.conf.disable /chemin-du-site/chemin-conf-nginx/nginx.redirssl.conf
systemctl reload nginx

Renouvellement

C'est simple avec le script certbot-auto : relancer la même commande tous les 60 jours, ça renouvellera le certificat. A mettre dans le cron, donc.

par exemple: à 1h du matin le 1er, tous les 2 mois : 00 01 1 */2 * /opt/letsencrypt/certbot-auto myuser domain.com

Pour avoir un retour en cas d'erreur, un petit script s'impose. Créer /opt/letsencrypt/letsencrypt-renew.sh :

# Renew Let's Encrypt SSL cert

source /etc/profile
PATH=$PATH:/usr/local/bin
MAIL=admin@domain.com

letsencrypt-vesta $1 $2 >> /var/log/letsencrypt/letsencrypt.log 2>&1

if [ $? -ne 0 ]
 then
        ERRORLOG=`tail /var/log/letsencrypt/letsencrypt.log`
        echo -e "Le certificat Lets Encrypt pour $2 n'a pas été renouvelé !\n \n" $ERRORLOG | mail -s "Erreur de renouvellement Lets Encrypt" $MAIL
 else
        systemctl reload httpd
fi

exit 0

Pour vesta, si on planifie le cron dans l'interface, il faut aussi autoriser l'utilisateur admin à lancer ce script.

Editer /etc/sudoers.d/admin, et y ajouter la ligne :

admin   ALL=NOPASSWD:/opt/letsencrypt/letsencrypt-renew.sh

Et pour le script, on peut récupérer l'adresse mail enregistrée pour l'utilisateur admin dans l'interface. Le script renew sera alors un peu différent :

# Renew Let's Encrypt SSL cert

source /etc/profile
source /usr/local/vesta/data/users/admin/user.conf
PATH=$PATH:/usr/local/bin

letsencrypt-vesta $1 $2 >> /var/log/letsencrypt/letsencrypt.log 2>&1

if [ $? -ne 0 ]
 then
        ERRORLOG=`tail /var/log/letsencrypt/letsencrypt.log`
        echo -e "Le certificat Lets Encrypt pour $2 n'a pas été renouvelé !\n \n" $ERRORLOG | mail -s "Erreur de renouvellement Lets Encrypt" $CONTACT
 else
        systemctl reload httpd
fi

exit 0

Divers

Automatisation

A tester : script d'automatisation de création manuelle (enlève l'obligation d'être sur le serveur lui-même (=> pas de réponse directe quand letsencrypt essaie de se connecter au site), ou pour un service non-apache/nginx qu'on ne peut pas arrêter pour le mode standalone)

ATTENTION : !! /etc/ssl/openssl.cnf doit exister !!

#!/bin/sh
#
# Wrapper script for the letsencrypt client to generate a server certificate in
# manual mode. It uses openssl to generate the key and should not modify the
# server configuration. It can be called off-side, i.e. not on the destination
# server.
#
# usage: gencert DOMAIN [DOMAIN...]
#
# This is free and unencumbered software released into the public domain.
# For more information, please refer to http://unlicense.org/ 

set -e

if [ $# -lt 1 ]; then
    echo "$0: error: at least one domain name required."
    exit 1
fi
domain=$1 

shift
other_domains=
while [ $# -gt 0 ]; do
    other_domains="$other_domains,DNS:$1"
    shift
done

country=FR
state="Vienne"
town="Poitiers"
email=admin@domain.fr

outdir="certs/$domain"
key="$outdir/privkey1.pem"
csr="$outdir/signreq.der"

if [ -d "$outdir" ]; then
    echo "output directory $outdir exists"
    exit 1
fi

tmpdir=
cleanup() {
    if [ -n "$tmpdir" -a -d "$tmpdir" ]; then
        rm -rf "$tmpdir"
    fi
}
trap cleanup INT QUIT TERM EXIT
tmpdir=`mktemp -d -t mkcert-XXXXXXX`

sslcnf="$tmpdir/openssl.cnf"
cat /etc/ssl/openssl.cnf > "$sslcnf"
echo "[SAN]" >> "$sslcnf"
echo "subjectAltName=DNS:$domain$other_domains" >> "$sslcnf"

mkdir -p "$outdir"
openssl req \
    -new -newkey rsa:2048 -sha256 -nodes \
    -keyout "$key" -out "$csr" -outform der \
    -subj "/C=$country/ST=$state/L=$town/O=$domain/emailAddress=$email/CN=$domain" \
    -reqexts SAN \
    -config "$sslcnf"

letsencrypt certonly \
    --authenticator manual \
    --server https://acme-v01.api.letsencrypt.org/directory --text \
    --config-dir letsencrypt/etc --logs-dir letsencrypt/log \
    --work-dir letsencrypt/lib --email "$email" \
    --csr "$csr"