You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker中启用SSL连接Cassandra遇RemoteCertificateNameMismatch错误求助

Docker中Cassandra SSL连接证书名称不匹配问题

环境配置

  • Docker Compose配置:
version: '3.5'
services:
  mycassandra:
    container_name: mycassandra
    image: cassandra:4.0
    networks:
        mydockernetwork:

networks:
    mydockernetwork:
        name: my_docker_network
        driver: bridge
  • 证书配置:颁发的证书CN为mycassandra,SAN字段包含DNS=mycassandra和IP=172.19.0.7
  • Cassandra配置:集群名设置为mycassandra

C#连接代码

await Cluster.Builder()
    .AddContactPoints("mycassandra")
    .WithSSL(new SSLOptions().SetRemoteCertValidationCallback(
        (sender, certificate, chain, errors) =>
        {
            var hostEntry = Dns.GetHostEntry(_serviceConfig.DatabaseHostname);
            log.LogDebug("Dns.GetHostEntry: " + hostEntry.HostName + " (Cert Subject:" + certificate.Subject + ")");

            if (errors == SslPolicyErrors.None)
                return true;

            throw new Exception($"Hand no shakey error: {errors}");
        }
    ))
.Build().ConnectAsync("mykeyspace");

错误信息

Dns.GetHostEntry: mycassandra (Cert Subject:CN=mycassandra)

Could not establish connection with cassandra. Message: All hosts tried for query failed (tried 172.19.0.7:9042: Exception 'Database handshake error: RemoteCertificateNameMismatch')
---> Cassandra.NoHostAvailableException: All hosts tried for query failed (tried 172.19.0.7:9042: Exception 'Database handshake error: RemoteCertificateNameMismatch')
at Cassandra.Connections.Control.ControlConnection.Connect(Boolean isInitializing)
at Cassandra.Connections.Control.ControlConnection.InitAsync()
at Cassandra.Tasks.TaskHelper.WaitToCompleteAsync(Task task, Int32 timeout)
at Cassandra.Cluster.Init()
at Cassandra.Cluster.ConnectAsync(String keyspace)

注:跳过RemoteCertificateNameMismatch验证时,连接可正常工作

关键发现

检查SetRemoteCertValidationCallback的sender参数(SSLStream类型)时,发现sender.targethostname的值为mycassandra.mydockernetwork——这正是证书验证失败的核心原因:SSL握手时实际验证的是带Docker网络后缀的主机名,但现有证书的SAN条目里没有包含这个值。

解决方案

方案1:更新证书SAN条目

重新生成证书,在SAN字段中添加DNS=mycassandra.mydockernetwork,让证书覆盖握手时实际使用的主机名。

方案2:指定Docker服务的hostname

修改Docker Compose配置,为Cassandra服务显式设置hostname,避免自动添加网络后缀:

version: '3.5'
services:
  mycassandra:
    container_name: mycassandra
    hostname: mycassandra  # 添加这一行
    image: cassandra:4.0
    networks:
        mydockernetwork:

networks:
    mydockernetwork:
        name: my_docker_network
        driver: bridge

方案3:修改证书验证逻辑

在C#的验证回调中,兼容带后缀的主机名匹配,比如提取前缀或直接指定允许的主机名:

.WithSSL(new SSLOptions().SetRemoteCertValidationCallback(
    (sender, certificate, chain, errors) =>
    {
        var sslStream = sender as SslStream;
        var targetHost = sslStream?.TargetHost;
        // 允许mycassandra和mycassandra.mydockernetwork两种主机名
        if (targetHost != null && (targetHost.Equals("mycassandra") || targetHost.Equals("mycassandra.mydockernetwork")))
        {
            // 可额外添加证书链有效性验证逻辑
            return true;
        }
        // 处理其他错误情况
        if (errors == SslPolicyErrors.None)
            return true;

        throw new Exception($"Handshake error: {errors}");
    }
))

内容的提问来源于stack exchange,提问作者Pea Kay See Es

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:53:11