wiki/HowtoLetsEncrypt.md

164 lines
6.4 KiB
Markdown
Raw Normal View History

2017-02-02 11:46:14 +01:00
---
categories: web security
title: Howto Let's Encrypt
...
2016-12-29 11:25:39 +01:00
2017-02-02 11:46:14 +01:00
* Documentation : <https://letsencrypt.org/docs/>
2017-02-06 10:47:25 +01:00
* Documentation Certbot : <https://certbot.eff.org/docs/>
* Rôle Ansible : <https://forge.evolix.org/projects/ansible-roles/repository/revisions/stable/show/evoacme>
2016-12-29 11:25:39 +01:00
[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.
2017-02-06 10:51:22 +01:00
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.
2017-02-02 11:46:14 +01:00
2016-12-29 11:25:39 +01:00
## Installation
2016-12-29 11:25:39 +01:00
Un client ACME est nécessaire pour communiquer avec les serveurs de Let's Encrypt et obtenir un certificat.
2016-12-29 11:25:39 +01:00
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` :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
2017-02-06 14:41:14 +01:00
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
2016-12-29 11:25:39 +01:00
~~~
puis on installe certbot et ses dépendances :
~~~
# apt install certbot
2016-12-29 11:25:39 +01:00
$ certbot --version
certbot 0.9.3
~~~
### Création d'un utilisateur dédié
2016-12-29 11:25:39 +01:00
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_ :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
# 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
2016-12-29 11:25:39 +01:00
~~~
et désactiver la tâche cron `/etc/cron.d/certbot` :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
# mv /etc/cron.d/certbot /etc/cron.d/certbot.disabled
2016-12-29 11:25:39 +01:00
~~~
### 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*
2016-12-29 11:25:39 +01:00
#### Apache
2017-02-06 14:41:14 +01:00
Configuration :
2017-01-03 11:20:35 +01:00
~~~{.apache}
2016-12-29 11:25:39 +01:00
Alias /.well-known/acme-challenge /var/lib/letsencrypt/.well-known/acme-challenge
<Directory "/var/lib/letsencrypt/.well-known/acme-challenge">
Options -Indexes
2017-02-02 11:46:14 +01:00
Allow from all
2016-12-29 11:25:39 +01:00
Require all granted
</Directory>
~~~
2017-02-02 11:46:14 +01:00
#### Nginx
Préférez importer le snippet /etc/nginx/snippets/letsencrypt.conf,
mais si une configuration manuelle est nécessaire:
2018-09-20 16:40:34 +02:00
Configuration Jessie :
2017-02-02 11:46:14 +01:00
~~~
2018-09-20 16:40:34 +02:00
location ~ /.well-known/acme-challenge {
2017-02-02 11:46:14 +01:00
alias /var/lib/letsencrypt/.well-known/acme-challenge;
try_files $uri =404;
allow all;
}
~~~
2018-09-20 16:40:34 +02:00
Configuration Stretch :
~~~
location ~ /.well-known/acme-challenge {
2018-09-20 16:40:54 +02:00
alias /var/lib/letsencrypt/;
2018-09-20 16:40:34 +02:00
try_files $uri =404;
allow all;
}
~~~
2017-02-02 11:46:14 +01:00
## Génération du certificat
2016-12-29 11:25:39 +01:00
Générer une clé privée (www.example.com.key) et sa demande de certificat associé (www.example.com.csr) (voir [HowtoSSL]()) :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
$ certbot certonly -d example.com,www.example.com --cert-name example.com --webroot --webroot-path /var/lib/letsencrypt/
2016-12-29 11:25:39 +01:00
~~~
## Renouvellement du certificat
Les certificats Let's Encrypt sont valables 90 jours. Un timer systemd roule automatiquement à chaque jour pour revalider le certificat. Il est possible d'utiliser --deploy-hook pour faire des actions après un renouvellement. Utiliser systemd edit certbot pour modifier l'invocation par défaut. Par example, pour NGINX, nous modifions
~~~
ExecStart=/usr/bin/certbot -q renew
~~~
Avec:
~~~
ExecStart=/usr/bin/certbot -q renew --deploy-hook systemctl reload nginx
~~~
2019-01-14 11:08:15 +01:00
## Suppression d'un certificat
~~~
# certbot delete --cert-name www.example.com
~~~
2016-12-29 11:25:39 +01:00
## 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
2018-06-05 17:36:52 +02:00
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
2016-12-29 11:25:39 +01:00
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.
2017-07-17 14:10:57 +02:00
### 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.
2018-06-05 17:37:56 +02:00
### Rate-limits
2018-06-08 10:26:18 +02:00
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.
2018-06-13 14:25:37 +02:00
- 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 !