Comment utiliser un certificat générique ssl pour authentifier mutuellement plusieurs serveurs WCF via X509?

StackOverflow https://stackoverflow.com/questions/1630968

  •  06-07-2019
  •  | 
  •  

Question

J'ai deux serveurs WCF, tous deux situés sur le domaine mydomain.com (exemple fictif, comme le sont les adresses IP ci-dessous!), nommés respectivement server1 et server2.

Ils sont tous deux accessibles via leurs adresses IP publiques (foo.1 et 2), mais également depuis le réseau local privé sur lequel ils se trouvent (c'est-à-dire 192.168.0.1 et 192.168.0.2)

Je possède un certificat SSL générique pour * .mondomaine.com. Il est installé correctement dans les magasins correspondants (par exemple, Personal pour le chiffrement et Clients approuvés pour l'authentification)

J'aimerais que mes deux serveurs se connectent l'un à l'autre sur leurs adresses réseau locales en utilisant mon certificat générique à des fins d'authentification.

J'ai mis à jour le fichier C: \ Windows \ System32 \ drivers \ etc \ hosts pour lui donner l'aspect suivant:

192.168.0.1     Server1.mydomain.com
192.186.0.2     Server2.mydomain.com

Ce ne sont pas les adresses IP que je reçois si je résous Server1.mydomain.com (je préférerais obtenir foo.1 - 2)

J'ai également modifié le suffixe DNS spécifique à la connexion pour mes interfaces locales IPV4 vers "mydomain.com"

.

Mon certificat est appelé ainsi dans mes fichiers Server.config (j'ai supprimé toutes les parties non liées à l'authentification)

        <behavior name="ServerToServerBehavior" >
          <serviceCredentials>
            <clientCertificate>
              <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="Online"/>
            </clientCertificate>
            <serviceCertificate x509FindType="FindByThumbprint" findValue="13a41b3456e431131cd461de"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="myServerAsClientBehaviorConfiguration">
          <clientCredentials>
            <clientCertificate x509FindType="FindByThumbprint" findValue="13a41b3456e431131cd461de" storeLocation="LocalMachine"/>
            <serviceCertificate>
              <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="Online" trustedStoreLocation="LocalMachine"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>

Cela fonctionne parfaitement sur mon propre ordinateur de développement avec des certificats X509 générés localement, mais dans mon environnement de production, voici ce que je reçois:

  

Server.Connect: échec de la connexion à   serveur Server2:   System.ServiceModel.Security.MessageSecurityException:   Échec du contrôle d'identité pour le courrier sortant   message. L'identité DNS attendue de   le point final distant était   'serveur2.mondomaine.com' mais la télécommande   Revendication DNS fournie par le point de terminaison   "mydomain.com". Si c'est un   point final distant légitime, vous pouvez   résoudre le problème en explicitement   spécification de l'identité DNS 'mydomain.com'   en tant que propriété d'identité de   EndpointAddress lors de la création d'un canal   proxy.

J'ai essayé de faire en sorte que le serveur réponde à Server2.mydomain.com au lieu de simplement mydomain.com, sans succès. Avez-vous une idée de la façon de procéder?

J'ai également essayé la solution suggérée dans le message d'erreur, mais cela semble n'avoir aucun effet (les autres utilisateurs semblent avoir le même problème et je n'ai pas encore trouvé de solution). Une idée sur la façon de résoudre ce problème?

Modifier: J'ai vérifié auprès de mon fournisseur de certificat que je pouvais bien l'utiliser pour l'authentification X509.

Était-ce utile?

La solution

J'ai finalement compris pourquoi mon champ Identité était ignoré.

Mon point final a été construit comme suit:

DistantServer = new ServiceReferenceServerToServer.ServerToServerClient("myServerBinding", "net.tcp://server.mydomain.com/Server");

lorsque le paramètre uri est fourni, le champ d'identité DNS (défini dans le fichier app.config) est également remplacé (même s'il est vide, comme c'est le cas lorsque nous utilisons une chaîne au lieu d'un objet URI réel).

la solution consiste à le définir par programme à l'aide du code suivant:

        System.ServiceModel.EndpointAddress uri = new System.ServiceModel.EndpointAddress(new Uri("net.tcp://server.mydomain.com/Server"),new System.ServiceModel.DnsEndpointIdentity("mydomain.com"),new System.ServiceModel.Channels.AddressHeader[0]);

        DistantServer = new ServiceReferenceServerToServer.ServerToServerClient("myServerBinding", uri );

Autres conseils

Je pense que le remplacement de la revendication DNS par l’erreur mentionnée serait spécifié côté client, pas sur le serveur. Par conséquent, vous n’ouvrez rien en apportant cette modification, sauf que votre client peut se connecter à n’importe quel serveur de votre serveur. domaine (si c’était à l’écoute). L'erreur que vous voyez est un peu comme l'équivalent en sécurité des messages d'une incompatibilité de nom d'hôte sur le certificat. La sécurité des messages fonctionne avec les certificats génériques après de nombreuses manipulations, mais vous devrez peut-être effectuer un travail de validation personnalisé, car votre certificat ne dispose probablement pas de l’utilisation spécifiée pour l’authentification du client.

Une raison pour laquelle vous n'utilisez pas la sécurité des transports? BEAUCOUP plus simple de travailler, sauf si vous avez un routage intermédiaire Layer7 ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top