Cet 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…
- en utilisant Certbot, le client Let’s Encrypt ;
- en générant un certificat auto-signé.
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).
- Installation
- Tester Certbot et générer un certificat
- Utiliser et tester le certificat
- Renouveler un certificat
- Révoquer un certificat
- Certificats et permissions
- Automatiser la procédure
- Certificat SAN multi-domaines
- Le cas de figure domaine-0001
Installation
Certbot est fourni par le dépôt EPEL.
$ sudo yum install certbot
Le paquet dépend d’une quantité importante de modules Python.
Tester Certbot et générer un certificat
Pour commencer, je vais générer un certificat pour le domaine slackbox.fr
. Étant donné que la requête utilise le port 80, je vérifie 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, je vais 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 fichierSSLCertificateKeyFile
.cert.pem
: le certificat du serveur. C’est ce qui correspond auSSLCertificateFile
d’Apache.chain.pem
: les certificats requis par le navigateur hormis le certificat du serveur. Requis par Apache < 2.4.8 pour leSSLCertificateChainFile
.fullchain.pem
: tous les certificats, y compris celui du serveur. Il s’agit là de la concaténation dechain.pem
et decert.pem
. C’est requis par Apache >= 2.4.8 pour leSSLCertificateFile
.
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 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, serveur FTP, 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 shell. Voici un exemple très simple.
#!/bin/bash # # mkcert.sh # Create certs group if ! grep -q "^certs:" /etc/group then echo "Adding group certs with GID 240." groupadd -g 240 certs fi # Stop Apache if ps ax | grep -v grep | grep httpd > /dev/null then echo "Stopping Apache server." systemctl stop httpd 1 > /dev/null 2>&1 fi # Generate SSL/TLS certificate 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 # Set permissions echo "Setting permissions." chgrp -R certs /etc/letsencrypt chmod -R g=rx /etc/letsencrypt # Start Apache echo "Starting Apache server." systemctl start httpd exit 0
À 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
# Renew SSL certificate every first day of the month at 4:30
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-domaines, 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
.
# Generate SSL/TLS certificate
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 ».
- Révoquer tous les certificats.
- Supprimer le répertoire
/etc/letsencrypt
et tout son contenu. - Relancer le script pour générer les certificats.
Pour aller plus loin
Le script de génération de certificats proposé ci-dessus est assez rudimentaire. Je propose un script plus élaboré qui permet une gestion plus confortable des certificats SSL/TLS sur un serveur dédié.
La rédaction de cette documentation demande du temps et des quantités significatives de café espresso. Vous appréciez ce blog ? Offrez un café au rédacteur en cliquant sur la tasse.
9 commentaires
Patrick B · 20 mars 2020 à 19 h 56 min
Bonjour,
Merci pour ce billet et celui sur la configuration d’apache et SSL, qui tombent tous deux à pic pour moi (même si je suis sur openSUSE) !
Une question : dans l’exemple donné, l’option –webroot-path est-elle vraiment nécessaire ? Elle semble s’appliquer uniquement dans le cas où cerbot utilise un serveur web existant et donc avec l’option –webroot. Ici c’est le mode standalone qui est utilisé, non ?
kikinovak · 21 mars 2020 à 8 h 33 min
Bonne question. Je vais explorer ça.
Mosby · 23 juillet 2020 à 11 h 00 min
Bonjour,
Je développe un site pour un intranet, et lorsque je rentre la commande suivante
certbot certonly –non-interactive –email mon@email –preferred-challenges http –standalone –agree-tos –renew-by-default –webroot-path /var/www/mon/repertoire/html/ -d mon.domaine.fr -d www. mon.domaine.fr –dry-run
Le message d’erreur suivant apparait :
An unexpected error occurred:
ConnectionError: (‘Connection aborted.’, gaierror(-2, ‘Name or service not known’))
J’ai appelé mon administrateur afin qu’il fasse un enregistrement DNS pour que mon.domaine.fr soit accessible (j’accède au site par IP actuellement depuis un navigateur web, et administre le serveur a distance via PUTTY.)
Pouvez-vous me confirmer que pour un intranet, lorsque que le nom de domaine sera enregistré, l’exécution de la commande se fera correctement ?
J’apprécierai d’utiliser certbot.
Existe-t-il des option qui se passent du nom de domaine en utilisant l’adresse IP ?
Peut-on ne pas spécifier de nom de domaine ?
Bien à vous
kikinovak · 23 juillet 2020 à 11 h 12 min
Est-ce que votre domaine est publiquement accessible ?
Mosby · 24 juillet 2020 à 9 h 30 min
Non
kikinovak · 24 juillet 2020 à 9 h 31 min
Dans ce cas vous ne pouvez pas utiliser Certbot. Vous devrez passer par un certificat auto-signé avec OpenSSL.
Mosby · 24 juillet 2020 à 9 h 48 min
Entendu, merci pour votre réponse !
Mickael · 14 décembre 2020 à 18 h 33 min
Bonjour…Quelle est la fonction exacte du webroot-path et est t’il obligatoire ?
Si mon site est /var/www/html/mickael, le webroot-path sera var/www/html/mickael ou var/www/html ?
Cdt
kikinovak · 14 décembre 2020 à 20 h 34 min
Le
--webroot-path
est censé indiquer la racine du site correspondant au certificat du sous-domaine. Ceci étant dit, j’ai expérimenté un peu, et c’est assez permissif. On pourrait théoriquement indiquer/var/www
pour tous les sous-domaines, et ça fonctionnerait. Pour ma part, j’aime bien l’indiquer dans mon script de génération de certificat pour plus de clarté.Les commentaires sont fermés.