Let's Encrypt avec NGINX

Let’s Encrypt est une autorité de certification libre et ouverte développée par Internet Security Research Group (ISRG). Les certificats émis par Let’s Encrypt sont approuvés par presque tous les navigateurs actuels.

Installer Certbot

Certbot est un outil permet d’obtenir et de renouveler les certificats SSL de Let’s Encrypt et de configurer les serveurs Web pour qu’ils utilisent ces mêmes certificats. Le paquet certbot est inclus dans les dépôts Debian/Ubuntu par défaut.

# apt update
# apt install certbot

Generate une clé de Diffie-Hellman

L’échange de clés de Diffie–Hellman (DH) permettant d’échanger de façon sécurisée des clés cryptographiques sur un canal de communication non sécurisé.

Généreration de clés DH 2048 bits pour renforcer la sécurité :

# openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Il est possible de paramétrer la taille des clés à 4096 bits mais le temps d’excution prendra environ 30 min.

Configuration d’un vhost

Pour obtenir un certificat SSL pour notre domaine, nous allons utiliser le plug-in Webroot qui fonctionne en créant un fichier temporaire pour valider le domaine demandé dans le répertoire ${webroot-path}/.well-known/acme-challenge. Le serveur Let’s Encrypt envoie des requêtes HTTP au fichier temporaire pour confirmer que le domaine demandé est résolu sur le serveur sur lequel certbot s’exécute.

Nous allons mapper toutes les requêtes HTTP pour .well-known/acme-challenge à un seul répertoire, /var/lib/letsencrypt.

Création du répertoire accessible en écriture pour le serveur Nginx :

# mkdir -p /var/lib/letsencrypt/.well-known
# chgrp www-data /var/lib/letsencrypt
# chmod g+s /var/lib/letsencrypt

Le Vhost de nginx /etc/nginx/sites-available/monSitePro.conf :

server {
listen 80;

server_name www.monsitePro.fr monsitePro.fr;
return 301 https://$host$request_uri;

}

server {
listen 443 ssl http2;

server_name www.monsitePro.fr monsitePro.fr;

ssl_certificate /etc/letsencrypt/live/monsitePro.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/monsitePro.fr/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/monsitePro.fr/chain.pem;
include snippets/ssl.conf;
include snippets/letsencrypt.conf;

root /home/USER42/monsitePro.fr/www/;
index index.php index.html index.htm;

location / {
try_files $uri $uri/ =404;
}

location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}

location ~ /\.ht {
deny all;
}

access_log /var/log/nginx/monsitePro.fr.access.log;
error_log /var/log/nginx/monsitePro.fr.error.log warn;

}

Le fichier /etc/nginx/snippets/letsencrypt.conf :

location ^~ /.well-known/acme-challenge/ {
allow all;
root /var/lib/letsencrypt/;
default_type "text/plain";
try_files $uri =404;
}

Le fichier /etc/nginx/snippets/ssl.conf, consulter régulièrement le site https://cipherli.st/ pour les mises à jour :

ssl_protocols TLSv1.2;

ssl_prefer_server_ciphers on;

ssl_dhparam /etc/ssl/certs/dhparam.pem;

ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;

ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0

ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9

ssl_stapling on; # Requires nginx >= 1.3.7

resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

Activer le vhost en créant un lien symbolique vers le répertoire /etc/nginx/sites-enabled/ :

# ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

Relancer NGINX :

# systemctl restart nginx

Générer le certificat

Faire un test préalable

Il existe une limite pour la génération de certificat même quand celui ci comporte une erreur, si on est pas sûr de sa configuration il est préférable d’utiliser l’option --dry-run qui possède une limite beaucoup plus élevée et permet de faire un nombre assez important de tentatives par jours.

https://letsencrypt.org/docs/rate-limits/
https://letsencrypt.org/docs/staging-environment/

# certbot renew --dry-run

Création du certificat

Si vous n’avez aucune erreur vous pouvez lancer la vraie commande pou créer un certificat SSL avec Certbot :

# certbot certonly --agree-tos --email [email protected] --webroot -w /var/lib/letsencrypt/ -d example.com -d www.example.com

If the SSL certificate is successfully obtained, the following message will be printed on your terminal:

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/example.com/privkey.pem
Your cert will expire on 2018-07-28. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

Puis relancer NGINX

# systemctl reload nginx

Les noms de domaines avec des caractères accentués

Si votre nom de domaine comporte des caratères accentué comme síle-de-tansarville.fr un message d’erreur vous invitera à utiliser le Punycode.

# certbot --webroot -w /var/lib/letsencrypt/ -d síle-de-tansarville.fr -d www.síle-de-tansarville.fr
Non-ASCII domain names not supported. To issue for an Internationalized Domain Name, use Punycode.

Le Punycode est un encodage spécial utilisé pour convertir les caractères Unicode en ASCII (des accents et des caractères non latin), il est utilisé pour coder les noms de domaine internationalisés (IDN).
Le nom de domaine au format correspondant peut se trouver dans votre pannel d’administration des noms de domaines de votre registrar préféré ou vous pouvez utiliser cet outils de conversion : https://www.punycoder.com/.

Exemple :

我是猫.fr                      |   xn--wnup5g6so.fr
pizzas-végétaliennes.fr | xn--pizzas-vgtaliennes-iwbb.fr

Note : La configuration des Vhost dans le serveur web doit se faire sous forme Punycode.

Renouvellement automatique des certificats Let’s Encrypt

Les certificats de Let Encrypt sont valables 90 jours. Pour les renouveler automatiquement avant leur expiration, le paquet certbot crée un cronjob qui s’exécute deux fois par jour et renouvellera automatiquement tout certificat 30 jours avant son expiration.

Comme nous utilisons le plug-in certbot webroot, une fois le certificat renouvelé, nous devons également recharger le service NGINX. Ajoutez –renew-hook «systemctl reload nginx» au fichier /etc/cron.d/certbot de la manière suivante :

# vim /etc/cron.d/certbot
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew --renew-hook "systemctl reload nginx"

NOTE : Configuration actuelle, fonctionne sans problème :

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(4    3200))' && certbot -q renew

Puis faire un test pour vérifier la configuration

# certbot renew --dry-run

S’il n’y a pas d’erreur, cela signifie que le processus de renouvellement a réussi.

Backup des certificats

Il suffit simplement de copier le répertoire où Let’s Encrypt les génère.

# cp /etc/letsencrypt/ /chemin/letsencrypt.backup -r

Revoquer un certificat

Pour révoquer un certificat on utilise l’option --cert-path ansi que le chemin complet qui mène au certificat situé dans le répertoire archive de Let’s Encrypt.

# certbot revoke --cert-path /etc/letsencrypt/archive/www.mydomain.com/cert1.pem

Supprimer un certificat

Il suffit simplement de préciser l’option delete et une liste des domaines avec les certificats à supprimer s’affichera.

# certbot delete

Pour les problèmes de Cipher

Les sites à lire :

https://f4fia.wordpress.com/2015/08/09/configurer-son-serveur-web-en-https/
https://safeciphers.org/
VOIR LES GRADES

Erreurs rencontrées

Vérifications de base avant de commencer :

  • Le domaine et les sous-domaine possèdent bien un enregistrement A au niveau des DNS.
  • Le domaine et les sous-domaine sont définis dans NGINX.
  • La génération des certificats commence par la racine “mondomaine” : certbot certonly --webroot -w /var/lib/letsencrypt/ -d mondomaine.fr -d www.mondomaine.fr -d sous.mondomaine.fr.

Impossibilté de générer un certificat

Le certificat Let’s Encrypt ne pouvait être généré uniquement si le sous-domaine n’était PAS définis dans NGINX.
Je n’ai toujours pas compris pkoi Let’s Encrypt me donnait cette erreur :

IMPORTANT NOTES:
- The following errors were reported by the server:

Domain: cloud2.mondaine.fr
Type: unauthorized
Detail: Invalid response from
https://cloud2.mondaine.fr/.well-known/acme-challenge/KOfjrjkp..._fP
[42.42.42.42]: "<html>\r\n<head><title>403
Forbidden</title></head>\r\n<body
bgcolor=\"white\">\r\n<center><h1>403
Forbidden</h1></center>\r\n<hr><center>"

To fix these errors, please make sure that your domain name was
entered correctly and the DNS A/AAAA record(s) for that domain
contain(s) the right IP address.

Remarque : La génération du domaine racine mondomaine.fr seul entrainait la création d’un nouveau certificat nommé mondomaine-0002.cert laissant supposer qu’un mondomaine-0001.cert existait déjà (ce qui était le cas) en plus du mondomaine.cert qui avait fonctionnée jusque là.

Résolution du problème :

  • Faire un backup du dossier /etc/letsencrypt/

  • Plusieurs solutions :

    • Aller dans la config NGINX

      • Commenter les liens vers les certificats. Rententer de générez les certificats avec un --dry-run
      • Commenter la ou les lignes spécifiants les server_names. Rententer de générez les certificats avec un --dry-run
      • Mixer les deux
      • Et décommenter les liens si tout se passe bien
    • Supprimer tous les certificats et répertoires en lien avec le domaine en question :

      • /etc/letsencrypt/renewal/mondomaine*
      • /etc/letsencrypt/archive/mondomaine*
      • /etc/letsencrypt/live/mondomaine*
      • Rententer de générez les certificats avec un --dry-run

Problème avec Python

L’erreur en question au moment de la génération de n’importe quel certificat :

# certbot certonly --webroot -w /var/lib/letsencrypt/ -d n0tes.fr --dry-run
Traceback (most recent call last):
File "/usr/bin/certbot", line 11, in <module>
load_entry_point('certbot==0.28.0', 'console_scripts', 'certbot')()
File "/usr/lib/python3/dist-packages/certbot/main.py", line 1308, in main
log.pre_arg_parse_setup()
File "/usr/lib/python3/dist-packages/certbot/log.py", line 55, in pre_arg_parse_setup
temp_handler = TempHandler()
File "/usr/lib/python3/dist-packages/certbot/log.py", line 243, in __init__
stream = tempfile.NamedTemporaryFile('w', delete=False)
File "/usr/lib/python3.5/tempfile.py", line 679, in NamedTemporaryFile
prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
File "/usr/lib/python3.5/tempfile.py", line 269, in _sanitize_params
dir = gettempdir()
File "/usr/lib/python3.5/tempfile.py", line 435, in gettempdir
tempdir = _get_default_tempdir()
File "/usr/lib/python3.5/tempfile.py", line 370, in _get_default_tempdir
dirlist)
FileNotFoundError: [Errno 2] No usable temporary directory found in ['/tmp', '/var/tmp', '/usr/tmp', '/root']

Il est fort probable que l’espace disque soit saturé ou insuffisant.

Problème de Fething

Ce problème est survenu après avoir ajouté un enregistrement AAA pour le sous domaine www, en plus de celle déjà existante avec l’IPV4.

Domain: www.mondomain-linux.fr
Type: connection
Detail: Fetching
https://www.mondomain-linux.fr/.well-known/acme-challenge/gZUEoKyN4Q-H8jwHPc5_lTIgkTN4ms2YSfBNhDRCSLy0:
Error getting validation data

Après avoir effacé l’enregistrement AAAA le certificat a pu être regenéré.

https://letsencrypt.org/fr/docs/ipv6-support/

Problème de redirection

Dans cette eurreur on voit que Let’s Encrypt galère entre le .com et le .fr (alors que le certificat demandé n’est que pour le .com).

IMPORTANT NOTES:
- The following errors were reported by the server:

Domain: lesite.com
Type: unauthorized
Detail: Invalid response from
https://lesite.fr
[2642:5500:3032::6212:3d42]: "<!doctype html>\r\n<html
lang=\"fr\">\r\n\r\n<head>\r\n <title>Le titre de la page</title>\r\n <meta charset=\""

Domain: www.lesite.com
Type: unauthorized
Detail: Invalid response from
https://lesite.fr
[2642:5500:3032::6212:3d42]: "<!doctype html>\r\n<html
lang=\"fr\">\r\n\r\n<head>\r\n <title>Le titre de la page</title>\r\n <meta charset=\""

To fix these errors, please make sure that your domain name was
entered correctly and the DNS A/AAAA record(s) for that domain
contain(s) the right IP address.

Résolution :

Commenter dans NGINX la redirection, générez le certificat puis réactiver la redirection.

return 301 https://lesite.fr;

Documentation

https://letsencrypt.org/fr/docs/
https://letsencrypt.org/docs/rate-limits/
https://letsencrypt.org/docs/staging-environment/

https://linuxize.com/post/secure-nginx-with-let-s-encrypt-on-debian-9/
https://f4fia.wordpress.com/2015/08/09/configurer-son-serveur-web-en-https/
https://www.tfrichet.fr/lets-encrypt-supprimer-correctement-un-domaine/

https://www.punycoder.com/

https://safeciphers.org/

https://letsencrypt.org/fr/docs/ipv6-support/

> Partager <