Shiro's blog

Comment sécuriser votre site web avec Nginx et Let's Encrypt ?

Translations: en

Introduction

Si vous avez un site web et qu'il ne supporte toujours pas le HTTPS, vous devriez vous mettre à la page. Une part grandissante du web est aujourd'hui délivré en utilisant ce protocole. Les navigateurs sanctionnent de plus en plus sévérement les sites web qui ne le proposent pas et ce pour élever le niveau de la sécurité chez l'utilisateur lambda.

Dans cet article, je vais expliquer comment j'ai mis en place le HTTPS pour mes sites web servis avec Nginx.

Comment ça marche ?

Nous allons utiliser le plugin "webroot" de certbot pour recevoir notre certificat.

Sur Ubuntu, certbot est pacakagé sous le nom letsencrypt, donc si vous ne l'avez pas encore:

apt-get install letsencrypt

Pour obtenir le certificat, nous allons devoir prouver que l'hôte demandant un certificat pour, par exemple, www.example.com, est bien celui vers lequel le nom de domaine pointe.

Pour ça, certbot va créer un dossier que nous devons exposer sur ce nom de domaine.

Let's Encrypt va requêter un fichier de ce dossier pour vérifier l'identité de la machine hôte. Si le résultat est positive, certbot va nous récupérer le certificat, ce qui va nous permettre de sécuriser le traffic vers notre site.

Modifier Nginx pour répondre au "challenge"

Premièrement, nous allons mettre en place la "location" pour letsencrypt dans la configuration nginx. C'est le chemin qui va être requêté.

Rajoutez les lignes suivantes dans le bloc "server" du domaine à sécuriser:

location /.well-known/ {
    root /var/lib/letsencrypt/;
}

.well-known/ est le nom du dossier créé par certbot quand il prépare l'identification de la machine hôte. Nous devons l'exposer à la racine du domaine.

/var/lib/letsencrypt/ est le dossier dans lequel nous allons informer certbot de mettre les informations nécessaires à l'identification. C'est ici qu'il va créer son dossier. Vous pouvez le changer mais attention à bien le faire pour toute la suite.

Ensuite, rechargez nginx pour prendre en compte les modifications.

service nginx reload

Utiliser let's encrypt pour obtenir un certificat

Maintenant que Nginx est prêt, nous pouvons demander notre certificat via certbot. Executez la commande suivante, en remplaçant blog.shir0.fr avec votre propre nom de domaine.

letsencrypt certonly --webroot -w /var/lib/letsencrypt -d blog.shir0.fr

Si cela réussi, certbot va créer le certificat et sa clé au emplacement /etc/letsencrypt/live/blog.shir0.fr/fullchain.pem et /etc/letsencrypt/live/blog.shir0.fr/privkey.pem, avec votre nom de domaine à la place du mien.

Ces fichiers sont valides pendant 90 jours. Vous pouvez soit les renouveler manuellement plus tard, ou automatiser leur renouvellement, ce que nous allons voir dans une prochaine section.

Activer le HTTPS

Pour activer le HTTPS, le serveur nginx doit écouter sur le port 443 et connaître l'emplacement des fichiers de certification. Pour cela, ajoutez les lignes suivantes dans la configuration du serveur et rechargez nginx.:

listen 443 ssl http2;
listen [::]:443 ssl http2;

ssl_certificate /etc/letsencrypt/live/blog.shir0.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blog.shir0.fr/privkey.pem;

Avec cela, vous devriez pouvoir accéder à votre site web en HTTPS. Il vous suffit, dans votre navigateur, de remplacer le http en début d'URL par HTTPS.

Forcer le HTTPS

Cette étape est optionnelle, mais vous pouvez forcer les visiteurs de votre site à utiliser HTTPS pour y accéder. Il suffit d'ajouter ces lignes avant les blocs "location".:

if ($scheme != "https") {
        return 301 https://$host$request_uri;
}

Encore une fois, il faut recharger nginx pour que le changement soit effectif.

Renouvellement automatique

Nous allons utiliser la crontab pour automatiser le renouvellement de nos certificats. Nous pouvons garder la même commande utilisée pour obtenir le certificat et ajouter l'option --keep à la fin. Elle permet à certbot de ne renouveller le certificat que s'il va bientôt expirer (il est considéré comme tel 30 jours avant l'expiration).

Nous allons exécuter cette commande quotidiennement, pour que certbot ai largement le temps de faire le remplacement. Même s'il y a une erreur réseau ou que le service letsencrypt est indisponible, il est très probable que le problème ne persiste pas un mois complet.

Il faut donc changer la crontab (with crontab -e) pour ajouter cette tàche.:

0 0 * * * letsencrypt certonly --webroot -w /var/lib/letsencrypt -d shir0.fr --keep

Les deux zéros au début de la ligne sont respectivement les heurs et les minutes. Vous pouvez les modifier pour faire tourner certbot à une heure différente.

À essayer si quelque chose ne fonctionne pas

  • Avez-vous bien rechargé le serveur nginx ?
  • Regarder du côté de error logs