Utilisation d'Nginx comme reverse proxy avec un certificat auto-signé, Let's Encrypt et un chiffrement fort

De HomeServer.DIY.
Version du 25 mars 2016 à 15:39 par Tom23 (discuter | contributions)
(diff) ← Version précédente | Voir la version courante (diff) | Version suivante → (diff)
Aller à : Navigation, rechercher

Sommaire

Introduction

Le SSL est de plus en plus utilisé par les services auto-hébergés. En général ce protocole est géré par le serveur web qui reçoit les requêtes directement. Par contre si vous avez mis en place un reverse proxy, la chaîne de chiffrement se fera entre le navigateur, et ce fameux reverse proxy.

Utilisant NginX, je l'ai donc configuré pour qu'il fonctionne correctement avec ce type de requête en lui laissant gérer les certificats. Ceux-ci pourront être auto-signés grâce à openssl, ou délivrés par une autorité de certification. L'arrivée de Let's Encrypt permet à chacun d'avoir son propre certificat délivré par une autorité reconnue par tous les navigateurs. Nous verrons comment gérer ce type de certificats avec un reverse proxy, ainsi que la mise en place d'un système de chiffrement digne de se nom. Il faut d'abord avoir mis en place NginX en tant que cache et reverse proxy comme décrit ce tuto Installation et configuration d’un reverse proxy avec NginX.

Création des clés et certificats

Certificat auto signé

On commence par installer openssl qui nous permettra de créer les clés SSL et le certificat :

aptitude install openssl

Ensuite on crée un répertoire qui contiendra le certificat SSL dédié au site :

mkdir /etc/nginx/cle_nomdusite/

Le nom du répertoire n'a pas d'importance, mais il faudra le renseigner dans le fichier de configuration de NginX. On se rend dans ce répertoire afin que les clés y soient créées :

cd /etc/nginx/cle_nomdusite

D'abord il faut générer une clé RSA en 1024bits :

openssl genrsa -out server.key 1024

A partir de cette clé on crée le certificat générique :

openssl req -new -key server.key -out server.csr

Remplissez les champs demandés comme vous le souhaitez. On crée enfin le certificat au format x509 toujours grâce à openssl :

openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Cette façon de faire comporte quelques inconvénients. En effet, le chiffrement est plutôt faible, et votre certificat fera l'objet d'une alerte de sécurité de la part de votre navigateur que vous serez obligé de "contourner" en ajoutant une exception. Voyons maintenant comment faire bien mieux en utilisant Let's Encrypt.

Certificat let's encrypt

Beaucoup de tutos proposent de vous expliquer l'installation et l'utilisation de Let's Encrypt sous linux. Pour des raisons de simplicité nous allons la revoir, sans entrer dans les détails.

Connectez vous à la machine sur laquelle tourne le reverse proxy.

Déplacez vous dans le répertoire opt:

cd /opt

Copier let's encrypt depuis github (git devant être installé sur cette machine):

git clone https://github.com/letsencrypt/letsencrypt    

Déplacez vous dans le répertoire letsencrypt

cd /letsencrypt 

Ensuite il faudra stopper NginX et toutes les applications utilisant le port 80 (apache2, etc ...)

service nginx stop 

Création du certificat

./letsencrypt-auto certonly -d votrenomde.domaine --rsa-key-size 4096

Si vous utilisez www.votrenomde.domaine , il sera nécessaire de refaire l'opération en précisant " -d www.votrenomde.domaine dans la commande ci-dessus. Idem pour tout autre sous-domaine. Vous êtes obligés de créer un certificat pour chaque sous-domaine que vous utilisez.


Lorsque la création du certificat est terminée, le message suivant apparaîtra :

IMPORTANT NOTES:

- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/votrenomde.domaine/fullchain.pem. Your cert will
expire on 2016-02-10. To obtain a new version of the certificate in
the future, simply run Let's Encrypt again.

Configuration de NginX

Avant de commencer, notez que l'emplacement par défaut des fichiers de configurations indiquant le comportement du reverse proxy est indiqué dans le fichier /etc/nginx/nginx.conf. Selon votre version de NginX le chemin par défaut des fichiers de configuration peut changer exemple : NginX 1.6.2 /etc/nginx/site.enabled/ NginX 1.9.12 /etc/nginx/conf.d/*.conf


Configuration d'Nginx avec un certificat auto-signé

Ceci fait, il ne reste qu'à configurer NginX pour qu'il travaille avec les fichiers que nous venons de créer. Pour cela, la configuration se fait dans le fichier /etc/nginx/sites-available/default comme toute redirection via le reverse proxy.On édite le fichier en passant par un client SCP ou un éditeur de texte en ligne de commande comme nano. nano /etc/nginx/sites-available/default Il suffit donc d'ajouter ces lignes :

server {
   listen 443;
   server_name *.domaine.com;
   ssl on;
   ssl_certificate /etc/nginx/cle_nomdusite/server.crt;
   ssl_certificate_key /etc/nginx/cle_nomdusite/server.key;
   location / {
   proxy_pass https://192.168.0.129;
   }
}

listen 443 demande à NginX d'écouter sur le port 443. C'est le port par défaut à utiliser pour le SSL

server_name sous cette forme indique que la suite de la configuration s'appliquera aux requêtes sur le domaine "domaine.com" et tous ses sous-domaines. Si vous enlevez les 2 premiers caractères *. la configuration ne fonctionnera que pour le domaine.

ssl on indique que le SSL peut être utilisé pour cette redirection.

ssl_certificate désigne le répertoire et le nom du fichier servant de certificat.

ssl_certificate_key désigne le répertoire et le nom du fichier servant de clé RSA.

proxy_pass est l'adresse du serveur web vers lequel les requêtes doivent être redirigées.

Il est possible d'utiliser un même certificat pour plusieurs domaines/sites. Mais il peut être plus judicieux de créer un certificat par site et de les placer dans un répertoire dédié que l'on indiquera spécifiquement dans la configuration de NginX.Pensez à rediriger le port 443 vers la machine qui sert de reverse proxy, si vous êtes derrière un NAT.

Configuration d'Nginx et mise en place d'un chiffrement fort dans le cas de l'utilisation de Let's Encrypt

Pour cela, nous allons créer une clé en 4096 bits. Ceci peut prendre du temps en fonction de l'activité de votre machine. Soyez patient.

openssl dhparam -out /etc/ssl/private/dh4096.pem 4096

Cela étant fait, nous allons pouvoir modifier le fichier de configuration "default" d'NginX pour utiliser les clés et certificats créés précédemment. Nous allons aussi préciser quels sont les protocoles de chiffrement utilisés entre le navigateur et le serveur. Ceci afin d'avoir un chiffrement d'un niveau acceptable vis à vis des utilisateurs de vos services.

Vous ne pouvez pas avoir plusieurs configurations possibles pour le même domaine. Le fichier de configuration créé dans le chapitre traitant du certificat auto-signé devra être vidé de tout ce qui concerne le domaine en question.

Le fichier de configuration doit être mis en place de cette façon:

server {
   listen       443;
   server_name  votrenomde.domaine;
   ssl on;
   ssl_protocols TLSv1.2;
   ssl_certificate /etc/letsencrypt/live/votrenomde.domaineg/fullchain.pem;
   ssl_certificate_key /etc/letsencrypt/live/votrenomde.domaine/privkey.pem;
   ssl_dhparam /etc/ssl/private/dh4096.pem;
   ssl_ecdh_curve secp384r1;
   ssl_prefer_server_ciphers on;
   ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
   location / {
               proxy_pass https://192.168.0.60/;
           }
}

listen 443 indique à NginX d'écouter le port 443 pour les sessions https

server_name est tout simplement votre nom de domaine

ssl on indique que le chiffrement sera utilisé pour cette redirection

ssl_protocols permet d'indiquer les différents protocoles supportés

ssl_certificate indique l'emplacement du fichier servant de certificat. Attention, ce sera forcément un fichier appelé fullchain.pem lors de l'utilisation de Let's Encrypt. Pensez aussi à adapter l'arborescence.

ssl_certificate_key indique l'emplacement du fichier servant de clé privée. Attention, ce sera forcément un fichier appelé privkey.pem lors de l'utilisation de Let's Encrypt. Pensez aussi à adapter l'arborescence.

ssl_dhparam indique l'emplacement de la clé Diffie-Helman précédemment généré (dans notre cas etc/ssl/private/dh4096.pem)

ssl_ecdh_curve robustesse de la clé utilisé pour les échanges via courbe elliptique.

ssl_prefer_server_ciphers on indique au client que le serveur a des préférences en matière de suite cryptographiques (ciphers) et qu'il précise lesquelles à la ligne suivante.

ssl_ciphers liste est la liste des combinaisons d'algorithmes de chiffrement.

Les derniers paramètres location et proxy_pass étant identiques à toute configuration d'NginX en reverse proxy.

Indiquer comment forcer le https pour toutes les requêtes.

Forcer l'accès via https

Si vous souhaitez que l'on consulte votre site uniquement en https, il est tout à fait possible de le faire en ajoutant ces lignes à la suite de votre fichier de configuration.

server {
       listen 80;
            server_name       votrenomde.domaine;
             rewrite ^ https://$server_name$request_uri? permanent;
}

Conclusion

Avec cette solution je n'ai plus de problème pour accéder via SSL aux sites que j'héberge. Vous avez le choix d'auto-signer vos certificats ou de passer par Let's Encrypt, mais il serait dommage de se passer des services d'une autorité de certification reconnue par l'ensemble des navigateurs et évitant aux utilisateurs de créer des exceptions pour pouvoir visiter vos sites. Par contre, rien ne vous empêche de mettre en place le chiffrement tel qu'il est décrit dans la partie concernant Let's Encrypt avec un certificat auto-signé. La configuration telle qu'elle est présentée ici vous permettra d'avoir une sécurité lors des échanges entre votre site et le navigateur supérieure à celle proposée par la plupart des site bancaires.

A ce propos, il est très facile de vérifier le niveau de sécuroté d'un serveur utilisant SSL (https) en entrant l'url du site correspondant sur:

https://www.ssllabs.com/ssltest/

https://tls.imirhil.fr/

Sources

https://angristan.fr/configurer-https-nginx/

https://memo-linux.com/configurer-le-serveur-web-nginx-en-https-avec-letsencrypt-sous-debian-jessie/