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

BWW*_*BWW 7 encryption ssl cassandra

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

我没有在日志中看到任何错误或任何异常.我确实在日志中看到以下行,表明它已按预期启动了加密消息传递服务:

MessagingService.java:482 - Starting Encrypted Messaging Service on SSL port 7001
Run Code Online (Sandbox Code Playgroud)

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

JVM_OPTS="$JVM_OPTS -Djavax.net.debug=ssl"
Run Code Online (Sandbox Code Playgroud)

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

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!
Run Code Online (Sandbox Code Playgroud)

可以使用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
Run Code Online (Sandbox Code Playgroud)

我的过程是这样的:

  • 为我的群集创建了证书颁发机构
  • 为每个节点创建了密钥库和信任库,并将我的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]
Run Code Online (Sandbox Code Playgroud)

如果任何人可以提供一些见解或方向来查看它将不胜感激.

更新:密码套件协议

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

javax.net.ssl.SSLHandshakeException: no cipher suites in common
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,我已经切换到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
Run Code Online (Sandbox Code Playgroud)

BWW*_*BWW 2

经过大量的探索和刺激,我终于成功地让它发挥作用。该问题与证书和密钥库有关。

\n\n

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

\n\n

无论如何,我通过执行以下操作设法使事情正常进行:

\n\n
    \n
  • 确保 CA 生成具有客户端和服务器密钥使用属性的节点证书。未能包含其中之一将导致节点无法正确地相互验证。这表现为密码套件协议错误。如果您使用 OpenSSL 来管理您的 CA,我已将-extensions在下面提供了我使用的配置。
  • \n
  • 确保您使用的根证书和任何中间 CA 证书(如果您使用中间 CA)均导入到密钥库和信任库中。
  • \n
  • 确保导入到密钥库中的节点证书包含从主证书到 CA 根的完整信任链,包括任何中介 \xe2\x80\x93\xc2\xa0,即使您已将这些 CA 证书单独导入到密钥库中也是如此。如果不这样做,就会出现无效的证书链错误。
  • \n
\n\n

OpenSSL CA 配置

\n\n

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

\n\n
[ dual_cert ]\n# Extensions for dual-role user/server certificates (`man x509v3_config`).\nbasicConstraints = CA:FALSE\nnsCertType = client, server\nnsComment = "Client/Server Dual-role Certificate"\nsubjectKeyIdentifier = hash\nauthorityKeyIdentifier = keyid,issuer:always\nkeyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment\nextendedKeyUsage = clientAuth, serverAuth\n
Run Code Online (Sandbox Code Playgroud)\n\n

创建包含完整信任链的 PEM

\n\n

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

\n\n
cat node1.crt ca-intermediate.crt ca-root.crt > node1-full-chain.crt\n
Run Code Online (Sandbox Code Playgroud)\n