Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a ssl wildcard certificate to mutually authenticate several WCF servers via X509?

I've got two WCF servers, both on the domain mydomain.com (fictional example, as are IP below !), respectively named server1 and server2.

They are both accessible through their public IP addresses (foo.1 and 2), but also from the private LAN they are on (ie 192.168.0.1 and 192.168.0.2)

I own a wildcard ssl certificate for *.mydomain.com. It's installed correctly in the relevant stores (ie Personal for encryption and Trusted Clients for Authentication)

I'd like both my servers to connect with one another on their local network addresses using my wildcard certificate for authentication purposes.

I've updated the C:\Windows\System32\drivers\etc\hosts file to make it look like this :

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

Those are not the IP addresses I get if I resolve Server1.mydomain.com (I would rather get foo.1 - 2)

I've also edited the Connection-specific DNS suffix for my IPV4 local interfaces to "mydomain.com"

My certificate is referred to like this in my Server.config files (I've stripped all the parts not related to authentication)

        <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>

This works perfectly fine on my own dev computer with locally generated X509 certificates, but in my production environment, here's what I get :

Server.Connect : Failed to connect to server Server2 : System.ServiceModel.Security.MessageSecurityException: Identity check failed for outgoing message. The expected DNS identity of the remote endpoint was 'server2.mydomain.com' but the remote endpoint provided DNS claim 'mydomain.com'. If this is a legitimate remote endpoint, you can fix the problem by explicitly specifying DNS identity 'mydomain.com' as the Identity property of EndpointAddress when creating channel proxy.

I've tried to get the server to answer Server2.mydomain.com instead of just mydomain.com, without success. Any hint on how to do this?

I've also tried the solution suggested in the error message, but this seems to have no effect at all (other users seem to have the same problem and I've yet to find a solution). Any idea on how to fix this ?

Edit : I've check with my certificate provider that I can indeed use it for X509 authentication.

like image 514
Brann Avatar asked Dec 05 '25 14:12

Brann


1 Answers

I eventually understood why my Identity field was being ignored.

My endpoint was constructed like this :

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

when the uri parameter is provided, the DNS identity field (defined in the app.config), is overridden as well (even if it's empty, which is the case when we use a string instead of a real URI object).

the solution is to set it programatically using the following code :

        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 );
like image 121
Brann Avatar answered Dec 09 '25 03:12

Brann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!