RemoteCertificateNameMismatch when establishing secure connection with 3.x sdk

I’m upgrading to the 3.x sdk version and there is incompatibility issue when using tls connection. We’re using host names to connect to couchbase nodes and when tls is enabled the sdk throws BucketNotFoundException unless this flag KvIgnoreRemoteCertificateNameMismatch is enabled (true).

As far as I understand the issue is because now sdk uses ip address of a node while doing ssl authentication so that the certificate with a domain name in the subject will be invalid.

Any reason why the behavior has been changed this ways (I mean using ip address instead of host name or some generic solution using DnsEndpoint instead of IPEndPoint)?

internal interface IConnectionFactory
    {
        Task<IConnection> CreateAndConnectAsync(IPEndPoint endPoint, CancellationToken cancellationToken = default);
    }

Could someone please advice how I can workaround this without enabling this KvIgnoreRemoteCertificateNameMismatch flag? I think setting the flag to true isn’t safe, because the client can’t validate that it connects to the correct server

@eugene-shcherbo -

Its the same behavior as SDK2 - ClientConfiguration.IgnoreRemoteCertificateNameMismatch is the flag.

You can provide your own implementation of ClusterOptions.HttpCertificateCallbackValidation or ClusterOptions.KvCertificateCallbackValidation and do your own validation there.

The problem you’ll find is that the root certificate is shared and contains the single hostname as the subject of the entire cluster, however, when you bootstrap any node on the cluster is a candidate for bootstrap host. I believe there are ways to get around this via certificate configuration but its very environment specific.

Jeff

Hello Jeff,

Thank you for your reply.

Yeah, the flag is the same, but it seems like the SDK2 uses host name of a node for ssl authentication, but SDK3 uses ip address.

I got the idea about validation callback, will see what I can do.

Thank you for the help

Hello @jmorris

Returning to this, do you know any reason why the 3.x SDK uses an IP address of a target host instead of its domain name while doing ssl authentication with the host?

We use a wildcard cert a a root certificate and obviously default validation failed because it’s trying to match ip address to domain name. I don’t think it will work even if you have a certificate per node, because again the certificates are probably will be configured with domain name as the subject not IP.

Have I got you correctly thinking that you’re proposing having an IP address of a service as the subject name of a certificate?

@eugene-shcherbo

I believe I can answer this, so I’m going to give it a shot since @jmorris won’t be in for a bit.

The name used to connect to the cluster is mostly dependent on how the cluster itself is configured. The names (or IPs) in your connection string are only used once, for initial bootstrap to a single node. The node map is then downloaded from the first node, and then the server names (or IPs) in the node map are used going forward.

I suspect what you’ll find if you examine your cluster is that, on the Servers tab, your servers are listed by IP. If you want to use DNS name validation, I would recommend that they be registered by their canonical domain name when the cluster is built.

Another useful tool is the SDK Doctor. It can help you diagnose connection problems to your cluster. I’m not certain, but I suspect it may give you a warning about this scenario.

Hello @btburnett3 . Thanks for your reply.

I have domain names on the Serves tab. But I’m not sure how cluster configuration is connected to the target host ( which can be represented as a domain name or IP address) used while SSL authentication. When SDK calls AuthenticateAsClientAsync on the SslStream it seems like it always passes an IP (the IPEndPoint class) address of a node which is then used to validate the certificate.

Hmmm, you’re right. Seems like it may be a bug to me, but I’ll wait for @jmorris to weigh in.

1 Like

@eugene-shcherbo -

This is indeed a change from SDK2 to SDK3; there is a resolved ticket and a patch in review for release in 3.2.1.

Once 3.2.1 is released, you can change the current behavior (which should resolve your issue) by doing this:

var options = new ClusterOptions
{
       ForceIpAsTargetHost = false
};
var cluster = await Cluster.ConnectAsync("https://localhost", options);

Jeff

1 Like

Wow @jmorris , that is super cool. Thank you very much for this.

1 Like