Certificats SSL/TLS avec Certbot sous Slackware

Cet article décrit la gestion des certificats SSL/TLS gratuits sur un serveur dédié tournant sous Slackware Linux. 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 Verisign 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).

Installation

Le portail SlackBuilds.org fournit un script pour construire et installer le paquet letsencrypt. Il dépend d’une quantité importante de modules Python. Sur mes serveurs tournant sous Slackware64 14.0, 14.1 et 14.2, j’ai dû en installer pas moins de vingt-huit. Les dépendances sont toutes disponibles sur SlackBuilds.org.

Voici l’ordre dans lequel on peut construire les paquets :

  1. psutil
  2. pysetuptools [1]
  3. pytz
  4. python-future
  5. werkzeug
  6. mock
  7. configobj
  8. pyparsing
  9. zope.interface
  10. zope.event
  11. zope.component
  12. pycparser
  13. ipaddress
  14. enum34
  15. six
  16. idna
  17. cffi
  18. pyasn1
  19. cryptography
  20. pyOpenSSL
  21. ndg_httpsclient
  22. python2-pythondialog
  23. augeas
  24. python-augeas
  25. python-requests
  26. pyrfc3339
  27. python-parsedatetime
  28. python-configparse
  29. letsencrypt

[1] Depuis la version 14.2, Slackware inclut le paquet python-setuptools.

Plug-ins

Le client Certbot supporte une série de plug-ins pour Apache et Nginx. Pour l’instant, ces plug-ins fonctionnent uniquement sous Debian. On se contentera donc du plug-in standalone, qui fonctionne très bien sous Slackware.

Afficher les plug-ins installés :

# certbot --text plugins
Saving debug log to /var/log/letsencrypt/letsencrypt.log
* webroot
Description: Place files in webroot directory
Interfaces: IAuthenticator, IPlugin
Entry point: webroot = certbot.plugins.webroot:Authenticator

* standalone
Description: Spin up a temporary webserver
Interfaces: IAuthenticator, IPlugin
Entry point: standalone = certbot.plugins.standalone:Authenticator
  • L’option --text spécifie la sortie au format texte simple au lieu d’utiliser l’interface NCurses.

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 443, il faut d’abord arrêter le serveur Web. En passant, il faudra éventuellement vérifier si le port 443 est bien ouvert dans le pare-feu.

# /etc/rc.d/rc.httpd stop

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

# certbot --text certonly --preferred-challenges tls-sni-01 \
  --email info@microlinux.fr --renew-by-default --agree-tos \
  --standalone -d www.slackbox.fr -d slackbox.fr \
  --webroot-path /srv/httpd/vhosts/slackbox-secure/htdocs \
  --test-cert

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Renewing an existing certificate
Performing the following challenges:
tls-sni-01 challenge for www.slackbox.fr
tls-sni-01 challenge for slackbox.fr
Waiting for verification...
Cleaning up challenges
Generating key 2048 bits /etc/letsencrypt/keys/0005_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0005_csr-certbot.pem

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
 /etc/letsencrypt/live/www.slackbox.fr/fullchain.pem. Your cert will
 expire on 2017-05-04. 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"

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 --test-cert pour générer le certificat pour de vrai.

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

# ls -1 /etc/letsencrypt/live/www.slackbox.fr/
cert.pem  
chain.pem  
fullchain.pem  
privkey.pem

À 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.

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 :

# /etc/httpd/extra/httpd-ssl.conf 

DocumentRoot "/srv/httpd/vhosts/slackbox-secure/htdocs"
...
SSLCertificateFile "/chemin/vers/cert.pem"
SSLCertificateKeyFile "/chemin/vers/privkey.pem"
SSLCertificateChainFile "/chemin/vers/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.

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 :

# groupadd -g 240 certs
# chgrp -R certs /etc/letsencrypt
# 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. Exemple pour la messagerie XMPP Prosody :

# 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 -k start
apache 3169 0.0 0.2 ... /usr/sbin/httpd -k start
apache 3170 0.0 0.3 ... /usr/sbin/httpd -k start
apache 3171 0.0 0.3 ... /usr/sbin/httpd -k start
apache 3254 0.0 0.3 ... /usr/sbin/httpd -k start

Automatiser la procédure

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

#!/bin/bash
#
# Create/renew SSL/TLS certificates for slackbox.fr

DOMAIN="slackbox.fr"
DIRNAM="slackbox"
CERTBOT="/usr/bin/certbot"
CHGRP="/usr/bin/chgrp"
CHMOD="/usr/bin/chmod"
CERTGRP="certs"
EMAIL="info@microlinux.fr"
OPTIONS="certonly \
         --preferred-challenges tls-sni-01 \
         --email $EMAIL \
         --renew-by-default \
         --agree-tos \
         --text \
         --standalone"

# Create $CERTGRP group 
if ! grep -q "^$CERTGRP:" /etc/group ; then
  groupadd -g 240 $CERTGRP
  echo ":: Added $CERTGRP group."
  sleep 3
fi

# Stop Apache
echo ":: Stopping Apache."
if ps ax | grep -v grep | grep httpd > /dev/null ; then
  /etc/rc.d/rc.httpd stop 1 > /dev/null 2>&1
  sleep 5
fi

$CERTBOT $OPTIONS -d www.$DOMAIN -d $DOMAIN \
  --webroot-path /srv/httpd/vhosts/$DIRNAM-secure/htdocs

$CERTBOT $OPTIONS -d mail.$DOMAIN \
  --webroot-path /srv/httpd/vhosts/$DIRNAM-webmail/htdocs

$CERTBOT $OPTIONS -d cloud.$DOMAIN \
  --webroot-path /srv/httpd/vhosts/$DIRNAM-owncloud/htdocs

# Fix permissions
echo ":: Setting permissions."
$CHGRP -R $CERTGRP /etc/letsencrypt
$CHMOD -R g=rx /etc/letsencrypt

# Start Apache
echo ":: Starting Apache."
/etc/rc.d/rc.httpd start

Si l’on range ce script dans /etc/cron.monthly/, les certificats sont renouvelés tous les 1er du mois à 4h20 du matin.

Certificat SAN multi-domaines

Dans certains cas de figure, 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.

HOST=$(/bin/hostname --fqdn)
CERTBOT="/usr/bin/certbot"
CHGRP="/usr/bin/chgrp"
...
$CERTBOT $OPTIONS \
  --webroot-path /srv/httpd/vhosts/default/htdocs \
  -d $HOST \
  --webroot-path /srv/httpd/vhosts/slackbox-secure/htdocs \
  -d www.slackbox.fr -d slackbox.fr \
  --webroot-path /srv/httpd/vhosts/slackbox-webmail/htdocs \
  -d mail.slackbox.fr \
  --webroot-path /srv/httpd/vhosts/unixbox-secure/htdocs \
  -d www.unixbox.fr -d unixbox.fr \
  --webroot-path /srv/httpd/vhosts/unixbox-webmail/htdocs \
  -d mail.unixbox.fr

Le certificat résultant sera stocké dans /etc/letsencrypt/live, dans le répertoire correspondant au FQDN du serveur, en l’occurrence sd-41893.dedibox.fr. Malheureusement, on a de fortes chances de tomber sur une erreur du style Too many certificates already issued for domain dedibox.fr, comme quoi d’autres ont eu la même idée avant nous. On devra donc remplacer le nom d’hôte du serveur par quelque chose d’autre.

HOST=bacasable.microlinux.eu
CERTBOT="/usr/bin/certbot"
CHGRP="/usr/bin/chgrp"

Révoquer un certificat

Si jamais, pour une raison ou pour une autre, on a besoin de révoquer un certificat, on peut le faire comme ceci.

# cd /etc/letsencrypt/live
# certbot --text revoke --cert-path chemin/vers/cert.pem

 

Ce contenu a été publié dans Documentation Microlinux, Slackware, avec comme mot(s)-clé(s) , , , , , . Vous pouvez le mettre en favoris avec ce permalien.

6 réponses à Certificats SSL/TLS avec Certbot sous Slackware

  1. Willy Sudiarto Raharjo dit :

    You need python-future as well as part of python-parsedatetime dep

    • kikinovak dit :

      Is this a new dependency introduced with a more recent version of python-parsedatetime? I’m asking out of curiosity, because I don’t have python-future on my server, and Certbot works perfectly.

  2. Didier COURTAUD dit :

    I try to install the twenty seven dependencies you have listed in this article to install certbot on my Slack 14.2 computer.

    1 ) psutil : OK

    2) pysetuptools

    I looked for it on the Slackbuild Web site but I cannot find it for the 14.2 version

    Moreover it is not in the list of dependencies of Willy on the letsencrypt slackbuild page !

    Where is the mistake ? Not available for 14.2 or not necessary for 14.2 ?

    In any case thanks a lot for your documentation on this blog !

    • kikinovak dit :

      Vous pouvez commenter en français, vu que c’est un blog francophone. :o)
      L’article a initialement été rédigé sous Slackware 14.1. Or, depuis la version 14.2, Slackware inclut officiellement le paquet python-setuptools. J’ai ajouté une petite note à l’article.

  3. Didier COURTAUD dit :

    Bonjour

    J’ai bien installé les 27 dépendances de letsencrypt puis letsencrypt lui -même sur ma machine sous Slack 14.2.
    Mais , comme le dit Willy Sudiarto Raharjo, il semble qu’il faille aussi python-future :

    root@pegase:~# certbot –text plugins
    Traceback (most recent call last):
    File « /usr/bin/certbot », line 5, in
    from pkg_resources import load_entry_point
    File « /usr/lib64/python2.7/site-packages/pkg_resources/__init__.py », line 2927, in
    @_call_aside
    File « /usr/lib64/python2.7/site-packages/pkg_resources/__init__.py », line 2913, in _call_aside
    f(*args, **kwargs)
    File « /usr/lib64/python2.7/site-packages/pkg_resources/__init__.py », line 2940, in _initialize_master_working_set
    working_set = WorkingSet._build_master()
    File « /usr/lib64/python2.7/site-packages/pkg_resources/__init__.py », line 635, in _build_master
    ws.require(__requires__)
    File « /usr/lib64/python2.7/site-packages/pkg_resources/__init__.py », line 943, in require
    needed = self.resolve(parse_requirements(requirements))
    File « /usr/lib64/python2.7/site-packages/pkg_resources/__init__.py », line 829, in resolve
    raise DistributionNotFound(req, requirers)
    pkg_resources.DistributionNotFound: The ‘future’ distribution was not found and is required by parsedatetime

    • kikinovak dit :

      Merci pour le rapport d’erreurs. Effectivement, python-future est une nouvelle dépendance. Je l’ai ajouté à la liste.

Laisser un commentaire

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