wiki/HowtoLetsEncrypt.md
2019-01-14 11:08:15 +01:00

173 lines
6.8 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
categories: web security
title: Howto Let's Encrypt
...
* Documentation : <https://letsencrypt.org/docs/>
* Documentation Certbot : <https://certbot.eff.org/docs/>
* Rôle Ansible : <https://forge.evolix.org/projects/ansible-roles/repository/revisions/stable/show/evoacme>
[Let's Encrypt](https://letsencrypt.org/) est une autorité de certification fournissant des certificats [SSL](HowtoSSL) valables 90 jours gratuitement et automatiquement.
L'obtention d'un certificat signé s'effectue via le protocole [ACME (Automated Certificate Management Environment)](https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment),
ce qui nécessite d'avoir temporairement un serveur HTTP sur le port TCP/80 de l'adresse IP correspondant au _Common Name_ du certificat à signer.
Le certificat intermédiaire de Let's Encrypt est également signé par l'autorité de certification [IdenTrust](https://www.identrust.com/) préinstallée dans la plupart des navigateurs.
## Installation
Un client ACME est nécessaire pour communiquer avec les serveurs de Let's Encrypt et obtenir un certificat.
Nous utilisons le client officiel [Certbot](https://certbot.eff.org/) disponible via les [backports](HowtoDebian/Backports).
On ajoute les lignes suivantes à `/etc/apt/preferences.d/backports` :
~~~
Package: certbot python-certbot python-acme python-cryptography python-openssl python-setuptools python-ndg-httpsclient python-pyasn1 python-pkg-resources
Pin: release a=jessie-backports
Pin-Priority: 999
~~~
puis on installe certbot et ses dépendances :
~~~
# apt install certbot
$ certbot --version
certbot 0.9.3
~~~
### Création d'un utilisateur dédié
On évite de faire tourner certbot avec l'utilisateur _root_ (notamment pour ne pas lui donner accès aux clés privées).
Nous allons créer un utilisateur dédié _acme_ :
~~~
# adduser --home /var/lib/letsencrypt --quiet --system --no-create-home --group acme
# install -m 755 -o acme -g acme -d /etc/letsencrypt /var/lib/letsencrypt
# install -m 750 -o acme -g acme -d /var/log/letsencrypt
~~~
et désactiver la tâche cron `/etc/cron.d/certbot` :
~~~
# mv /etc/cron.d/certbot /etc/cron.d/certbot.disabled
~~~
### Configuration du Serveur Web
Pour vérifier que la demande est légitime, Let's Encrypt doit accéder à un fichier temporaire via HTTP sur le port TCP/80 de l'adresse IP correspondant au _Common Name_ du certificat à signer,
du type *http://www.example.com/.well-known/acme-challenge/hNgN_ygEFf-XiHJd6VErwNbfRcpP2CbJmIN3qpJXZOQ*
#### Apache
Configuration :
~~~{.apache}
Alias /.well-known/acme-challenge /var/lib/letsencrypt/.well-known/acme-challenge
<Directory "/var/lib/letsencrypt/.well-known/acme-challenge">
Options -Indexes
Allow from all
Require all granted
</Directory>
~~~
#### Nginx
Configuration Jessie :
~~~
location ~ /.well-known/acme-challenge {
alias /var/lib/letsencrypt/.well-known/acme-challenge;
try_files $uri =404;
allow all;
}
~~~
Configuration Stretch :
~~~
location ~ /.well-known/acme-challenge {
alias /var/lib/letsencrypt/;
try_files $uri =404;
allow all;
}
~~~
## Génération du certificat
Générér une clé privée (www.example.com.key) et sa demande de certificat associé (www.example.com.csr) (voir [HowtoSSL]()) :
~~~
# openssl req -newkey rsa:2048 -sha256 -nodes -keyout /etc/ssl/private/www.example.com.key -out /etc/letsencrypt/www.example.com.csr
# chown acme:acme /etc/letsencrypt/www.example.com.csr
~~~
Faire la première demande de certificat avec l'utilisateur _acme_ :
~~~
$ certbot certonly --webroot --csr /etc/letsencrypt/www.example.com/www.example.com.csr --webroot-path /var/lib/letsencrypt \
--cert-path /etc/letsencrypt/www.example.com.crt --non-interactive --agree-tos --register-unsafely-without-email
~~~
Votre certificat est maintenant présent dans `/etc/letsencrypt/www.example.com.crt`.
> *Note* : l'utilisateur _acme_ n'a pas accès aux clés privées :
~~~
$ cat /etc/ssl/private/www.example.com.key
cat: /etc/ssl/private/www.example.com.key: Permission non accordée
~~~
## Renouvellement du certificat
Les certificats Let's Encrypt sont valables 90 jours. Avant la date d'expiration, il faudra relancer avec l'utilisateur _acme_ :
~~~
$ certbot certonly --webroot --csr /etc/letsencrypt/www.example.com/www.example.com.csr --webroot-path /var/lib/letsencrypt \
--cert-path /etc/letsencrypt/www.example.com.crt --non-interactive
~~~
## Suppression d'un certificat
~~~
# certbot delete --cert-name www.example.com
~~~
## Automatisation
Pour automatiser l'installation de _Certbot_ et la génération/renouvellement de certificats, nous utilisons des scripts : [Evoacme](https://forge.evolix.org/projects/ansible-roles/repository/revisions/stable/show/evoacme).
## FAQ
### Certificat Wildcard ou EV
Let's Encrypt permet de générer un certificat Wildcard (via challenge DNS) mais pas EV (Extended Validation).
### Je n'ai pas de port TCP/80 accessible
Let's Encrypt vérifie la légitimité de la demande en faisant une requête DNS sur l'enregistrement DNS correspondant au _Common Name_ du certificat à signer (si il n'y a pas d'enregistrement DNS propagé mondialement, c'est donc impossible d'utiliser Let's Encrypt) et effectue une requête HTTP vers le port TCP/80 de l'adresse IP : il faut donc obligatoirement avoir temporairement un service HTTP sur le port TCP/80... au moins temporairement.
### Challenge DNS
Si notre serveur web n'est pas accessible de l'extérieur, on peut utiliser un challenge par DNS plutôt que via une page http.
~~~
$ certbot -d domain.example.com --manual --preferred-challenges dns certonly
~~~
Il suffira alors de créer l'entrée DNS que certbot affichera et continuer le processus interactif.
### Rate-limits
Doc officielle : <https://letsencrypt.org/docs/rate-limits/>
L'API de Let's Encrypt dispose un « rate limiting » afin d'éviter les abus.
- 20 certificats pour 1 domaine maximum par semaine. 1 domaine est la partie juste avant le TLD. www.example.com, le domaine est example.com. blog.exemple.fr, le domaine est exemple.fr ; Si vous faites 1 certificat par sous-domaines, vous êtes donc limités à 20 par semaine. Il est donc préférable de regrouper plusieurs sous-domaines dans un seul certificat (SAN). La limite du SAN est de 100 sous-domaines. La limite est donc de 2000 certificats pour 1 domaine par semaine si vous mettez 100 sous-domaines par certificats.
- La limite de renouvellement d'un certificat est de 5 par semaine. Si votre procédure de renouvellement automatique échoue, au bout de 5 jours vous allez être banni pendant 1 semaine.
- La limite d'échec de validation du challenge est de 5 par heures (par adresse IP et utilisateur enregistré par email) ;
Si vous échouez 5 fois à valider le challenge DNS, on peut penser qu'il suffit d'attendre 1h, sauf qu'en fait non. Le « bannissement » est pour 1 semaine !