CertificatCet article décrit la gestion des certificats SSL/TLS gratuits sur un serveur dédié tournant sous CentOS 7. Un certificat électronique peut être vu comme une carte d’identité numérique. Il est utilisé principalement pour identifier et authentifier une personne physique ou morale, ou pour chiffrer des échanges. Il est signé par un tiers de confiance qui atteste du lien entre l’identité physique et l’entité numérique. Le standard le plus utilisé pour la création des certificats numériques est le X.509.

Les prix des certificats électroniques sont extrêmement variables, et certaines entreprises comme par exemple Symantec les font payer très cher. En revanche, il est tout à fait possible de les avoir gratuitement…

Let’s Encrypt est une autorité de certification lancée le 3 décembre 2015 en version bêta publique. Elle fournit des certificats SSL/TLS gratuits grâce au client Certbot installé sur le serveur qui automatise la plupart des tâches. On n’est donc plus obligé de payer une fortune et/ou de sauter à travers des cerceaux en feu pour créer et renouveler les certificats.

Les certificats générés avec Certbot sont reconnus par l’ensemble des navigateurs Web modernes. Cette technologie repose sur le protocole ACME (Automated Certificate Management Environment).

Prérequis

Pour nos tests, nous allons partir d’une installation par défaut d’Apache, avec un seul site statique rangé dans /var/www/html. Si l’on dispose déjà d’une installation d’Apache avec une série d’hôtes virtuels, voici ce qu’il faut faire pour remettre les compteurs à zéro.

$ sudo yum remove httpd
$ sudo rm -rf /var/www/*
$ sudo rm -rf /etc/httpd/
$ sudo yum install httpd
$ cd /etc/httpd/conf
$ sudo mv httpd.conf httpd.conf.orig
$ egrep -v '^#|^$|^    #|^      #' httpd.conf.orig | sudo tee httpd.conf.lite
$ sudo cp httpd.conf.lite httpd.conf
$ sudo cp -R /usr/share/httpd/noindex/* /var/www/html/

Renseigner quelques directives de base dans httpd.conf.

ServerAdmin info@microlinux.fr
...
  CustomLog "logs/access_log" common
...
AddDefaultCharset off

Éventuellement, on pourra éditer /var/www/html/index.html et remplacer le titre générique Testing 123... de la page par quelque chose de plus parlant, par exemple le domaine hébergé www.slackbox.fr.

Installation

Certbot est fourni par le dépôt EPEL.

$ sudo yum install certbot

On notera au passage que le paquet dépend d’une quantité importante de modules Python.

Plug-ins

Le client Certbot supporte une série de plug-ins pour Apache et Nginx. L’option plugins permet d’afficher les plug-ins installés.

$ certbot plugins

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* standalone
Description: Spin up a temporary webserver
Interfaces: IAuthenticator, IPlugin
Entry point: standalone = certbot.plugins.standalone:Authenticator

* webroot
Description: Place files in webroot directory
Interfaces: IAuthenticator, IPlugin
Entry point: webroot = certbot.plugins.webroot:Authenticator
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Notre installation dispose des plug-ins standalone et webroot.

Tester Certbot et générer un certificat

Pour commencer, nous allons générer un certificat pour le domaine slackbox.fr. Étant donné que la requête utilise le port 80, il faut vérifier si le port est ouvert dans le pare-feu. Le cas échéant, il faudra arrêter le serveur web.

$ sudo systemctl stop httpd

Dans un premier temps, nous allons tester la génération du certificat comme ceci.

$ sudo certbot certonly --non-interactive --email info@microlinux.fr \
  --preferred-challenges http --standalone --agree-tos --renew-by-default \
  --webroot-path /var/www/html -d slackbox.fr -d www.slackbox.fr --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Starting new HTTPS connection (1): acme-staging-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for slackbox.fr
http-01 challenge for www.slackbox.fr
Waiting for verification...
Cleaning up challenges
Resetting dropped connection: acme-staging-v02.api.letsencrypt.org

IMPORTANT NOTES:
 - The dry run was successful.

Pour en savoir un peu plus sur les options utilisées, on peut afficher l’aide de certbot comme ceci.

$ certbot --help all | less

Si tout s’est passé comme prévu, on peut réitérer la commande ci-dessus en omettant l’option --dry-run pour générer le certificat pour de vrai.

$ sudo certbot certonly --non-interactive --email info@microlinux.fr \
  --preferred-challenges http --standalone --agree-tos --renew-by-default \
  --webroot-path /var/www/html -d slackbox.fr -d www.slackbox.fr
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for slackbox.fr
http-01 challenge for www.slackbox.fr
Waiting for verification...
Cleaning up challenges
Resetting dropped connection: acme-v02.api.letsencrypt.org

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/slackbox.fr/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/slackbox.fr/privkey.pem
   Your cert will expire on 2019-06-15. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"

Les fichiers générés se trouvent dans le répertoire /etc/letsencrypt/live/<domaine>. On va donc jeter un oeil.

$ sudo ls -1 /etc/letsencrypt/live/slackbox.fr/
cert.pem  
chain.pem  
fullchain.pem  
privkey.pem
README

À quoi correspondent ces fichiers ?

  • privkey.pem : c’est la clé privée pour le certificat. Ce fichier ne doit surtout pas être divulgué. Le serveur doit pouvoir y accéder pour que SSL/TLS fonctionne. C’est ce qu’Apache utilisera comme fichier SSLCertificateKeyFile.
  • cert.pem : le certificat du serveur. C’est ce qui correspond au SSLCertificateFile d’Apache.
  • chain.pem : les certificats requis par le navigateur hormis le certificat du serveur. Requis par Apache < 2.4.8 pour le SSLCertificateChainFile.
  • fullchain.pem : tous les certificats, y compris celui du serveur. Il s’agit là de la concaténation de chain.pem et de cert.pem. C’est requis par Apache >= 2.4.8 pour le SSLCertificateFile.

Notez qui si l’on ne dispose pas de son propre domaine, on peut très bien créer un certificat propre au nom d’hôte pleinement qualifié de la Dedibox.

$ sudo certbot certonly --non-interactive --email info@microlinux.fr \
  --preferred-challenges http --standalone --agree-tos --renew-by-default \
  --webroot-path /var/www/html -d sd-100246.dedibox.fr

Utiliser et tester le certificat

Pour commencer, on peut mettre en place un hébergement sécurisé avec le serveur Web Apache. La procédure détaillée fait l’objet d’un article à part. Voici la stance correspondante dans la configuration d’Apache.

...
SSLCertificateFile /etc/letsencrypt/live/slackbox.fr/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/slackbox.fr/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/slackbox.fr/fullchain.pem
...

Renouveler un certificat

La durée de vie d’un certificat est de 90 jours, ce qui n’est pas beaucoup. Pour prolonger la validité d’un certificat, il suffit de le renouveler en réinvoquant exactement la même commande utilisée pour le générer initialement.

Révoquer un certificat

Dans certains cas de figure – par exemple lorsqu’on déménage un hébergement vers une autre machine avec une adresse IP différente – il peut être nécessaire de révoquer un certificat avant de le générer ailleurs. On peut le faire comme ceci.

$ sudo certbot --text revoke \
  --cert-path /etc/letsencrypt/live/slackbox.fr/cert.pem

Certificats et permissions

Si l’on souhaite utiliser plusieurs applications sécurisées pour un même domaine (Web, courrier, messagerie XMPP), on se retrouve confronté à un problème de permissions. Concrètement, si le serveur Web ainsi que le serveur de messagerie Prosody doivent accéder en lecture au certificat et à la clé privée, on peut utiliser la solution qui suit.

On crée un groupe système certs, on ajoute les utilisateurs système respectifs à ce groupe et on règle les permissions des fichiers en fonction, c’est-à-dire root:certs. Concrètement :

$ sudo groupadd -g 240 certs
$ sudo chgrp -R certs /etc/letsencrypt
$ sudo chmod -R g=rx /etc/letsencrypt

Si l’on souhaite qu’une application accède au certificat et à la clé privée, il suffit qu’on ajoute l’utilisateur correspondant au groupe système certs. Voici un exemple pour la messagerie XMPP Prosody :

$ sudo usermod -a -G certs prosody

Notez que ce n’est pas la peine d’ajouter l’utilisateur apache au groupe certs. Au démarrage, le serveur Apache s’exécute avec les droits root, puis lance une série de processus enfants avec des droits restreints :

$ ps aux | grep httpd | grep -v grep
root   3168 0.0 0.2 ... /usr/sbin/httpd -DFOREGROUND
apache 3169 0.0 0.2 ... /usr/sbin/httpd -DFOREGROUND
apache 3170 0.0 0.3 ... /usr/sbin/httpd -DFOREGROUND
apache 3171 0.0 0.3 ... /usr/sbin/httpd -DFOREGROUND
apache 3254 0.0 0.3 ... /usr/sbin/httpd -DFOREGROUND

Automatiser la procédure

La procédure de génération et de renouvellement peut être automatisée à l’aide d’un petit script. Voici un exemple.

#!/bin/bash
#
# mkcert.sh
#
# Créer/renouveler un certificat SSL/TLS

# Créer le groupe certs avec le GID 240
if ! grep -q "^certs:" /etc/group ; then
  groupadd -g 240 certs
  echo ":: Ajout du groupe certs."
  sleep 3
fi

# Arrêter Apache
if ps ax | grep -v grep | grep httpd > /dev/null ; then
  echo ":: Arrêt du serveur Apache."
  systemctl stop httpd 1 > /dev/null 2>&1
  sleep 5
fi

# Générer le certificat SSL/TLS
certbot certonly \
  --non-interactive \
  --email info@microlinux.fr \
  --preferred-challenges http \
  --standalone \
  --agree-tos \
  --renew-by-default \
  --webroot-path /var/www/html \
  -d slackbox.fr -d www.slackbox.fr

# Définir les permissions
echo ":: Définition des permissions."
chgrp -R certs /etc/letsencrypt
chmod -R g=rx /etc/letsencrypt

# Démarrer Apache
echo ":: Démarrage du serveur Apache."
systemctl start httpd

À partir de là, on peut définir une tâche automatique (cronjob) pour renouveler le certificat tous les débuts de mois, comme ceci par exemple.

$ sudo crontab -l
# Renouveler le certificat SSL le 1er du mois à 4h30
30 4 1 * * /home/microlinux/bin/mkcert.sh 1> /dev/null

Certificat SAN multi-domaines

Dans certains cas de figure, notamment lorsqu’on met en place le serveur de messagerie Postfix, on peut avoir besoin de regrouper les certificats pour plusieurs domaines dans un seul certificat SAN (Subject Alternative Names). Pour générer un certificat SAN multi-domaine, on pourra adapter le script ci-dessus.

Voici un exemple pour un certificat SAN pour les domaines slackbox.fr et unixbox.fr et les sous-domaines mail.slackbox.fr et mail.unixbox.fr.

# Générer le certificat SSL/TLS
certbot certonly \
  --non-interactive \
  --email info@microlinux.fr \
  --preferred-challenges http \
  --standalone \
  --agree-tos \
  --renew-by-default \
  --webroot-path /var/www/slackbox-site/html \
  -d slackbox.fr -d www.slackbox.fr \
  --webroot-path /var/www/slackbox-mail/html \
  -d mail.slackbox.fr \
  --webroot-path /var/www/unixbox-site/html \
  -d www.unixbox.fr -d unixbox.fr \
  --webroot-path /var/www/unixbox-mail/html \
  -d mail.unixbox.fr

Le cas de figure domaine-0001

Il peut arriver qu’on soit confronté à la création d’un répertoire domaine-0001 dans /etc/letsencrypt/live, par exemple suite à la suppression d’un sous-domaine pour un certificat SAN. Du coup les chemins vers les certificats ne sont plus valides, et c’est une belle pagaille.

La manière la plus simple de rectifier le tir pour récupérer une configuration consiste à faire le ménage « à la louche ».

  1. Révoquer tous les certificats.
  2. Supprimer le répertoire /etc/letsencrypt et tout son contenu.
  3. Relancer le script pour générer les certificats.

Téléchargement

Un modèle de script mkcert.sh est disponible au téléchargement dans mon dépôt Github, dans le répertoire el7/config/certbot.

$ git clone https://github.com/kikinovak/centos

0 commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.