Let's encrypt : certificat multi domaines
Bonjour à tous,
Un petit article rapide sur comment avoir un certificat Let's Encrypt qui couvre plusieurs domaines comme c'est le cas sur mon site : boris-tassou.fr et www.boris-tassou.fr.
Tout d'abord, il est nécessaire de générer une clé qui servira pour la création et l'enregistrement du compte auprès de Let's Encrypt :
openssl genrsa 4096 > account.key
Il faut maintenant générer la clé qui sera utilisée pour le ou les certificats LE que vous génèrerez :
openssl genrsa 4096 > boris-tassou.key
On peut donc passer à la génération du CSR multi-domains. Dans ce cas précis, je n'ai que deux domaines mais il est possible d'en avoir plus si vous souhaitez couvrir d'autres domaines avec le même certificat (même si ce n'est pas la technique la plus propre) :
openssl req -new -sha256 -key boris-tassou.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:boris-tassou.fr,DNS:www.boris-tassou.fr")) > boris-tassou.csr
Avant de pouvoir enregistrer le CSR et d'obtenir le certificat auprès de LE, il faut configurer le virtual host, dans mon cas avec Nginx :
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name boris-tassou.fr www.boris-tassou.fr;
location /.well-known/acme-challenge/ {
alias /usr/local/www/challenges/;
try_files $uri =404;
}
}
Il est simpliste et ne gère pas le HTTPS pour l'instant car LE doit pouvoir accéder au challenge qu'il génère.
Pour l'enregistrement au près de LE, j'utilise le script python acme_tiny que vous pouvez trouver ici : https://github.com/diafygi/acme-tiny
Pour avoir le certificat signé, il faut exécuter la commande suivante :
python3 /etc/ssl/LE/acme_tiny.py --account-key /etc/ssl/LE/account.key --csr /etc/ssl/LE/domain.csr --acme-dir /usr/local/www/challenges/ > /etc/ssl/LE/signed_chain.crt || exit
Votre certificat est maintenant disponible!
Il ne reste plus qu'à modifier le virtual host pour gérer le HTTPS tout en laissant la possibilité à LE de pouvoir accéder au challenge pour le renouvellement du certificat :
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name boris-tassou.fr www.boris-tassou.fr;
location /.well-known/acme-challenge/ {
alias /usr/local/www/challenges/;
try_files $uri =404;
}
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl ipv6only=on;
server_name www.boris-tassou.fr boris-tassou.fr;
if ($host = 'boris-tassou.fr' ) {
rewrite ^/(.*)$ https://www.boris-tassou.fr/$1 permanent;
}
access_log /var/log/blog/access.log;
error_log /var/log/blog/error.log;
include /usr/local/etc/nginx/ssl.conf;
ssl_certificate /etc/ssl/LE/signed_chain.crt;
ssl_certificate_key /etc/ssl/LE/boris-tassou.key;
client_max_body_size 10m;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://XXXXXXXXX;
}
}
Afin d'avoir une utilisation complète du certificat, je publie l'empreinte de la clé publique pour éviter une usurpation du certificat.
Pour récupérer cette empreinte, il faut exécuter la commande suivante :
openssl x509 -in /etc/ssl/LE/signed_chain.crt -noout -pubkey | openssl pkey -pubin -outform DER | sha512
Il ne reste plus qu'à l'ajouter au DNS, dans mon cas Knot :
_443._tcp.www.boris-tassou.fr. TLSA 3 1 2 EMPREINTETLSA
Les options de la déclaration du TLSA peuvent varier :
- TLSA 3 0 2 : si le certificat ne change pas, hors il change quand il est renouvellé (publication de l'empreinte du certificat).
- TLSA 3 1 2 : si le certificat change mais que la clé privée ne change pas (publication de l'empreinte de la clé publique).
Pour gérer le renouvellement automatique (le certificat généré étant valide pour 90J), il faut mettre en place une tâche cron qui exécute ce petit script :
#!/bin/sh
python3 /etc/ssl/LE/acme_tiny.py --account-key /etc/ssl/LE/account.key --csr /etc/ssl/LE/boris-tassou.csr --acme-dir /usr/local/www/challenges/ > /etc/ssl/LE/signed_chain.crt || exit
service nginx reload
Et la tâche cron :
# s'execute une fois par mois
0 0 1 * * /root/renew_cert.sh 2>> /var/log/acme_tiny.log
Vous pouvez maintenant profiter des certificats Let's Encrypt!
Have a nice day.