diff --git a/CHANGES.txt b/CHANGES.txt index 728a529c87..6e0853c3a4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 3.0.30 + * Backport CASSANDRA-10508: Remove hard-coded SSL cipher suites (CASSANDRA-18575) * Suppress CVE-2023-2976 (CASSANDRA-18562) * Remove dh_python use in Debian packaging (CASSANDRA-18558) * Pass down all contact points to driver for cassandra-stress (CASSANDRA-18025) diff --git a/conf/cassandra.yaml b/conf/cassandra.yaml index ec2157b4a0..da6874e699 100644 --- a/conf/cassandra.yaml +++ b/conf/cassandra.yaml @@ -909,10 +909,14 @@ request_scheduler: org.apache.cassandra.scheduler.NoScheduler # request_scheduler_id: keyspace # Enable or disable inter-node encryption -# Default settings are TLS v1, RSA 1024-bit keys (it is imperative that -# users generate their own keys) TLS_RSA_WITH_AES_128_CBC_SHA as the cipher -# suite for authentication, key exchange and encryption of the actual data transfers. -# Use the DHE/ECDHE ciphers if running in FIPS 140 compliant mode. +# JVM defaults for supported SSL socket protocols and cipher suites can +# be replaced using custom encryption options. This is not recommended +# unless you have policies in place that dictate certain settings, or +# need to disable vulnerable ciphers or protocols in case the JVM cannot +# be updated. +# FIPS compliant settings can be configured at JVM level and should not +# involve changing encryption settings here: +# https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/FIPS.html # NOTE: No custom encryption options are enabled at the moment # The available internode options are : all, none, dc, rack # diff --git a/src/java/org/apache/cassandra/config/EncryptionOptions.java b/src/java/org/apache/cassandra/config/EncryptionOptions.java index 497768f219..7231c55ef1 100644 --- a/src/java/org/apache/cassandra/config/EncryptionOptions.java +++ b/src/java/org/apache/cassandra/config/EncryptionOptions.java @@ -17,6 +17,8 @@ */ package org.apache.cassandra.config; +import javax.net.ssl.SSLSocketFactory; + import java.net.InetAddress; import org.slf4j.Logger; @@ -33,11 +35,7 @@ public abstract class EncryptionOptions public String keystore_password = "cassandra"; public String truststore = "conf/.truststore"; public String truststore_password = "cassandra"; - public String[] 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" - }; + public String[] cipher_suites = ((SSLSocketFactory)SSLSocketFactory.getDefault()).getDefaultCipherSuites(); public String protocol = "TLS"; public String algorithm = "SunX509"; public String store_type = "JKS"; @@ -55,7 +53,6 @@ public abstract class EncryptionOptions { all, none, dc, rack } - public InternodeEncryption internode_encryption = InternodeEncryption.none; public boolean shouldEncrypt(InetAddress endpoint) diff --git a/src/java/org/apache/cassandra/security/SSLFactory.java b/src/java/org/apache/cassandra/security/SSLFactory.java index 56a3a3f122..bef4a60298 100644 --- a/src/java/org/apache/cassandra/security/SSLFactory.java +++ b/src/java/org/apache/cassandra/security/SSLFactory.java @@ -53,28 +53,18 @@ import com.google.common.collect.Sets; public final class SSLFactory { private static final Logger logger = LoggerFactory.getLogger(SSLFactory.class); - public static final String[] ACCEPTED_PROTOCOLS = new String[] {"SSLv2Hello", "TLSv1", "TLSv1.1", "TLSv1.2"}; private static boolean checkedExpiry = false; public static SSLServerSocket getServerSocket(EncryptionOptions options, InetAddress address, int port) throws IOException { SSLContext ctx = createSSLContext(options, true); - SSLServerSocket serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(); - try - { - serverSocket.setReuseAddress(true); - String[] suites = filterCipherSuites(serverSocket.getSupportedCipherSuites(), options.cipher_suites); - serverSocket.setEnabledCipherSuites(suites); - serverSocket.setNeedClientAuth(options.require_client_auth); - serverSocket.setEnabledProtocols(ACCEPTED_PROTOCOLS); - serverSocket.bind(new InetSocketAddress(address, port), 500); - return serverSocket; - } - catch (IllegalArgumentException | SecurityException | IOException e) - { - serverSocket.close(); - throw e; - } + SSLServerSocket serverSocket = (SSLServerSocket)ctx.getServerSocketFactory().createServerSocket(); + serverSocket.setReuseAddress(true); + String[] suites = filterCipherSuites(serverSocket.getSupportedCipherSuites(), options.cipher_suites); + serverSocket.setEnabledCipherSuites(suites); + serverSocket.setNeedClientAuth(options.require_client_auth); + serverSocket.bind(new InetSocketAddress(address, port), 500); + return serverSocket; } /** Create a socket and connect */ @@ -82,18 +72,9 @@ public final class SSLFactory { SSLContext ctx = createSSLContext(options, true); SSLSocket socket = (SSLSocket) ctx.getSocketFactory().createSocket(address, port, localAddress, localPort); - try - { - String[] suites = filterCipherSuites(socket.getSupportedCipherSuites(), options.cipher_suites); - socket.setEnabledCipherSuites(suites); - socket.setEnabledProtocols(ACCEPTED_PROTOCOLS); - return socket; - } - catch (IllegalArgumentException e) - { - socket.close(); - throw e; - } + String[] suites = filterCipherSuites(socket.getSupportedCipherSuites(), options.cipher_suites); + socket.setEnabledCipherSuites(suites); + return socket; } /** Create a socket and connect, using any local address */ @@ -101,18 +82,9 @@ public final class SSLFactory { SSLContext ctx = createSSLContext(options, true); SSLSocket socket = (SSLSocket) ctx.getSocketFactory().createSocket(address, port); - try - { - String[] suites = filterCipherSuites(socket.getSupportedCipherSuites(), options.cipher_suites); - socket.setEnabledCipherSuites(suites); - socket.setEnabledProtocols(ACCEPTED_PROTOCOLS); - return socket; - } - catch (IllegalArgumentException e) - { - socket.close(); - throw e; - } + String[] suites = filterCipherSuites(socket.getSupportedCipherSuites(), options.cipher_suites); + socket.setEnabledCipherSuites(suites); + return socket; } /** Just create a socket */ @@ -120,18 +92,9 @@ public final class SSLFactory { SSLContext ctx = createSSLContext(options, true); SSLSocket socket = (SSLSocket) ctx.getSocketFactory().createSocket(); - try - { - String[] suites = filterCipherSuites(socket.getSupportedCipherSuites(), options.cipher_suites); - socket.setEnabledCipherSuites(suites); - socket.setEnabledProtocols(ACCEPTED_PROTOCOLS); - return socket; - } - catch (IllegalArgumentException e) - { - socket.close(); - throw e; - } + String[] suites = filterCipherSuites(socket.getSupportedCipherSuites(), options.cipher_suites); + socket.setEnabledCipherSuites(suites); + return socket; } @SuppressWarnings("resource") diff --git a/src/java/org/apache/cassandra/thrift/CustomTThreadPoolServer.java b/src/java/org/apache/cassandra/thrift/CustomTThreadPoolServer.java index efa93300cb..c50904e8ab 100644 --- a/src/java/org/apache/cassandra/thrift/CustomTThreadPoolServer.java +++ b/src/java/org/apache/cassandra/thrift/CustomTThreadPoolServer.java @@ -257,8 +257,7 @@ public class CustomTThreadPoolServer extends TServer SSLServerSocket sslServerSocket = (SSLServerSocket) sslServer.getServerSocket(); String[] suites = SSLFactory.filterCipherSuites(sslServerSocket.getSupportedCipherSuites(), clientEnc.cipher_suites); sslServerSocket.setEnabledCipherSuites(suites); - sslServerSocket.setEnabledProtocols(SSLFactory.ACCEPTED_PROTOCOLS); - serverTransport = new TCustomServerSocket(sslServer.getServerSocket(), args.keepAlive, args.sendBufferSize, args.recvBufferSize); + serverTransport = new TCustomServerSocket(sslServerSocket, args.keepAlive, args.sendBufferSize, args.recvBufferSize); } else { diff --git a/src/java/org/apache/cassandra/transport/Server.java b/src/java/org/apache/cassandra/transport/Server.java index 012b3266d5..36587c4aa8 100644 --- a/src/java/org/apache/cassandra/transport/Server.java +++ b/src/java/org/apache/cassandra/transport/Server.java @@ -418,7 +418,6 @@ public class Server implements CassandraDaemon.Server String[] suites = SSLFactory.filterCipherSuites(sslEngine.getSupportedCipherSuites(), encryptionOptions.cipher_suites); sslEngine.setEnabledCipherSuites(suites); sslEngine.setNeedClientAuth(encryptionOptions.require_client_auth); - sslEngine.setEnabledProtocols(SSLFactory.ACCEPTED_PROTOCOLS); return new SslHandler(sslEngine); } } diff --git a/src/java/org/apache/cassandra/transport/SimpleClient.java b/src/java/org/apache/cassandra/transport/SimpleClient.java index 40423c314c..0fb352ce2a 100644 --- a/src/java/org/apache/cassandra/transport/SimpleClient.java +++ b/src/java/org/apache/cassandra/transport/SimpleClient.java @@ -308,7 +308,6 @@ public class SimpleClient implements Closeable sslEngine.setUseClientMode(true); String[] suites = SSLFactory.filterCipherSuites(sslEngine.getSupportedCipherSuites(), encryptionOptions.cipher_suites); sslEngine.setEnabledCipherSuites(suites); - sslEngine.setEnabledProtocols(SSLFactory.ACCEPTED_PROTOCOLS); channel.pipeline().addFirst("ssl", new SslHandler(sslEngine)); } }