Quand il s’agit de l’authentification sur le web, nous sommes à peu près tous familiers avec le mot de passe – roi de la colline, tristement célèbre à la fois pour ses défauts ainsi que son ubiquité. En dehors du mot de passe, vous avez souvent des schémas d’authentification tels que le partage de jetons (par exemple, les jetons OAuth ou RSA).
Une autre méthode que vous verrez très rarement est la forme de certificat client faible de l’authentification. Certs client sont liés aux certificats de serveur beaucoup plus populaires et existent dans la même poignée de main TLS. En d’autres termes, la même connexion initiale à partir de votre navigateur Web qui demande au serveur s’il a un certificat SSL, implique également le serveur demandant au navigateur s’il a un certificat SSL. L’adoption de la première a été importante au cours de la dernière décennie en raison de son utilisation dans HTTPS. Les certificats clients ne sont utiles que pour l’authentification, de sorte qu’en comparaison leur adoption a été plus limitée que les certificats serveur.
Malgré son manque de popularité et quelques aspects lourds, le cert client est compatible avec les navigateurs de bureau modernes et les serveurs Web. Pour certains cas d’utilisation, il est logique de renoncer à la commodité absolue du mot de passe pour la sécurité absolue des certificats SSL.
Mettre tout cela ensemble
Il y a quelques défauts laids que nous devons couvrir, mais je ne veux pas vous décourager en devenait trop technique dès le début. Au lieu de cela, nous allons travailler en arrière et jeter un oeil à la façon dont tout cela devrait se réunir.
Sur la photo ci-dessus, vous pouvez voir que le gestionnaire de certificat de Firefox a la possibilité de stocker des certificats personnels. Lors de l’utilisation de l’authentification cert client, le navigateur de l’utilisateur aurait un certificat d’une autorité de certificat de confiance. Sur la photo, vous pouvez voir que j’ai deux, un de Comodo pour mon e-mail, et un certificat d’auto-signe pour auth. Nous entrerons dans le bit auto-signé plus tard, mais cela ne représente pas le même risque que les certificats de serveur auto-signés.
En supposant que vous avez un certificat client dans votre navigateur (vous n’avez pas encore, mais ne vous inquiétez pas, nous allons revenir à cela), votre navigateur sera automatiquement l’envoyer au serveur lors de l’exécution de la même poignée de main TLS utilisé pour négocier HTTPS. C’est en supposant que le serveur demande effectivement un cert client.
La configuration Nginx ci-dessus est un extrait de la configuration de ce site. Les lignes 2-11 et 17 sont à peu près vos configurations HTTPS de base. J’inclus ceux pour l’exhaustivité puisque le fait de renoncer à HTTPS est une condition préalable à l’authentification du certificat client pour travailler; mais, honnêtement, j’espère que vous faites déjà cela.
Les lignes 13, 14 et 15 sont la vraie viande et les pommes de terre de la configuration du serveur;
ssl_verify_client – ceci est défini en option, ce qui signifie que nous demandons au navigateur un certificat client s’il en a un, et le valider s’il est fourni, mais Nginx ne manquera pas la poignée de main TLS si le navigateur ne fournit pas un.
ssl_client_certificate – cette configuration indique à Nginx à qui les autorités de certificat doivent faire confiance. Tout comme la façon dont les navigateurs Web maintiennent une liste de CA de confiance, cela permet à votre serveur d’avoir une liste similaire. Nginx énumérera ces CA par leur nom pendant la poignée de main.
ssl_verify_depth – enfin, ce paramètre permet à Nginx de savoir combien de certificats intermédiaires permettre. Les certificats clients sont rarement signés directement par le certificat racine de l’auteur du certificat; par conséquent, le réglage de ce à 2 accueille 1 signataire intermédiaire en plus du certificat racine, ce qui est assez typique.
Les trois éléments de configuration ci-dessus sont tout ce qui est nécessaire pour activer les certificats clients dans Nginx. Il en reste deux qui envisagent; comment pouvons-nous générer ces certificats, et comment imposer une forme significative d’authentification? Discutons d’abord de ce dernier.
Authentification de l’utilisateur
C’est une chose de demander au navigateur de fournir un certificat, c’est autre chose d’authentifier réellement un utilisateur. Dans la section précédente, nous avons défini ssl_verify_client en option. La raison en est que la plupart des sites Web ont un mélange de contenu public et privé. Vous ne voulez pas empêcher les utilisateurs d’accéder au contenu public, simplement parce qu’ils n’ont pas le certificat nécessaire pour les parties privées. Même les applications entièrement privées voudront exposer un certain type de page personnalisée pour ceux qui ne sont pas authentifiés en cours – par exemple une connexion ou une page d’inscription. Pour toutes ces raisons, la recommandation est de laisser la ssl_verify_client à l’option et de gérer toute logique supplémentaire dans l’application ou dans les règles de localisation Nginx.
Nginx fournit deux variables utiles pour affirmer l’authentification – ssl_client_verify and ssl_client_raw_cert.
La ssl_client_verify variable, dans sa forme la plus basique, équivaut à SUCCÈS lorsqu’un certificat client a été présenté et correspond à la liste fiable des CA du serveur (tel qu’il est défini avec ssl_client_certificate). Vous pouvez vous référer à la documentation Nginx pour d’autres valeurs qu’elle contient, mais pour la plupart des cas d’utilisation, il suffit de simplement tester l’égalité ou l’inégalité au SUCCÈS. Par exemple;
L’extrait ci-dessus est tiré de la configuration Nginx de ce site. Dans cet exemple, vous pouvez voir que ssl_client_verify est comparé à SUCCESS pour toute personne qui tente d’accéder à la page de connexion WordPress de ce site. La fourniture d’un certificat client valide transmet la demande à WordPress pour une authentification régulière basée sur le mot de passe – donc aucun écart par rapport à la configuration standard là-bas. Toutefois, pour les navigateurs sans certificat client valide, leur connexion sera immédiatement terminée par une erreur 404 – Accès refusé.
Dans ce cas d’utilisation, l’authentification du certificat client ne fournit qu’une couche supplémentaire de sécurité. Un besoin beaucoup, compte tenu du nombre endémique de tentatives de piratage automatisé effectuées contre les sites WordPress. Cette mesure de sécurité suppose également que la validation simple du certificat est suffisante pour filtrer le riff-raff. Cela fonctionne parce que Nginx est configuré pour ne faire confiance qu’à une liste définie d’autorités de certificat (voir la discussion ssl_client_certificate ci-dessus) – dans mon cas, mon propre CA.
Pour un contrôle plus fin, la variable ssl_client_raw_cert permet l’inspection du certificat client lui-même. Cette variable est codée par PEM, et nécessite donc un traitement supplémentaire pour la rendre utile. Pour cette raison, il est préférable de transmettre cette variable au serveur en amont pour inspection au niveau de l’application. En d’autres termes, nous allons farcir cette variable dans un en-tête HTTP et permettre ruby, nœud.js, .NET, Java, etc pour traiter le certificat formaté PEM dans la couche de demande, et soit autoriser ou rejeter la demande.
L’extrait ci-dessus illustre comment une telle variable peut être transmise au serveur en amont. Par convention HTTP en-tête commençant par « X » sont personnalisés, et il ya une fois libre de choisir n’importe quel nom que nous voulons, tant que Nginx et l’application en amont s’accordent sur la convention de nommage.
Ci-dessus est un exemple de ce que le contenu de cet en-tête ressemblera – un certificat codé PEM.
C’est entièrement à l’application client sur la façon de gérer les choses à partir de ce point. À titre de comparaison, cependant, ce n’est pas conceptuellement très différent de la gestion de l’authentification basée sur le mot de passe. La couche d’application doit avoir une logique pour valider le nom d’utilisateur et le mot de passe fournis, et pour répondre en conséquence. De même, une application faisant usage de l’authentification du certificat client devrait avoir une logique pour traiter le certificat codé PEM, extraire les champs qu’elle juge pertinents (très probablement le nom commun) et répondre en conséquence. La demande n’a pas besoin de valider le certificat, car la validation a été traitée par Nginx avant de transmettre la demande.
Les détails laids
Clés et certificats – dire ces mots à la plupart des développeurs et ils grincer des dents. À juste titre, il ya peu dans la manière de l’utilisateur sans amis – vraiment un produit de la fonction sur la forme. Aimez-les, ou haïssez-les, ils sont une nécessité dans notre monde moderne. Après avoir résisté aux pressions de décennies de cryptoanalyse, ils sont la priorité numéro un est d’obtenir une assistance numérique, pas nécessairement rendre la vie des développeurs plus facile. C’est pour ces raisons que j’ai décidé de couvrir ce sujet en dernier.
Si vous voulez vraiment sauter cette section, vous êtes toujours les bienvenus pour acheter un certificat commercial. Les vendeurs tels que Comodo vendent des billets d’authentification client pour environ le prix d’un dîner pour deux – bien qu’il s’agit d’une taxe annuelle. Mis à part le coût, les inconvénients d’un certificat commercial sont que la validation simple avec ssl_client_verify, comme nous l’avons vu ci-dessus, n’est pas aussi pratique. Dans cet exemple, j’ai montré comment ce blog même utilise la validité du certificat seul en tant que gardien. Cela fonctionne pour mon blog parce qu’il valide contre ma propre autorité de certificat. Puisque je ne génère pas de certs pour tout le monde, je sais que si quelqu’un a un cert authentique, ils vont très probablement moi.
Contrairement aux certificats de serveur, il y a peu d’inconvénients aux certificats clients autosignés. Les dangers liés aux certificats de serveur autosignés découlent de l’aspect confiance du client. Faire confiance à tout certificat revient à faire confiance à une ou plusieurs autorités de certificat pour délivrer des certificats en toute sécurité et correctement. Les navigateurs font confiance aux autorités de certificat s’appuyant sur une liste bien vérifiée de CA regroupés dans chaque navigateur. Lorsqu’ils sont confrontés à un certificat de recherche par ailleurs valide, les navigateurs rejetteront la connexion si ce n’est d’un CA de confiance. Les utilisateurs peuvent passer outre à ce comportement, mais un tel comportement est découragé en raison des dangers d’un utilisateur faisant confiance par inadvertance au mauvais cert. La probabilité d’une attaque de l’homme au milieu est trop élevée, et la plupart des sites Web n’utilisent pas de certs auto-signés. C’est là que réside les dangers.
Lorsqu’ils sont correctement distribués, les certificats autosignés peuvent être tout aussi sûrs que les certificats commerciaux – mais c’est un BIG si pour les certs serveur. Pour les certs clients, les risques sont pratiquement éliminés. Les navigateurs ne se soucient pas de savoir qui délite leurs certificats de client puisqu’ils conservent à la fois la clé publique et la clé privée. Le serveur, vraisemblablement exploité par la même personne ou organisation qui est auto-signature certs peuvent intrinsèquement se faire confiance – j’espère.
Assez de retard de ma part, regardons comment nous générons ces certificats.
La première étape est que nous devons devenir une autorité de certificat. L’utilisation d’OpenSSL est relativement facile.
Tout d’abord, vérifiez le réglage dir dans la section [ ca_default ] de la configuration OpenSSL – vous trouverez généralement cela dans /etc/ssl. Le paramètre dir doit pointer vers ca, faisant le chemin complet /etc/ssl/ca – c’est le chemin que ces exemples utiliseront. Si votre chemin ne correspond pas, mettez à jour le config OpenSSL ou les scripts suivants pour correspondre les uns aux autres.
Avec cela vérifié, il est temps de créer notre autorité de certificat.
Le script ci-dessus s’occupe de tout le levage lourd. Vous serez invité pour un mot de passe pour le certificat du CA – s’il vous plaît rappelez-vous cela, ce n’est pas quelque chose que vous voudrez oublier. Avec cette configuration unique terminée, nous sommes maintenant prêts à créer un ou plusieurs certificats clients. Cela aussi peut être automatisé en un script simple.
Le nom d’utilisateur du client doit être fourni comme premier argument lors de l’appel de ce script. Puisque nous sommes notre propre CA, ce nom d’utilisateur peut être tout ce que nous voulons – même une adresse e-mail. La seule exigence est qu’il est unique au sein de notre propre CA.
Lorsque le script créer-utilisateur se termine, vous aurez un mot de passe protéger PKCS #12 formaté certificat client prêt à importer dans votre navigateur. Vous avez fini – allez-y et importez-le. Les chemins d’emplacement Nginx protégés dans les sections antérieures devraient maintenant être accessibles.
En conclusion
L’authentification des certificats clients, bien qu’elle ne soit pas pratique pour tous les scénarios, est un outil précieux à mettre à votre disposition. Avec un support intégré directement dans les navigateurs de bureau modernes et Nginx, la configuration peut être achevée en quelques minutes, mais pourtant fournir une protection bien supérieure aux mots de passe réguliers. De loin les plus gros inconvénients de cette technique est son manque de soutien dans les navigateurs mobiles et les tracas associés à la distribution initiale du certificat client. Ne vous attendez pas à ce que cela remplace les mots de passe, mais est une option idéale pour une sécurité supplémentaire sur les pages admin privées pour les petites entreprises ou les sites Web personnels.