Révision de a doc Let's Encrypt
This commit is contained in:
parent
aa0dc954b8
commit
5ba75035b5
|
@ -5,7 +5,7 @@ title: Howto Let's Encrypt
|
||||||
|
|
||||||
* Documentation : <https://letsencrypt.org/docs/>
|
* Documentation : <https://letsencrypt.org/docs/>
|
||||||
* Documentation Certbot : <https://certbot.eff.org/docs/>
|
* Documentation Certbot : <https://certbot.eff.org/docs/>
|
||||||
* Rôle Ansible : <https://forge.evolix.org/projects/ansible-roles/repository/revisions/stable/show/evoacme>
|
* Rôle Ansible : <https://gitea.evolix.org/evolix/ansible-roles/src/branch/stable/certbot/files/hooks>
|
||||||
|
|
||||||
[Let's Encrypt](https://letsencrypt.org/) est une autorité de certification fournissant des certificats [SSL](HowtoSSL) valables 90 jours gratuitement et automatiquement.
|
[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),
|
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),
|
||||||
|
@ -15,54 +15,32 @@ Le certificat intermédiaire de Let's Encrypt est également signé par l'autori
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Un client ACME est nécessaire pour communiquer avec les serveurs de Let's Encrypt et obtenir un certificat.
|
On installe certbot et ses dépendances :
|
||||||
|
|
||||||
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
|
# apt install certbot
|
||||||
|
|
||||||
$ certbot --version
|
$ certbot --version
|
||||||
certbot 0.9.3
|
certbot 0.31.0
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
### 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
|
### 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,
|
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*
|
||||||
du type *http://www.example.com/.well-known/acme-challenge/hNgN_ygEFf-XiHJd6VErwNbfRcpP2CbJmIN3qpJXZOQ*
|
|
||||||
|
|
||||||
#### Apache
|
#### Apache
|
||||||
|
|
||||||
Configuration :
|
Configuration :
|
||||||
|
|
||||||
~~~{.apache}
|
~~~{.apache}
|
||||||
|
<IfModule jk_module>
|
||||||
|
SetEnvIf Request_URI "/.well-known/acme-challenge/*" no-jk
|
||||||
|
</IfModule>
|
||||||
|
<IfModule proxy_module>
|
||||||
|
ProxyPass /.well-known/acme-challenge/ !
|
||||||
|
</IfModule>
|
||||||
Alias /.well-known/acme-challenge /var/lib/letsencrypt/.well-known/acme-challenge
|
Alias /.well-known/acme-challenge /var/lib/letsencrypt/.well-known/acme-challenge
|
||||||
<Directory "/var/lib/letsencrypt/.well-known/acme-challenge">
|
<Directory "/var/lib/letsencrypt/.well-known/acme-challenge">
|
||||||
Options -Indexes
|
Options -Indexes
|
||||||
|
@ -73,8 +51,7 @@ Alias /.well-known/acme-challenge /var/lib/letsencrypt/.well-known/acme-challeng
|
||||||
|
|
||||||
#### Nginx
|
#### Nginx
|
||||||
|
|
||||||
Préférez importer le snippet /etc/nginx/snippets/letsencrypt.conf,
|
Préférez importer le snippet `/etc/nginx/snippets/letsencrypt.conf`, mais si une configuration manuelle est nécessaire:
|
||||||
mais si une configuration manuelle est nécessaire:
|
|
||||||
|
|
||||||
Configuration Jessie :
|
Configuration Jessie :
|
||||||
|
|
||||||
|
@ -99,24 +76,126 @@ location ~ /.well-known/acme-challenge {
|
||||||
|
|
||||||
## Génération du certificat
|
## Génération du certificat
|
||||||
|
|
||||||
Générer une clé privée (www.example.com.key) et sa demande de certificat associé (www.example.com.csr) (voir [HowtoSSL]()) :
|
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
$ certbot certonly -d example.com,www.example.com --cert-name example.com --webroot --webroot-path /var/lib/letsencrypt/
|
$ certbot certonly --webroot --webroot-path /var/lib/letsencrypt/ -d example.com,www.example.com --cert-name example.com
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
## Renouvellement du certificat
|
## 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
|
Les certificats Let's Encrypt sont valables 90 jours. Un timer systemd roule automatiquement à chaque jour pour revalider le certificat.
|
||||||
|
|
||||||
~~~
|
Pour effectuer des actions post-renouvellement (recharger le service web, par exemple), on repose sur les hooks. Ils sont automatiquement exécutés s'ils sont détectés et exécutables.
|
||||||
ExecStart=/usr/bin/certbot -q renew
|
|
||||||
|
Pour Apache (`/etc/letsencrypt/renewal-hooks/deploy/apache.sh`):
|
||||||
|
|
||||||
|
~~~{.bash}
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
error() {
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
debug() {
|
||||||
|
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
daemon_found_and_running() {
|
||||||
|
test -n "$(pidof apache2)" && test -n "${apache2ctl_bin}"
|
||||||
|
}
|
||||||
|
config_check() {
|
||||||
|
${apache2ctl_bin} configtest > /dev/null 2>&1
|
||||||
|
}
|
||||||
|
letsencrypt_used() {
|
||||||
|
grep -q -r -E "letsencrypt" /etc/apache2/
|
||||||
|
}
|
||||||
|
main() {
|
||||||
|
if daemon_found_and_running; then
|
||||||
|
if letsencrypt_used; then
|
||||||
|
if config_check; then
|
||||||
|
debug "Apache detected... reloading"
|
||||||
|
systemctl reload apache2
|
||||||
|
else
|
||||||
|
error "Apache config is broken, you must fix it !"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
debug "Apache doesn't use Let's Encrypt certificate. Skip."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
debug "Apache is not running or missing. Skip."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly PROGNAME=$(basename "$0")
|
||||||
|
readonly VERBOSE=${VERBOSE:-"0"}
|
||||||
|
readonly QUIET=${QUIET:-"0"}
|
||||||
|
|
||||||
|
readonly apache2ctl_bin=$(command -v apache2ctl)
|
||||||
|
|
||||||
|
main
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Avec:
|
Pour Nginx (`/etc/letsencrypt/renewal-hooks/deploy/nginx.sh`) :
|
||||||
|
|
||||||
|
~~~{.bash}
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
error() {
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
debug() {
|
||||||
|
if [ "${VERBOSE}" = "1" ] && [ "${QUIET}" != "1" ]; then
|
||||||
|
>&2 echo "${PROGNAME}: $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
daemon_found_and_running() {
|
||||||
|
test -n "$(pidof nginx)" && test -n "${nginx_bin}"
|
||||||
|
}
|
||||||
|
config_check() {
|
||||||
|
${nginx_bin} -t > /dev/null 2>&1
|
||||||
|
}
|
||||||
|
letsencrypt_used() {
|
||||||
|
grep -q --dereference-recursive -E "letsencrypt" /etc/nginx/sites-enabled
|
||||||
|
}
|
||||||
|
main() {
|
||||||
|
if daemon_found_and_running; then
|
||||||
|
if letsencrypt_used; then
|
||||||
|
if config_check; then
|
||||||
|
debug "Nginx detected... reloading"
|
||||||
|
systemctl reload nginx
|
||||||
|
else
|
||||||
|
error "Nginx config is broken, you must fix it !"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
debug "Nginx doesn't use Let's Encrypt certificate. Skip."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
debug "Nginx is not running or missing. Skip."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly PROGNAME=$(basename "$0")
|
||||||
|
readonly VERBOSE=${VERBOSE:-"0"}
|
||||||
|
readonly QUIET=${QUIET:-"0"}
|
||||||
|
|
||||||
|
readonly nginx_bin=$(command -v nginx)
|
||||||
|
|
||||||
|
main
|
||||||
|
~~~
|
||||||
|
|
||||||
|
D'autres hooks sont disponibles dans le [dépôt Ansible](https://gitea.evolix.org/evolix/ansible-roles/src/branch/stable/certbot/files/hooks).
|
||||||
|
|
||||||
|
Pour exécuter un hook manuellement, par exemple après la création du certificat :
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
ExecStart=/usr/bin/certbot -q renew --deploy-hook systemctl reload nginx
|
# VERBOSE=1 RENEWED_LINEAGE=/etc/letsencrypt/live/<cert-name> /etc/letsencrypt/renewal-hooks/deploy/<hook>.sh
|
||||||
|
~~~
|
||||||
|
|
||||||
|
## Lister les certificats
|
||||||
|
|
||||||
|
~~~
|
||||||
|
# certbot certificates
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
## Suppression d'un certificat
|
## Suppression d'un certificat
|
||||||
|
@ -125,9 +204,10 @@ ExecStart=/usr/bin/certbot -q renew --deploy-hook systemctl reload nginx
|
||||||
# certbot delete --cert-name www.example.com
|
# certbot delete --cert-name www.example.com
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
|
||||||
## Automatisation
|
## 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).
|
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/certbot).
|
||||||
|
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
@ -142,7 +222,7 @@ Let's Encrypt vérifie la légitimité de la demande en faisant une requête DNS
|
||||||
|
|
||||||
### Challenge DNS
|
### 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.
|
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
|
$ certbot -d domain.example.com --manual --preferred-challenges dns certonly
|
||||||
|
@ -161,4 +241,4 @@ L'API de Let's Encrypt dispose un « rate limiting » afin d'éviter les abus.
|
||||||
- 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 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) ;
|
- 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 !
|
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 !
|
||||||
|
|
Loading…
Reference in a new issue