我已经建立了一个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
我的过程就是这样:
我正在使用的服务器加密配置是$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
答案 0 :(得分:2)
经过更多的探索和刺激后,我终于设法让这个工作了。问题与证书和密钥库有关。
由于这些问题,SSL握手会因证书链问题或密码套件协议问题而失败。 Cassandra相当无益地丢弃与SSL相关的错误并且没有记录任何内容。
无论如何,我通过以下方式成功地完成了工作:
-extensions
配置。这是我的双角色客户端/服务器证书的扩展部分。您可以将此包含在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文件,只需将cat
所有证书文件以相反的顺序从节点证书下载到CA根目录。
cat node1.crt ca-intermediate.crt ca-root.crt > node1-full-chain.crt