启用节点加密后,Cassandra节点无法看到对方

时间:2015-12-02 15:10:20

标签: ssl encryption cassandra

我已经建立了一个6节点的Cassandra集群,跨越两个AWS区域/数据中心(每个3个),一切正常。在做了那么多的工作之后,我试图启用节点加密,这是我无法正常工作的,尽管阅读了关于这个主题的无数文档并且无休止地进行了调整。

我在日志中看不到任何错误或任何异常。我在日志中看到以下行,表明它已按预期启动了加密消息服务:

MessagingService.java:482 - Starting Encrypted Messaging Service on SSL port 7001

我在cassandra-env.sh中启用了SSL的详细日志记录,但这不会产生任何错误或有关我可以看到的SSL节点间连接的其他信息更新下面):

JVM_OPTS="$JVM_OPTS -Djavax.net.debug=ssl"

可以使用nc从一个节点连接到加密消息传递端口7001上的所有其他节点,因此没有防火墙问题。

ubuntu@ip-5-6-7-8:~$ nc -v 1.2.3.4 7001
Connection to 1.2.3.4 7001 port [tcp/afs3-callback] succeeded!

可以使用cqlsh在本地连接到每个节点(我没有启用客户端 - 服务器加密),并且可以查询系统密钥空间等。

但是,如果我运行nodetool status,我发现节点无法看到对方。列表中仅显示我正在查询群集的节点。在启用节点间加密之前情况并非如此,他们都可以看到对方就好了。

ubuntu@ip-5-6-7-8:~$ nodetool status
Datacenter: us-east_A
=====================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address        Load       Tokens       Owns    Host ID                               Rack
UN  1.2.3.4        144.75 KB  256          ?       992ae1bc-77e4-4ab1-a18f-4db62bb0ce6f  1b

我的过程就是这样:

  • 为我的群集创建了证书颁发机构
  • 为每个节点创建了一个密钥库和信任库,并将我的CA证书链添加到了两个
  • 为每个节点生成密钥对和CSR,与我的CA签名,并将生成的证书添加到每个节点的密钥库
  • 将每个节点的配置更新为以下内容
  • 重新启动所有节点

我正在使用的服务器加密配置是$variables中的适当值。

server_encryption_options:
    internode_encryption: all
    keystore: $keystore_path
    keystore_password: $keystore_passwd
    truststore: $truststore_path
    truststore_password: $truststore_passwd
    require_client_auth: true
    protocol: TLS
    algorithm: SunX509
    store_type: JKS
    cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]

如果有人能提供一些见解或指导,那将非常感激。

更新:密码套件协议

显然SSL调试日志记录打印到stdout,它没有记录到Cassandra的日志文件中,所以我之前没有看到输出。在前台运行Cassandra我可以看到大量的SSL错误追踪,所有这些都抱怨握手失败,因为:

javax.net.ssl.SSLHandshakeException: no cipher suites in common

为了解决这个问题,我已经切换到Oracle JRE(之前我很懒惰并使用OpenJDK)并安装了JCE无限强度加密策略文件,以确保支持所有可能的密码。

它没有解决任何问题。

鉴于所有这些节点完全相同,这一点尤其令人困惑:硬件,操作系统供应商和版本,Java供应商和版本,Cassandra版本和配置文件。我无法想象为什么他们在这种情况下无法就密码套件达成一致。

以下是跟踪的完整错误:

*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1449074039 bytes = { 205, 93, 27, 38, 184, 219, 250, 8, 232, 46, 117, 84, 69, 53, 225, 16, 27, 31, 3, 7, 203, 16, 133, 156, 137, 231, 238, 39 }
Session ID:  {}
Cipher Suites: [TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
***
%% Initialized:  [Session-3, SSL_NULL_WITH_NULL_NULL]
%% Invalidated:  [Session-3, SSL_NULL_WITH_NULL_NULL]
ACCEPT-/1.2.3.4, SEND TLSv1.2 ALERT:  fatal, description = handshake_failure
ACCEPT-/1.2.3.4, WRITE: TLSv1.2 Alert, length = 2
ACCEPT-/1.2.3.4, called closeSocket()
ACCEPT-/1.2.3.4, handling exception: javax.net.ssl.SSLHandshakeException: no cipher suites in common
ACCEPT-/1.2.3.4, called close()
ACCEPT-/1.2.3.4, called closeInternal(true)
INFO  16:33:59 Waiting for gossip to settle before accepting client requests...
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
ACCEPT-/1.2.3.4, setSoTimeout(10000) called
ACCEPT-/1.2.3.4, READ:  SSL v2, contentType = Handshake, translated length = 57

1 个答案:

答案 0 :(得分:2)

经过更多的探索和刺激后,我终于设法让这个工作了。问题与证书和密钥库有关。

由于这些问题,SSL握手会因证书链问题或密码套件协议问题而失败。 Cassandra相当无益地丢弃与SSL相关的错误并且没有记录任何内容。

无论如何,我通过以下方式成功地完成了工作:

  • 确保CA使用 客户端和服务器密钥用法属性生成节点证书。未能包含其中一个将阻止节点正确地相互进行身份验证。这表现为密码套件协议错误。如果您使用OpenSSL来管理您的CA,我已经包含了我在下面使用的-extensions配置。
  • 确保您使用的根证书和任何中间CA证书(如果您使用的是中间CA)都已导入密钥库和信任库。
  • 确保导入密钥库的节点证书包含从主证书到CA根目录的完整信任链,包括任何中介 - 即使您已将这些CA证书单独导入到密钥库。如果不这样做,就会将其视为无效的证书链错误。

OpenSSL CA Config

这是我的双角色客户端/服务器证书的扩展部分。您可以将此包含在OpenSSL配置文件中,并在签名时通过指定-extensions dual_cert来引用它。

[ dual_cert ]
# Extensions for dual-role user/server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, server
nsComment = "Client/Server Dual-role Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth

创建包含完整信任链的PEM

要创建包含节点证书的完整信任链的单个PEM文件,只需将cat所有证书文件以相反的顺序从节点证书下载到CA根目录。

cat node1.crt ca-intermediate.crt ca-root.crt > node1-full-chain.crt