Let's Encrypt est une nouvelle autorité de certification qui délivre des certificats SSL gratuits. Oui, j'ai bien dit gratuit, là où auparavant il fallait parfois débourser jusqu'à une centaine d'euros par an pour un certificat !
Mais désormais, il n'y a plus aucune raison pour ne pas laisser tomber son certificat auto-signé et mettre en place le HTTPS avec un véritable certificat SSL, certifié par une autorité, et qui n'affichera donc pas dans les navigateurs une page d'alerte qui ferait fuir vos visiteurs.
Dans cet article, je vais donc vous présenter la méthode que j'ai utilisée pour mettre en place un certificat SSL gratuit de Let's Encrypt sur mon VPS.
Le site de Let's Encrypt suggère pour cela d'utiliser le client Python officiel, totalement automatisé. Mais personnellement, je ne suis pas très fan de l'idée qu'un script, dont j'ignore le contenu, s’exécute automatiquement avec les permissions root, manipule des fichiers de configurations sensibles (tel que ceux d'Apache), et contrôle la sécurité de mon serveur Web.
De plus, le script officiel requiert selon moi beaucoup trop de dépendances à installer, et propose trop de fonctionnalités par rapport à ce qui m'est réellement utile. Je suis en effet totalement capable de faire l'installation et la configuration initiale moi-même, manuellement. Je n'ai besoin d'un script que pour renouveler automatiquement le certificat, rien de plus.
Je suis donc parti à la recherche d'une solution alternative pour obtenir un certificat Let's Encrypt, et je suis finalement tombé sur acme-tiny. C'est un script de seulement 200 lignes, que j'ai donc pu facilement analyser pour vérifier qu'il ne comportait rien de malveillant, et qui n'a besoin que de Python, quelques modules de base et la commande openssl
pour fonctionner. Le plus souvent, tout ceci est déjà présent sur une configuration classique.
La méthode proposée ci dessous est adaptée pour obtenir une sécurité optimale sur un serveur Debian Wheezy ou Jessie, avec Apache 2.2 ou 2.4.10, et OpenSSL 1.0.1. Il est toutefois important que vous compreniez ce que vous faites et que vous ajustiez la configuration proposée selon votre système et vos besoins.
Préparation du serveur
Vérification des prérequis
On commence par quelques petites vérifications et préparations sur le serveur. Tout d'abord, on s'assure que Python 2.7.x est bien installé en utilisant la commande suivante :
python --version
Si vous obtenez un message command not found, il vous faudra passer par la case installation de Python avant de poursuivre.
Profitez en également pour récupérer la version d'Apache et d'OpenSSL installée sur votre système respectivement avec les commandes ci-dessous :
sudo apache2ctl -v openssl version
Création d'un utilisateur dédié
A partir de ce point, je vous conseille de passer une bonne fois pour toute en root, car la plupart des commandes qui vont suivre vont nécessiter ces permissions pour fonctionner. Pour cela, vous pouvez utiliser la commande sudo -i
.
On va maintenant créer un utilisateur letsencrypt
, auquel on attribuera le strict minimum de permissions pour pouvoir créer et renouveler des certificats. Cet utilisateur sera responsable de l'exécution du script de renouvellement automatique, que nous verrons plus bas. Ainsi, ce script ne s'exécutera pas en root et ne pourra pas modifier accidentellement des fichiers importants du système. On créé également un dossier pour contenir tous les fichiers associés à Let's Encrypt :
mkdir /etc/letsencrypt adduser --system --home /etc/letsencrypt --no-create-home --disabled-login \ --disabled-password --group letsencrypt
On créé ensuite un ensemble de sous-dossiers pour bien ranger les choses :
- bin : Dossier stockant les scripts acme-tiny et de renouvellement automatique.
- certs : Contiendra les certificats, rangés par date d'obtention dans un sous-dossier archive, avec un lien symbolique live pointant vers le dossier contenant les certificats actuellement utilisés.
- private : Les clés privées, ne devant absolument pas être divulguées, seront dans ce dossier avec le minimum de permissions.
- challenges : Ce dossier sera utilisé pour déposer les fichiers temporaires nécessaires pour valider votre demande de certificats.
Voici les commandes à lancer pour créer tous ces dossiers :
cd ~letsencrypt mkdir -p ~letsencrypt/{bin,certs/archive/$(date --utc +'%FT%TZ'),private,challenges}
Sans plus attendre, on ajuste quelques permissions sur les dossiers que l'on vient de créer :
chown -R letsencrypt:letsencrypt ~letsencrypt chown letsencrypt:www-data ~letsencrypt/challenges chmod 755 ~letsencrypt chmod -R 775 ~letsencrypt/certs chmod 750 ~letsencrypt/{bin,private,challenges}
Ensuite, on créé le lien symbolique pointant vers le dossier des certificats en cours d'usage. L'intérêt de ce lien est qu'ainsi le script de renouvellement ne modifiera pas directement les fichiers en production. Il créera plutôt un nouveau dossier, où il préparera tout le nécessaire, et ne redirigera le lien qu'une fois terminé et en l'absence d'erreur.
ln -s archive/$(date --utc +'%FT%TZ') ~letsencrypt/certs/live
Autoriser l'utilisateur letsencrypt
à redémarrer Apache
Lors du renouvellement automatique du certificat, le script doit être en mesure de pouvoir redémarrer Apache afin que le nouveau certificat soit pris en compte. Pour cela, on va autoriser l'utilisateur letsencrypt
à faire un sudo
sans mot de passe, mais seulement sur la commande permettant de redémarrer Apache.
Pour cela, on créé et on édite un nouveau fichier sudoers avec la commande ci-dessous :
visudo -f /etc/sudoers.d/letsencrypt-apache2ctl-graceful
Dans ce nouveau fichier, on écrit le contenu suivant :
letsencrypt ALL=NOPASSWD: /usr/sbin/apache2ctl graceful
Ainsi, l’utilisateur letsencrypt
, et donc le script de renouvellement, peut désormais lancer la commande sudo apache2ctl graceful
sans mot de passe.
Téléchargement du script acme-tiny
On termine l'étape de préparation du serveur en récupérant une copie du script acme-tiny
permettant d'obtenir le certificat Let's Encrypt avec la commande suivante :
wget -O ~letsencrypt/bin/acme_tiny.py https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py
Préparation de Apache
Durant le processus d'obtention du certificat, il faut prouver à Let's Encrypt que l'on a bien le contrôle administratif du domaine pour lequel on fait la demande. Pour cela, Let's Encrypt va nous demander d'héberger temporairement un fichier particulier à une adresse précise.
Ce fichier sera déposé par le script acme-tiny
dans le dossier /etc/letsencrypt/challenges
, qui doit être accessible par le web à l'adresse http://mondomaine.fr/.well-known/acme-challenge
.
Pour cela, il est nécessaire de modifier quelque peu la configuration d'Apache, selon la version que vous utilisez.
Apache 2.4
Pour Apache 2.4, on commence par créer un nouveau fichier de configuration :
vi /etc/apache2/conf-available/letsencrypt.conf
Dans celui-ci, on écrit le contenu suivant :
Alias "/.well-known/acme-challenge" "/etc/letsencrypt/challenges" # Retourne un code 404 plutot que Forbidden lorsque l'on tente d'acceder au dossier RedirectMatch 404 ^/.well-known/acme-challenge(/$|$) <Directory "/etc/letsencrypt/challenges"> Options None AllowOverride None Require all granted <IfModule mod_headers.c> Header set Content-Type "application/jose+json" </IfModule> </Directory>
On active ensuite cette nouvelle configuration avec les commandes ci-dessous :
a2enconf letsencrypt apache2ctl graceful
Apache 2.2
Sur Apache 2.2, on créé un nouveau fichier de configuration global :
vi /etc/apache2/conf.d/letsencrypt
Dans ce dernier, on dispose le contenu suivant :
Alias "/.well-known/acme-challenge" "/etc/letsencrypt/challenges" # Retourne un code 404 plutot que Forbidden lorsque l'on tente d'acceder au dossier RedirectMatch 404 ^/.well-known/acme-challenge(/$|$) <Directory "/etc/letsencrypt/challenges"> Options None AllowOverride None Order allow,deny Allow from all <IfModule mod_headers.c> Header set Content-Type "application/jose+json" </IfModule> </Directory>
Puis on redémarre le serveur Apache pour prendre en compte les changements :
apache2ctl graceful
Vérification de l'accessibilité du dossier
Une fois la configuration d'Apache appliquée, on peut ensuite vérifier que le dossier de challenge est bien accessible sur le Web. Pour cela, créez un fichier de test à l'intérieur :
echo "Hello World" > ~letsencrypt/challenges/test.txt
Assurez-vous ensuite que vous pouvez récupérer ce fichier depuis un navigateur Web à l'adresse http://mondomaine.fr/.well-known/acme-challenge/test.txt
(en remplaçant évidemment par votre propre nom de domaine). Si ce n'est pas le cas, vérifiez la configuration. Sinon, vous pouvez supprimer le fichier de test et passer à la suite :
rm ~letsencrypt/challenges/test.txt
Installation de Let's Encrypt
Création des clés
L'étape suivante consiste à générer un ensemble de clés et de fichiers nécessaires à Let's Encrypt pour vous authentifier et générer le certificat. En effet, il n'est pas nécessaire d'ouvrir un compte ni même de fournir des informations personnelles pour obtenir un certificat auprès de ce service. Let's Encrypt demande seulement une clé utilisateur pour vous reconnaître.
On commence donc par créer cette première clé d'une longueur de 4096 bits. Cette clé peut être partagée entre plusieurs serveurs, mais doit toujours rester parfaitement en sécurité.
openssl genrsa 4096 > ~letsencrypt/private/account.key
Puis on génère la clé privée du certificat. Cette clé doit obligatoirement être différente de la clé utilisateur et doit impérativement être gardée secrète !
openssl genrsa 4096 > ~letsencrypt/private/domain.key
On poursuit en créant la demande de signature de certificat (CSR), qui sera envoyée à Let's Encrypt par le protocole ACME pour faire générer le certificat. Pour cela, il y a deux possibilités. Soit votre certificat n'est utilisé que par un seul domaine, et dans ce cas vous utiliserez la commande suivante, en remplaçant bien sûr mondomaine.fr
par votre propre domaine :
openssl req -new -sha256 -key ~letsencrypt/private/domain.key \ -subj "/CN=mondomaine.fr" > ~letsencrypt/private/domain.csr
Soit vous partagez le même certificat sur plusieurs domaines (mondomaine.fr
et www.mondomaine.fr
par exemple), et il vous faut alors utiliser l'extension SAN (Subjet Alternative Names) dans la CSR :
openssl req -new -sha256 -key ~letsencrypt/private/domain.key -subj "/" -reqexts SAN \ -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:mondomaine.fr,DNS:www.mondomaine.fr")) > ~letsencrypt/private/domain.csr
Vous pouvez alors inclure autant de domaines que vous souhaitez simplement en ajoutant une entrée DNS:autredomaine.fr
par domaine.
Obtention du certificat
Nous y voici enfin, il est temps d'obtenir ce fameux certificat SSL gratuit ! Il vous suffit pour cela de lancer la commande suivante :
sudo -u letsencrypt -- python ~letsencrypt/bin/acme_tiny.py \ --account-key ~letsencrypt/private/account.key --csr ~letsencrypt/private/domain.csr \ --acme-dir ~letsencrypt/challenges/ > ~letsencrypt/certs/live/signed.crt
Si tout se passe bien, vous devriez obtenir un nouveau fichier signed.crt, c'est votre certificat !
Pour qu'il puisse être utilisé, il faut encore récupérer le certificat intermédiaire de Let's Encrypt et construire le certificat chainé :
sudo -u letsencrypt -- wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > ~letsencrypt/certs/live/intermediate.pem sudo -u letsencrypt -- cat ~letsencrypt/certs/live/signed.crt ~letsencrypt/certs/live/intermediate.pem > ~letsencrypt/certs/live/chained.pem
Installation du certificat sur Apache
L'étape suivante consiste à configurer Apache afin d'utiliser les certificats fraîchement obtenus.
Je vous propose ci-dessous un exemple de configuration, libre à vous de l'ajuster en fonction de vos besoins, du niveau de sécurité souhaité et de la compatibilité nécessaire avec les navigateurs de vos visiteurs. Vous pouvez vous aider pour cela du générateur de configuration proposé par Mozilla.
Si vous souhaitez en savoir plus sur la configuration SSL avancée sur Apache, je vous conseille les pages suivantes (en anglais) :
- Strong SSL Security on Apache 2
- Hardening Your Web Server's SSL Ciphers
- Mozilla Wiki : Server Side TLS
Apache 2.4
Sur Apache 2.4, il faut modifier le fichier /etc/apache2/mods-available/ssl.conf
afin d'y insérer les directives suivantes :
SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS SSLHonorCipherOrder on SSLProtocol all -SSLv3 SSLCompression off SSLSessionTickets off # OCSP Stapling SSLUseStapling on SSLStaplingResponderTimeout 5 SSLStaplingReturnResponderErrors off SSLStaplingCache shmcb:/var/run/ocsp(128000)
Puis, pour chaque virtual host, il faut ajouter les lignes suivantes dans le fichier de configuration situé sous /etc/apache2/site-available/
:
<VirtualHost *:443> ... SSLEngine on SSLCertificateFile /etc/letsencrypt/certs/live/chained.pem SSLCertificateKeyFile /etc/letsencrypt/private/domain.key ... </VirtualHost>
Apache 2.2
Pour Apache 2.2, le fichier /etc/apache2/mods-available/ssl.conf
devra contenir les lignes suivantes :
SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS SSLHonorCipherOrder on SSLProtocol all -SSLv3 -SSLv2
Ensuite, pour chaque virtual host, on ajoute les lignes de configuration suivantes :
<VirtualHost *:443> ... SSLEngine on SSLCertificateFile /etc/letsencrypt/certs/live/signed.crt SSLCertificateKeyFile /etc/letsencrypt/private/domain.key SSLCertificateChainFile /etc/letsencrypt/certs/live/intermediate.pem ... </VirtualHost
Une fois la configuration appliquée, quelle que soit la version d'Apache, il faudra bien sûr lui demander de recharger sa configuration avec la commande apache2ctl graceful
.
Automatisation du renouvellement
Le seul inconvénient des certificats gratuits émis par Let's Encrypt est qu'ils ne sont valables que pour 90 jours. Je ne sais pas vous, mais je n'est pas très envie de devoir me connecter sans cesse sur mes serveurs pour faire le renouvellement. C'est pourquoi nous devons automatiser cela avec un petit script et une tâche cron.
On va donc créer un script de renouvellement automatique dans le dossier /etc/letsencrypt/bin
, que l'on nommera par exemple le-renew.sh
.
vi ~letsencrypt/bin/le-renew.sh
Pour le contenu du script, je vous propose cet exemple qui ne renouvellera le certificat que lorsque la date d'expiration approche, mais là encore vous pouvez bien entendu le personnaliser. L'essentiel est de relancer le script acme-tiny
avec les mêmes paramètres que lors de la création initiale du certificat, puis de reconstruire le certificat chainé et de redémarrer Apache.
#!/bin/bash # Configure le nombre de jours en dessous duquel le certificat doit être renouvelé. RENEW=15 # Récupère le timestamp actuel NOW=$(date +%s) # Récupère la date d'expiration du certificat actuel EXPIRE=$(openssl x509 -in ~letsencrypt/certs/live/signed.crt -noout -enddate) EXPIRE=${EXPIRE:9} # Convertit la date d'expiration en un timestamp EXPIRE=$(date --date="$EXPIRE" +%s) # Calcul le temps restant avant l'expiration du certificat LIFE=$(($EXPIRE - $NOW)) # Si la durée de vie restante est en dessous du minimum demandé. if [ "$LIFE" -lt "$(( $RENEW * 86400 ))" ]; then DATE="$(date --utc +'%FT%TZ')" mkdir --mode=775 ~letsencrypt/certs/archive/$DATE python ~letsencrypt/bin/acme_tiny.py --account-key ~letsencrypt/private/account.key --csr ~letsencrypt/private/domain.csr --acme-dir ~letsencrypt/challenges/ > ~letsencrypt/certs/archive/$DATE/signed.crt || exit wget -O ~letsencrypt/certs/archive/$DATE/intermediate.pem https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem cat ~letsencrypt/certs/archive/$DATE/signed.crt ~letsencrypt/certs/archive/$DATE/intermediate.pem > ~letsencrypt/certs/archive/$DATE/chained.pem chmod 644 ~letsencrypt/certs/archive/$DATE/{chained.pem,intermediate.pem,signed.crt} rm ~letsencrypt/certs/live ln -s archive/$DATE ~letsencrypt/certs/live sudo apache2ctl graceful fi
Je vous propose également une version plus avancée de ce script sur Gist, avec une meilleure gestion des erreurs et des logs, qui peut ensuite être combiné à LogWatch et LogRotate par exemple. A vous de faire votre choix !
Créez ensuite un dossier supplémentaire dédié au stockage des journaux d'exécution (logs):
mkdir /var/log/letsencrypt chown letsencrypt:adm /var/log/letsencrypt chmod 2755 /var/log/letsencrypt
Il ne reste plus qu'à créer une tâche cron qui exécutera le script avec l'utilisateur letsencrypt
. Pour cela, plusieurs solutions, vous pouvez par exemple ajouter un fichier crontab dans le dossier /etc/cron.d/
:
vi /etc/cron.d/letsencrypt
Dans ce fichier, vous placerez le contenu suivant :
# Renouvellement automatique du certificat Let's Encrypt # Tous les dimanches à 3H00 0 3 * * 0 letsencrypt /etc/letsencrypt/bin/le-renew.sh 2>> /var/log/letsencrypt/letsencrypt.log
Le script sera alors exécuté tous les dimanches à 3H00. Vous pouvez bien sûr ajuster cette fréquence, mais il est préférable de le faire tourner assez souvent de sorte à ce que plusieurs tentatives puissent avoir lieu durant les 90 jours de validité du certificat.
Fermeture des écoutilles
Il reste encore à ajuster quelques permissions pour renforcer la sécurité des fichiers sensibles et n'autoriser que le strict minimum.
On commence par changer le propriétaire et les permissions des deux scripts, de sorte que seul root
puisse écrire dedans, et le groupe letsencrypt
puisse les lire et les exécuter :
chown root:letsencrypt ~letsencrypt/bin/{acme_tiny.py,le-renew.sh} chmod 750 ~letsencrypt/bin/{acme_tiny.py,le-renew.sh}
Maintenant, nous allons réduire les permissions sur les clés privés. L'utilisateur letsencrypt
a simplement besoin de lire la clé utilisateur (account.key
) et la demande de signature (domain.csr
). Il ne doit pas pouvoir accéder à la clé privée du certificat (domain.key
), qui ne doit être accessible que par root
.
chown root:letsencrypt ~letsencrypt/private/{account.key,domain.csr,domain.key} chmod 640 ~letsencrypt/private/{account.key,domain.csr} chmod 600 ~letsencrypt/private/domain.key
Enfin, on fait en sorte que les certificats soient lisibles par tous, mais que seul l'utilisateur letsencrypt
puisse les écrire :
chown letsencrypt:letsencrypt ~letsencrypt/certs/live/{chained.pem,intermediate.pem,signed.crt} chmod 644 ~letsencrypt/certs/live/{chained.pem,intermediate.pem,signed.crt}
Conclusion
Félicitations, votre serveur est maintenant doté d'un certificat gratuit validé par une autorité de certification ! Pour vous assurez qu'il offre une sécurité optimale, je vous conseille de valider votre configuration sur un service tel que SSLLabs. Avec la configuration proposée ici, vous devriez obtenir sans peine une note A voire A+, ce qui est très satisfaisant.
Si vous avez une amélioration ou une correction à apporter à cette méthode, n'hésitez pas à la proposer dans un commentaire !
Salut Kévin, déjà très bel article
Je pense que je vais l'utiliser pour un projet perso.
Cependant, je me demande qu'en est il de la durée de validité de ce certificat.
J'ai lu par ailleurs qu'il était valide uniquement 90 jours, si c'est le cas, est ce que le script assure lui même le renouvellement ou faut le faire à la main ?
Hello !
L'article est un peu long, mais assez complet je pense : toutes les réponses y sont déjà écrites
Effectivement le certificat généré est valide pour 90 jours. Si tu parles du script que je propose, je te conseille de relire le paragraphe "Automatisation du renouvellement", où il est écrit comment faire la tâche cron pour automatiser le renouvellement.
Si tu parles plutôt du script "officiel", alors je ne saurais trop te dire (vu que je ne l'ai pas utilisé ^^), mais je dirais qu'il faut aussi faire une tâche cron.
En ce qui me concerne, sur mon VPS et avec le script maison que j'ai déposé sur Gist, je ne m'occupe plus de rien et je reçois même les logs sur ma boîte mail via Logwatch !
Oups, j'avais lu cette section en diagonale, je parlais bien évidemment du script officiel
Je suis un peu comme toi, réticent à installer une usine à gaz dont tu as peu de contrôle et qui peut faire tout et n'importe quoi (surtout du grand n'importe quoi).
Donc tu parlais du script que je fourni, et non du script officiel
Oui, je parlais bien évidemment du script dont tu parles ici
va falloir que je dorme plus souvent moi
Salut ! Merci pour cet excellent tuto que je garde sous le coude (et dans mes marque-pages !) pour un avenir très proche !
J'ai parcouru rapidement, et j'ai juste quelques détails que je ne comprends pas ou peu : dans l'étape préparatoire (création de l'utilisateur dédié + dossiers), il y a ce morceau de code :
mkdir -p ~letsencrypt/{bin,certs/archive/$(date --utc +'%FT%TZ'),private,challenges}
suivi plus loin de :
ln -s archive/$(date --utc +'%FT%TZ') ~letsencrypt/certs/live
Dans le premier cas il s'agit de créer un dossier à la date/heure UTC actuelle ? Le '%TZ' final ne devrait-il pas être '%T%Z' ? (car sinon chez moi ça me retourne par exemple '08:14:49Z' au lieu de '08:14:49UTC')
Le cas échéant on retrouve cette 'coquille' (si c'en est une ! ^^) dans le script de renouvellement (ainsi que celui proposé sur Github).
Pour le lien symbolique, j'imagine qu'il faut en fait le faire sur le dossier précédemment créé et non retaper avec la commande date ?
Merci en tout cas pour ce superbe tuto que je cherche depuis quelques jours, les précédents ne m'ayant pas toujours satisfait !
Effectivement le but est bien de créer un dossier nommé selon la date et heure UTC courante. Mais pas d'erreur selon moi sur le format : j'applique le standard ISO 8601, qui indique que le fuseau UTC doit être signalé par un "Z".
Après cela n'est qu'un choix personnel, tu peux tout à fait choisir un autre format de nommage. L'essentiel est d'être certain qu'un nom différent sera généré à chaque exécution, pour ne pas avoir de collision.
Effectivement le lien symbolique doit toujours pointer vers le dernier dossier créé, de sorte à ce que le dernier certificat généré en date soit utilisé (à moins que la dernière exécution ait planté, et dans ce cas tout l'intérêt de ce lien est justement de pouvoir switcher rapidement vers une précédente "version").
Ah je n'avais pas du tout saisi le standard ISO, ce qui effectivement rend le "Z" cohérent... J'ai été induit en erreur je pense par l'écriture 'TZ' (Timezone)qui m'a conduit à penser à voir apparaître 'UTC'...
Quoiqu'il en soit oui j'avais compris qu'il fallait éviter les collisions des dossiers et cela ne m'a pas empêché de mettre en oeuvre le certificat SSL aujourd'hui, a priori avec succès en tout cas dans la phase de création initiale et de mise en production !
J'ai tenté de lancer le script de renouvellement mais je n'ai eu qu'une réponse "négative" dans le sens où le certif conservant encore 89 jours de validité il n'est pas renouvelé... En soi ce n'est pas si négatif que ça, au moins cela montre qu'une partie du script semble s'exécuter comme attendu !
J'imagine que je n'aurai de réponse définitive qu'au moment où le critère de renouvellement sera atteint.
Encore merci pour la réponse et le tuto
PS : je viens de réaliser, il y a du coup au fur et à mesure des renouvellements une accumulation des dossiers de stockage des certifs, j'imagine que rien n'empêche de supprimer les anciens (par exemple sur la base de leur date justement : inutile de garder les dossiers de plus de 90 jours car les certifs qu'ils contiennent sont forcément périmés) ? Auquel cas j'essaierai de voir si je peux inclure ça dans le script de renouvellement automatique : je n'aime pas l'accumulation de fichiers/dossiers inutiles .
Tu peux éventuellement tester le renouvellement sans attendre soit en modifiant temporairement la valeur de la variable
RENEW
pour lui affecter 91, ce qui invalidera en permanence le certificat actuel et lancera le renouvellement, soit, si tu utilises la version avancée du script disponible sur Gist, directement en lançant le script avec l'option--force
(ou-f
) pour forcer le renouvellement.Je n'ai en effet rien intégré pour supprimer automatiquement les anciens dossiers. Je ne suis pas vraiment fan des scripts de suppression automatique : il y a toujours le risque qu'un de ces scripts ne supprime plus qu'il ne devrait ! Et puis ici, avec un renouvellement tous les 2 mois, cela fait au final seulement six dossiers par an. Du coup j'ai préféré dans mon cas faire le nettoyage manuellement une fois par an. Après libre à chacun d'adapter ce qui est proposé selon ses préférences et d'ajouter si nécessaire un petit script auxiliaire pour faire le ménage .
Bjr
J'ai essayé de suivre ce tuto. Malheureusement, il se trouve que je ne comprends pas tout. Je bloque à l'obtention du certificat : /etc/letsencrypt/certs/live/vgsigned.crt: Aucun fichier ou dossier de ce type
Si je veux aller dans le dossier "live" (lien symbolique si j'ai bien compris) : Aucun fichier ou dossier de ce type
J'en déduis que le lien symbolique ne pointe pas au bon endroit.
Question annexe : je n'ai pas de dossier "sudoers.d" et accessoirement la commande visudo est introuvable.
Est ce que je peux créer le dossier "sudoers.d" a la main et le fichier "letsencrypt-apache2ctl-graceful" avec nano ?
Merci
Re Bsr
Je comprends mieux le problème, même si je ne sais pas encore le résoudre. J'ai le problème de Tyolus. Le nom du dossier créé : 2017-02-03T15:59:41Z (avec le T et Le Z en final)
Plus génant, le lien symbolique live renvoie vers un dossier inexistant : live -> archive/2017-02-03T16:01:59Z
Ma question est : comment je corrige ?
Merci
V.
Bonsoir,
Concernant l'absence du dossier sudoers.d, cela semble indiquer que tu n'as pas la commande sudo sur ton serveur, ou que cela ne s'applique pas à ta distribution (j'ai fait cet article sur un serveur Debian, ça doit s'appliquer également sur Ubuntu et ses autres dérivés. Dans le premier cas, tu peux l'obtenir en installant le package du même nom.
Le lien symbolique "live" doit en général pointer sur le dernier sous-dossier créé dans archive (dont le nom est la date la plus récente). Pour corriger tu peux donc simplement supprimer le lien cassé puis le recréer en pointant sur le bon dossier. Je t'invite à relire mes précédentes réponses en complément.
Bonjour
Ok, Je comprends mieux. j'ai fait un copier coller de la commande "ln -s archive/$(date --utc +'%FT%TZ') ~letsencrypt/certs/live". Forcement, ça a créer un lien symbolique avec un décalage de date (en fait quelques secondes) par rapport à la commande précédente "mkdir -p ~letsencrypt/{bin,certs/archive/$(date --utc +'%FT%TZ'),private,challenges}". Il n'en reste pas moins que je vais devoir revoir le format de la date.
Quand à la commande sudo, effectivement, il semblerait qu'elle ne soit pas installé par défaut sur Jessie.
Merci de tes réponses
V.
Re Bonjour
Je pensais pouvoir m'en sortir en suivant attentivement ce tuto, mais c'est un petit peu au-delà de mes compétences. Le script acme_tiny génère une erreur sur la vérification du nom de domaine. Les sous-domaines sont vérifiés, mais le domaine principal ne passe pas. Ca dit que ça ne peut pas DL le fichier généré. J'ai vérifié : le dossier autorise bien le téléchargement. Bref, je cale.
Si tu as des conseils, je suis preneur.
Merci.
V.
Difficile de t'aider plus ici, mais a priori le script t'indique qu'il ne parvient pas à télécharger le fichier qu'il a déposé. Tu devrais vérifier que tu arrive bien à accéder à l’adresse http://tondomaine.fr/.well-known/acme-challenge/, ainsi qu'à un fichier texte de test que tu créé manuellement dans acme-challenge, en utilisant bien le domaine principal. Tu ne dois pas avoir de redirection vers un sous domaine type www.tondomaine.fr.
En revanche je ne vois pas la raison pour laquelle tu devrais revoir le format de date, tout devrais fonctionner avec le format initial...
Bon, ben c'est mort. Je ne sais pas si j'utilise trop de noms de sous-domaine mais le fait est que ça ne marche pas chez moi :'(
Parsing account key...
Parsing CSR...
Registering account...
Already registered!
[...]
Verifying domain.fr...
Traceback (most recent call last):
File "/etc/letsencrypt/bin/acme_tiny.py", line 198, in
main(sys.argv[1:])
File "/etc/letsencrypt/bin/acme_tiny.py", line 194, in main
signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca)
File "/etc/letsencrypt/bin/acme_tiny.py", line 123, in get_crt
wellknown_path, wellknown_url))
ValueError: Wrote file to /etc/letsencrypt/challenges/zMEgccOddwbxBgMiP6qWOc9iYcoJPrN8-dVTaGkiCrI, but couldn't download http://tondomaine.fr/.well-known/acme-challenge/zMEgccOddwbxBgMiP6qWOc9iYcoJPrN8-dVTaGkiCrI
Me reste plus qu'à trouver une autre autorité de certification... :/
Avant de passer à une autre autorité de certification, tu peux tout de même te rabattre sur le script officiel, qui est peut-être plus simple d'utilisation : https://certbot.eff.org/
Bonjour, j'essaye d'installer le certificat avec mes maigres connaissances (pour le moment!), à l'étape de récupérer le script:
wget -O ~letsencrypt/bin/acme_tiny.py https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py
Il ne se télécharge pas, dans le terminal, j'ai:
--2017-08-16 20:16:54-- (essai : 3) https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py
Connexion à raw.githubusercontent.com (raw.githubusercontent.com)|151.101.120.133|:443…
Savez-vous pourquoi ? Cela semble étrange que Github ne me laisse pas le télécharger !
As tu vérifié que ton serveur a bien accès à Internet ? N'est-il pas bloqué derrière un proxy par exemple ?
A défaut tu pourrais récupérer le script sur ton PC via un navigateur web puis le transférer vers le serveur par un autre moyen (SFTP/FTP par exemple) en le plaçant dans le bon dossier, mais tu risques d'être à nouveau bloqué sur les étapes suivantes.
Il y a juste un problème de droit : Apache ne peut pas accéder à la clé privée /etc/letsencrypt/private/domain.key.
Un simple
sudo -u www-data sh -c "ls -lah /etc/letsencrypt/private"
permet de la vérifier.
Mais apparemment, ce n'est pas gênant, Apache doit lire les clés avant de passer en utilisateur www-data...
Hum oui c'est ce que je me disais aussi. En effet je n'autorise pas l'utilisateur www-data à lire la clé privée, mais je n'ai jamais constaté un problème sur les installations que j'ai faites de cette manière.
Effectivement la clé doit être lu au chargement du service avec les droits root.
Merci encore pour cet article. Juste une petite erreur dans les commandes de l'installation initiale. Il faut faire:
DATE=$(date --utc +'%FT%TZ')
mkdir -p ~letsencrypt/{bin,certs/archive/$DATE,private,challenges}
à la place de
mkdir -p ~letsencrypt/{bin,certs/archive/$(date --utc +'%FT%TZ'),private,challenges}
et plus loin
ln -s archive/$DATE ~letsencrypt/certs/live
à la place de
ln -s archive/$(date --utc +'%FT%TZ') ~letsencrypt/certs/live
En effet, entre la création du dossier et celle du lien symbolique, l'heure change et le lien pointe sur un dossier qui n'existe pas. D'ailleurs cette "erreur" est corrigée dans le script de renouvellement.