TUTOS.EU

S'authentifier sur un site web avec un certificat avec nginx

Utiliser le proxy nginx sous linux pour s'authentifier sur un site web


Le but est de s'authentifier sur un site web perso, pour de la domotique par exemple, et de s'authentifier, non pas avec un login/mot de passe, mais avec un certificat.
Une solution est d'utiliser nginx que je vais mettre ici sur un raspberry pi.

Donc ici je me suis connecté en ssh avec putty sur un raspberry pi qui est connecté derrière ma box internet.
Pour être admin le reste de la session je tape

sudo -s
Lien vers le fichier : cliquez ici Copier le code

Pour la première partie j'ai suivi les indication d'openhab, une suite opensource de domotique :
https://www.openhab.org/docs/installation/security.html

Pour mettre à jour le dépot et installer nginx, j'ai tapé

sudo apt-get update && sudo apt-get install nginx
Lien vers le fichier : cliquez ici Copier le code

Si nginx est installé vous devez pouvoir accéder à /etc/nginx
et voir ses fichiers avec ces commandes :

cd /etc/nginx
ls -l
Lien vers le fichier : cliquez ici Copier le code

Démarrer le service puis regarder le log avec ces commandes

service nginx start
tail -f /var/log/syslog
Lien vers le fichier : cliquez ici Copier le code

Chez moi cela retourne
Started A high performance web server and a reverse proxy server.

nginx se configure un peu comme apache, cad qu'il y a un fichier de configuration par site/instance,
et que ce fichier de configuration doit se trouver dans un répertoire nommé sites-enabled situé dans /etc/nginx

Le fichier de configuration du site par défaut se nomme default

Pour le voir, taper

cd /etc/nginx/sites-enabled
ls
Lien vers le fichier : cliquez ici Copier le code

Par défaut la configuration ressemble à ceci, cad qu'il n'y a qu'un bloc server{} pour le paramétrage du site qui écoute sur le port 80

Ce fichier a une copie dans
/etc/nginx/sites-available

On va le réduire à peau de chagrin pour que le trafic soit redirigé sur la version https.
Aussi effacez le contenu de ce bloc serveur{} par ce qui est ce-dessous, en remplaçant ip_ou_url_de_votre_proxy_raspberrypi par l'ip de votre serveur/raspberry pi/serveur linux ou par son url si vous en avez fait une

server {
 listen 80;
 server_name ip_ou_url_de_votre_proxy_raspberrypi;
 return 301 https://$server_name$request_uri;
}
Lien vers le fichier : cliquez ici Copier le code

Ce qui donne après modification quelque-chose de simple comme ce qu'il y a ci-dessous.
L'ip 82.64.37.22 représente l'ip publique de ma box internet. A vous de l'adapter avec la votre.
Sachant derrière, sur ma box internet, j'ai fait une redirection vers mon raspberry pi où j'ai installé nginx

On va maintenant ajouter le plus important, cad le bloc server pour que nginx écouter en https et proxifie le flux vers votre serveur/page interne.
Le plus par rapport aux exemples de config que l'on trouve sur le net, ce sont les paramètres ssl_client_certificate et ssl_verify_client
Ce sont eux qui demandent aux client de s'authentifier avec un certificat, et non un login/mot de passe

server{
        listen 443 ssl http2; #Ecouter en ipv4 sur le port 443 en http2, possible à partir de la v1.9.5 de Nginx
        server_name                     server_name ip_ou_url_de_votre_proxy_raspberrypi; #Adresse de votre proxy nginx

        ssl_certificate                 /etc/ssl/nginx/nginx.crt; #Clé publique pour communiquer en https avec nginx
        ssl_certificate_key             /etc/ssl/nginx/nginx.key; #Clé privée pour communiquer en https avec nginx

        ssl_client_certificate          /etc/ssl/nginx/ca.crt; # Certificat de l'autorité de certification qui peut reconnaitre le certificat qui se présentera des clients
        ssl_verify_client                on; #Pour que les clients s'authentifient avec un certificat

        #HSTS est un header HTTP qui dit à un visiteur de se connecter directement en HTTPS à sa prochaine visite.
        #Cela permet donc dpavoir une communication entièrement chiffrée, et d'éviter la redirection du début
        add_header Strict-Transport-Security "max-age=15552000; includeSubdomains; preload";

        #Protocol
        #Toutes les versions de SSL sont à proscrire, cad SSL v1, v2 et v3. TLS v1.0, et v1.1 sont également à éviter.
        ssl_protocols TLSv1.2;

        #Ciphers
        ssl_ciphers EECDH+CHACHA20:EECDH+AESGCM:EECDH+AES;

        #TLS parameters
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 5m;
        ssl_session_tickets off;

    location / {
        proxy_pass                            http://ip_de_la_page_interne_que_vous_voulez_joindre;
        proxy_set_header Host $http_host;
        #$http_proxy_host;

        proxy_set_header X-Real-IP            $remote_addr;
        proxy_set_header X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto    $scheme;
    }


}
Lien vers le fichier : cliquez ici Copier le code

Vous devez donc maintenant avoir 2 blocs server
un pour écouter sur le port 80 et qui redirige tout sur le port 443
un pour écouter sur le port 443 : c'est lui qui porte votre configuration pour atteindre votre serveur interne et qui permet une authentification avec un certificat

Sauvegardez votre configuration et sortez de nano.

Pour la vérifier, taper

sudo nginx -t
Lien vers le fichier : cliquez ici Copier le code

Si elle est correcte, pour la prendre en compte, redémarrer nginx avec

service nginx restart
Lien vers le fichier : cliquez ici Copier le code

Pour qu'un client s'authentifie avec un certificat, cela se fait au niveau du navigateur web.
Il vous faut donc générer un certificat pour votre client.
Par contre, il faut charger dans le navigateur web le certificat avec la clé privée.
Pour cela il faut un format pfx. On le génère à partir du .cer et du .key.

Voici la commande openssl à utiliser :

openssl pkcs12 -export -in MonCertificat.cer -inkey macleeprivee.key -out MonCertificatConverti.pfx
Lien vers le fichier : cliquez ici Copier le code

Le certificat en entrée peut être un .crt à la place d'un .cer, ce n'est pas bloquant

openssl pkcs12 -export -in MonCertificat.crt -inkey macleeprivee.key -out MonCertificatConverti.pfx
Lien vers le fichier : cliquez ici Copier le code

Pour utiliser ce certificat pour s'authentifier, il faut l'importer dans votre navigateur.
Par exemple, sur Pc, sous chrome, pour importer le certificat en .pfx, aller dans les paramètres avancés

Puis dans Confidentialité et sécurité

Ensuite Gérer les certificats

Import

Filtrer sur les .pfx et sélectionnez votre certificat

Entrez le mot de passe du certificat

Le certificat de votre client est maintenant importé dans Chrome

Quand vous allez vous connecter à nginx, chrome vous demandera alors de sélectionner le certificat à utiliser pour l'authentification

Sous Chrome avec un téléphone Android,
pour importer votre certificat pfx utilisateur
comme expliqué sur
https://support.google.com/nexus/answer/2844832?hl=fr

  • Ouvrez l'application Paramètres Application Paramètres sur votre appareil.
  • Appuyez sur Sécurité et localisation puis Chiffrement et identifiants.
  • Sous "Stockage des identifiants", appuyez sur Installer depuis la mémoire.
  • En haut à gauche, appuyez sur Menu Menu.
  • Sous "Ouvrir à partir de", appuyez sur l'emplacement où vous avez enregistré votre certificat.
  • Appuyez sur le fichier. (Si nécessaire, saisissez le mot de passe du magasin de clés, puis appuyez sur OK).
  • Attribuez un nom au certificat.
  • Sélectionnez VPN et applications ou Wi-Fi.
  • Appuyez sur OK.

Pages Web

Site WebDescription
Community.openhab.orgUsing NGINX Reverse Proxy for client certificate authentication
Securing openHABSecuring access to openHAB
Configurer HTTPS sur NginxConfigurer HTTPS sur Nginx
Module ngx_http_ssl_moduleConfiguration du module ngx_http_ssl_module
HTTP/2 TestOutil de vérification de la compatibilité HTTP 2 pour un site

2