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
相关产品推荐
相关产品推荐

