Full SSL avec Let’s Encrypt sous Nginx

Let’s Encrypt a considérablement facilité l’acquisition d’un certificat SSL signé. Le principale avantage de ce service est sa gratuité. Mais les certificats délivrés étant valides seulement 90 jours (pour des raisons de gestion et de sécurité), Let’s Encrypt permet aussi leur renouvellement automatisé.

Puisque c’est gratuit et automatisable, il n’y a plus de raison de ne pas systématiser le chiffrement SSL. Il est ici question de configurer un serveur Nginx sous CentOS, mais la démarche est sensiblement la même avec d’autres environnements Linux (Apache/Debian).

Création du certificat

Le client officiel « certbot » initie la demande auprès de Let’s Encrypt, et automatise sa validation (protocole ACME) avant de transférer les fichiers résultants (certificat et clés).
Pour satisfaire cette validation, il faut naturellement prouver que l’on est bien propriétaire du domaine concerné. Cela se fera par le biais d’un répertoire dédié, publié en HTTP par Nginx.

Certbot est capable de modifier a lui seul la configuration de Nginx (ou autres) afin de simplifier la démarche, et gérer le processus de validation de bout en bout.
En production, l’idée d’avoir un programme qui manipule les configurations et redémarre le serveur directement ne sera cependant pas du goût d’un sysadmin consciencieux. La configuration requise est donc définie en dure, afin de permettre à certbot de fonctionner sans intervention système (mode « certonly »).

D’autres implémentations libres sont aujourd’hui disponibles et dans divers langages.
Il est également possible d’effectuer la validation d’une demande via un enregistrement DNS (champs TXT).

Installation de certbot (via dépôt EPEL):

yum install certbot -y

Création des répertoires:

mkdir /var/letsencrypt
chgrp nginx letsencrypt /var/letsencrypt
mkdir -p /etc/letsencrypt/configs

Configuration Let’s Encrypt:

/etc/letsencrypt/configs/domaine.dom.conf

domains = domaine.dom
rsa-key-size = 2048
server = https://acme-v01.api.letsencrypt.org/directory
email = moi@domaine.dom
text = True
authenticator = webroot
webroot-path = /var/letsencrypt/

Configuration Nginx:

...
location /.well-known/acme-challenge {
  root /var/letsencrypt;
}

Génération du certificat avec certbot:

certbot --config /etc/letsencrypt/configs/domaine.dom.conf certonly

Configuration SSL de Nginx

Nginx est ensuite configuré pour rediriger tous les flux en SSL, en utilisant le nouveau certificat. La stratégie de chiffrement fort est ici relativement stricte, réduisant alors la compatibilité de certains anciens clients (IE < 11, Andoid < 4.4, Java < 8…).

server {
     listen 80;
     server_name domaine.dom;
     return 301 https://$server_name$request_uri;
}

server {
    server_name domaine.dom;
    listen 443 ssl http2 default_server;
    ....
    ssl_protocols TLSv1.2;
    ssl_ecdh_curve secp384r1;
    ssl_ciphers EECDH+AESGCM:EECDH+AES;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 5m;
    ssl_session_tickets off;
    add_header Strict-Transport-Security "max-age=15552000; includeSubdomains; preload";
    ssl_certificate /etc/letsencrypt/live/domaine.dom/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domaine.dom/privkey.pem;
    ....
    location /.well-known/acme-challenge {
        root /var/letsencrypt;
    }
}

Configuration du site

Le site hébergé peut aussi être à adapter a cette configuration « Full SSL ».

En effet, en plus de l’utilisation de l’entête Strict-Transport-Security, il faut éviter tout lien interne absolu s’il ne spécifie pas une URL sécurisée, les redirections étant coûteuses en performances. D’autres part, les ressources externes doivent également passer par HTTPS, sous peine de se voir qualifié, par les navigateurs, de site partiellement sécurisé (Mixed Content Page).

WordPress

 Les paramètres suivant sont a adapter dans le fichier wp-config.php

define('WP_HOME','https://domaine.dom');
define('WP_SITEURL','https://domaine.dom');

Sous WordPress, l’on peut utiliser Search & Replace DB pour corriger d’éventuels liens absolus qui seraient resté en http://.

Renouvellement planifié

Let’s Encrypt permet le renouvellement d’un certificat tous les 2 mois.

Tâche cron:

3 2 3 */2 * /usr/bin/certbot renew

Sources et ressources

Let’s Encrypt with Nginx: https://www.nginx.com/blog/free-cert…
Configuration SSL sous Nginx: https://angristan.fr/configurer-https-nginx/

Documentation Let’s Encrypt: https://letsencrypt.org/docs/
Documentation Certbot: https://certbot.eff.org/

Qualys SSL Labs: https://www.ssllabs.com/ssltest/