Vendredi 23 novembre 2018

Certificats SSL letsencrypt (yunohost avec des sous-domaines)

Procédure de création et renouvellement des certificats SSL letsencrypt (yunohost avec des sous-domaines)

1. Installer le client Let’s encrypt

domaine.tld devra être remplacé par votre nom de domaine*

Connectez vous en root sur votre serveur, puis :
Assurez-vous que votre système est à jour (en tant que root)

apt update && apt upgrade

Vérifier où installer git et bc

apt-get -y install git bc

Clonez le dépôt git de Let’s encrypt

git clone https://github.com/certbot/certbot /opt/certbot

2. Éditez la configuration de Nginx et de SSOwat

Pour verifier que vous êtes effectivement propriétaire de domaine.tld, le client de Let’s encrypt va ajouter des fichiers sur votre serveur et auxquels l’autorité de certification de Let’s encrypt pourra accéder.

REMPLACER domaine.tld par votre nom de domaine ( exemple.com , site.fr , etc…)

Nous allons rendre l’URL domaine.tld/.well-known/acme-challenge accessible, et le contenu correspondant sera stocké dans /tmp/letsencrypt-auto. Ajoutez un fichier de config nginx, par exemple nommé letsencrypt.conf.

nano /etc/nginx/conf.d/domain.tld.d/letsencrypt.conf

Dans ce fichier, ajoutez ce bloc :

location '/.well-known/acme-challenge' {  
    default_type "text/plain";  
    root         /tmp/letsencrypt-auto;  
}  

Créer le dossier temporaire

mkdir -p /tmp/letsencrypt-auto

Dans le contexte de YunoHost, nous devons aussi modifier la configuration SSOwat pour que les serveurs de Let’s encrypt ne soient pas redirigés vers l’interface de login en tentant d’accéder à .well-known/acme-challenge. Ouvrez le fichier de règles persistantes pour SSOwat (nano /etc/ssowat/conf.json.persistent)

nano /etc/ssowat/conf.json.persistent

et ajoutez une nouvelle règle unprotected_urls :

{  
    unprotected_urls : [  
        "domaine.tld/.well-known/acme-challenge"  
    ]  
}  

Attention à la syntaxe, si vous avez déjà des choses dans votre conf.json.persistent : il faut ajouter le unprotected_urls dans les { } (c.f. ce post)

Dans le cas d’un domaine + sous domaine
On veut ajouter static.domaine.tld
Modifier le fichier de configuration

nano /etc/nginx/conf.d/domaine.tld.conf

Modifier la ligne server_name , ajouter static.domaine.tld

server {
    listen 80;
    listen [::]:80;
    server_name domaine.tld static.domaine.tld;
[...]

ajoutez une nouvelle règle unprotected_urls :

nano /etc/ssowat/conf.json.persistent
{  
    unprotected_urls : [  
        "domaine.tld/.well-known/acme-challenge",  
        "static.domaine.tld/.well-known/acme-challenge"  
    ]  
}  

Vérifiez que votre configuration nginx est valide avec

nginx -t

puis redémarrez le daemon avec

service nginx restart # (Pas besoin de faire quoi que ce soit pour SSOwat)  

3. Obtenir les certificats

Maintenant nous allons effectivement demander le certificat à l’autorité de certification.
Créer le répertoire

mkdir /usr/local/etc/letsencrypt

Créez un fichier de configuration

nano /usr/local/etc/letsencrypt/domaine.tld.ini

avec le contenu suivant :

#################################  
#  Let's encrypt configuration  #  
#################################  
  
# Taille de la clef  
rsa-key-size = 4096  
  
# Email de notification / contact si nécessaire dans le futur  
email = webmaster@domaine.tld  

# domaine(s)
domains = domaine.tld,sub.domaine.tld 
  
# Utiliser la méthode d'authentification webroot  
# avec le contenu dans /tmp/letsencrypt-auto  
webroot-path = /tmp/letsencrypt-auto  

(N’oubliez pas de changer l’adresse email dans le fichier de configuration.) De retour à la ligne de commande, listons les domaines pour lesquels vous souhaitez un certificat :

Récupérons maintenant le certificat, en indiquant le fichier de config :

cd /opt/certbot
./certbot-auto certonly --config /usr/local/etc/letsencrypt/example.com.ini --webroot
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/domaine.tld/fullchain.pem. Your cert will
   expire on 2016-11-28. 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"

4. Utiliser vos certificats

Effacer les certificats actuels :

rm /etc/yunohost/certs/domaine.tld/{crt.pem,key.pem}`   

Maintenant, créez des liens symboliques vers vos nouveaux certificats :

ln -s /etc/letsencrypt/live/domaine.tld/fullchain.pem /etc/yunohost/certs/domaine.tld/crt.pem  
ln -s /etc/letsencrypt/live/domaine.tld/privkey.pem /etc/yunohost/certs/domaine.tld/key.pem  

Vérifiez nginx

nginx -t

et redémarrez-le avec

service nginx restart

Ensuite, ouvrez votre site dans votre navigateur et vous devriez normalement avoir un certificat signé par Let’s encrypt et reconnu automatiquement ! (cliquez sur le cadenas à côté de l’URL pour voir les infos)

5. Renouveler automatiquement ses certificats

Pour encourager l’automatisation, les certificats de Let’s encrypt ne sont valides que 90 jours et doivent être renouvelé après cette période. Dans le futur, cette durée sera peut-être même plus courte.

Il est possible de mettre en place un cron job (tache automatique périodique) pour vérifier la validité de votre certificat et le renouveler s’ils sont sur le point d’expirer.
Création du script dans les jobs hebdomadaires

nano /usr/local/sbin/le-renew-webroot

#!/bin/bash

web_service='nginx'
mkdir -p /tmp/letsencrypt-auto

FILES=/usr/local/etc/letsencrypt/*.ini
for f in $FILES
do
    echo "Renewing for $f file..."
    config_file="$f"


    le_path='/opt/certbot'
    exp_limit=30;

    if [ ! -f $config_file ]; then
            echo "[ERROR] config file does not exist: $config_file"
            exit 1;
    fi

    domain=`grep "^\s*domains" $config_file | sed "s/^\s*domains\s*=\s*//" | sed 's/(\s*)\|,.*$//'`
    cert_file="/etc/letsencrypt/live/$domain/fullchain.pem"

    if [ ! -f $cert_file ]; then
            echo "[ERROR] certificate file not found for domain $domain."
    fi

    exp=$(date -d "`openssl x509 -in $cert_file -text -noout|grep "Not After"|cut -c 25-`" +%s)
    datenow=$(date -d "now" +%s)
    days_exp=$(echo \( $exp - $datenow \) / 86400 |bc)

    echo "Checking expiration date for $domain..."

    if [ "$days_exp" -gt "$exp_limit" ] ; then
            echo "The certificate is up to date, no need for renewal ($days_exp days left)."
            continue;
    else
            echo "The certificate for $domain is about to expire soon. Starting webroot renewal script..."
            $le_path/letsencrypt-auto certonly -a webroot --agree-tos --renew-by-default --config $config_file
            echo "Renewal process finished for domain $domain"
            continue;
    fi
done
echo "Reloading $web_service"

Droits en exécution

chmod +x /usr/local/sbin/le-renew-webroot

Si vous voulez, lancez le script manuellement

le-renew-webroot

Ajouter une ligne au crontab

crontab -e

30 2 * * 1 /usr/local/sbin/le-renew-webroot >> /var/log/le-renewal.log

6. Options - Forcer le rechargement d’un domaine

Utile dans le cas d’un ajout de sous-domaine

# /opt/certbot/certbot-auto certonly -a webroot --renew-by-default --config /usr/local/etc/letsencrypt/example.com.ini

Redémarrer Nginx

service nginx restart