J'utilise apache2 (2.2.3) pour servir un site où j'aimerais que les clients s'authentifient avec des certificats. Étant donné que je dois seulement vérifier qu'un utilisateur présentant un certificat particulier est le même utilisateur qui a présenté ce certificat dans le passé, l'autorité de certification qui signe le certificat n'est pas pertinente. Il semble cependant que l'utilisation de SSLVerifyClient require
requiert SSLCACertificateFile ...
(ou SSLCACertificatePath ...
), puis apache n'acceptera que les certificats signés par une autorité de certification dans ce fichier / chemin. Existe-t-il un moyen pour apache d'accepter un certificat client, quelle que soit l'autorité de certification émettrice / chantante? (c.-à-d. vérifier que le client possède la clé privée correspondante à la clé publique présentée, mais pas la peine de vérifier l'AC émettrice / signataire)
9
mod_ssl
été conçu pour authentifier les utilisateurs sur la base d'une relation de signature de certificat; si vous préférez ignorer cela pour une raison quelconque, vous devrez implémenter l'authentification par certificat dans votre propre code qui gère également votre mappage certificat-utilisateur.mod_ssl
machinerie là-bas, j'espérais qu'il pourrait s'occuper d'une partie du travail pour moi.optional_no_ca
est que cela peut être meilleur pour l'interface utilisateur, car vous pouvez afficher un message d'erreur HTTP si quelque chose ne va pas avec le certificat (vous ne pourriez pas autrement, car un mauvais certificat client arrêterait la connexion avant la couche HTTP ). Il est également utile si vous souhaitez essayer d'autres méthodes de vérification d'un certificat (par exemple WebID ). Vous avez raison, vous voudriez que quelque chose fasse la vérification, et cela ne fonctionnerait vraiment que lorsque la demande est traitée par du code (par exemple dans PHP / CGI / Java), pas tellement avec des fichiers.Réponses:
Comme vous l'avez constaté, vous pouvez désactiver la vérification de certificat au niveau de la négociation SSL / TLS dans Apache Httpd à l'aide de
SSLVerifyCLient optional_no_ca
.Le deuxième problème auquel vous allez être confronté avec ce que vous essayez de faire est d'amener le client à envoyer le certificat. Étant donné que vos certificats ne sont pas destinés à faire partie d'une infrastructure à clé publique, ils peuvent être auto-signés et avoir différents émetteurs.
Lors de la demande d'un certificat client, le serveur envoie un
CertificateRequest
message TLS au client pendant le handhsake. Ce message contient lacertificate_authorities
liste:Les navigateurs l'utilisent pour choisir le certificat client à envoyer (le cas échéant).
(Notez que la partie sur la liste vide est uniquement dans la spécification à partir de TLS 1.1. SSL 3.0 et TLS 1.0 sont silencieux à ce sujet, et en pratique, cela fonctionnera également.)
Vous avez deux options pour cela.
Si les certificats clients que vous attendez vont être auto-signés, ils auront tous des émetteurs différents. Parce que vous ne savez pas à quoi vous attendre, le serveur devra envoyer une liste vide. Pour ce faire, utilisez la
SSLCADNRequestFile
directive et pointez-la vers un fichier qui ne contient qu'une ligne vide (si je me souviens bien, cela ne fonctionne pas avec un fichier complètement vide).La deuxième option (moins propre). Est de convenir d'un DN émetteur commun à tous les certificats clients que vous attendez, qu'ils aient effectivement été émis ou non par ce certificat CA (ou que cette CA existe ou non). Ce faisant, vous briseriez considérablement le modèle PKI (plus).
Si vous êtes d'accord sur un DN émetteur comme
CN=Dummy CA
(par exemple). Tout le monde peut créer un certificat auto-signé en utilisantCN=Dummy CA
comme DN d'objet (et DN d'émetteur), éventuellement avec des clés différentes. Bien que laSSLCADNRequestFile
directive s'attende à être configurée avec des certificats pour construire la liste, ceux-ci ne sont pas du tout utilisés pour vérifier le certificat client, c'est juste une manière compliquée (mais naturelle dans le contexte des autres directives) de configurer lacertificate_authorities
liste. Si vous, en tant que service, placez un certificat auto-signé avec ces nomsSSLCADNRequestFile
, cela fera que leCertificateRequest
message TLS sera utiliséCN=Dummy CA
dans lacertificate_authorities
liste (ce ne sont que des noms, pas des certificats à ce stade). Le client pourra alors récupérer son propre certificat auprès de l'émetteur DNCN=Dummy CA
, que sa signature puisse ou non être vérifiée par ce certificat (mêmes clés), car aucune vérification de signature n'est de toute façon impliquée dans ces étapes.Cela étant dit, n'oubliez pas qu'avec
SSLVerifyCLient optional_no_ca
, aucune vérification de certificat réelle n'est effectuée (je suppose que vous pouvez vérifier laSSL_CLIENT_VERIFY
variable si votre vérification manuelle n'est qu'une solution de secours à une PKI que vous avez configurée de toute façon). Tout ce que vous saurez à ce stade, c'est que le client possède la clé privée du certificat de clé publique qu'il a présenté (garanti par leCertificateVerify
message TLS ): vous devrez effectuer une certaine forme de vérification si vous voulez qu'il y ait authentification de certains Trier. (Vous ne pouvez pas faire confiance au contenu du certificat, c'est-à-dire à la liaison entre sa clé publique et les noms / attributs qu'il contient.)Cela ne fonctionnera pas bien pour les fichiers, mais vous pouvez le faire pour une application (par exemple PHP / CGI / ... même Java si vous passez le certificat au serveur Java mandaté). Une façon de base serait d'avoir une liste pré-connue de clés publiques, ou vous pouvez regarder les idées dans FOAF + SSL / WebID .
la source
L'utilisation
SSLVerifyCLient optional_no_ca
(au lieu derequire
) empêche Apache de vérifier l'autorité de certification émettrice (et donc de ne pas avoir besoin d'un fichier ou d'un chemin de certificat d'autorité de certification). Cela permet au client / utilisateur de ne pas soumettre de certificat, donc la vérification qu'un certificat a été utilisé doit être effectuée séparément.(Apparemment, je n'ai tout simplement pas lu attentivement la
mod_ssl
documentation.)la source