[
https://issues.apache.org/jira/browse/CASSANDRA-13325?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17205879#comment-17205879
]
Jon Meredith commented on CASSANDRA-13325:
------------------------------------------
I've been investigating restricting the TLS protocols to prevent use of TLSv1 &
TLSv1.1 for secure internode messaging and streaming connections and think the
current implementation needs improvement before the final 4.0 release, so I'd
like to pick this up again.
The Apache Cassandra documentation page on security
https://cassandra.apache.org/doc/latest/operating/security.html mentions
"... the JVM defaults for supported protocols and cipher suites are used when
encryption is enabled. These can be overidden using the settings in
cassandra.yaml, but this is not recommended unless there are policies in place
which dictate certain settings or a need to disable vulnerable ciphers or
protocols in cases where the JVM cannot be updated."
The implication to me there is that the preferred mechanism is to configure the
JSSE subsystem. Trawling through documentation, the operator can disable older
TLS protocol at the JVM level by creating new security properties file
{code}
$ cat conf/cassandra-security.properties
jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, DH keySize < 1024, \
EC keySize < 224, 3DES_EDE_CBC, anon, NULL, TLSv1, TLSv1.1
{code}
And appending to the current security properties using
{code}
-Djava.security.properties=conf/cassandra-security.properties
{code}
This works fine pre-4.0, however the introduction of Netty tcnative which uses
OpenSSL under the hood, does not use the {{java.security.properties}} to
restrict anything. Neither does it implement the calls for supporting the
OpenSSL configuration file. It only seems possible to restrict the protocol &
ciphers through the Netty SSLContext API. It is possible to disable OpenSSL by
setting the Java system property {{cassandra.disable_tcactive_openssl=true}},
but it seems undesirable to lose the performance benefit there.
Looking in {{cassandra.yaml}}, under 'More advanced defaults' there is a
{{protocol}} setting, which an operator might expect restricts which TLS
protocols are accepted.
{code}
# More advanced defaults:
# protocol: TLS
{code}
However, setting that to {{TLSv1.2}} had no effect on the protocols the server
accepted. Running {{openssl}} will connect without issue and negotiate a
TLSv1.0 session.
{code}
openssl s_client -tlsv1 -connect 127.0.0.1:7000
{code}
I found two previous tickets that addressed TLS protocols, first explicitly
hard-coding the accepted TLS protocols to disable SSLv3 (due to POODLE) in
CASSANDRA-8265 / b93f48a5db321bf7c9fb55a800ed6ab2d6f6b102, and then rely back
on Java8 defaults in CASSANDRA-10508 / e4a0a4bf65a87c3aabae4ee0cc35009879e2d455
once the defaults were fixed.
CASSANDRA-10508 mentions the ‘protocol' field as a mechanism for specifying the
protocol, however according to Java docs, that only verifies the protocol is to
the SSL engine supported, and does not restrict negotiation to using it, as the
openssl s_client test demonstrates.
>From a quick search of the internet, a couple of blog posts recommend setting
>the cipher suite to only {{TLSv1.2}} valid ciphers and I can confirm that does
>work, leading to this being logged (at ERROR).
{code}
ERROR [Messaging-EventLoop-3-2] 2020-09-19T16:17:48,023 : - Failed to properly
handshake with peer /127.0.0.1:33826. Closing the channel.
io.netty.handler.codec.DecoderException:
javax.net.ssl.SSLHandshakeException: Client requested protocol TLSv1.1 is not
enabled or supported in server context
Caused by: javax.net.ssl.SSLHandshakeException: Client requested protocol
TLSv1.1 is not enabled or supported in server context
{code}
While it does work to restrict the protocol, if we start logging the accepted
protocols the log will show that the server will negotiate TLS1/TLS1.1 which
may get flagged by anybody validating the operators configuration/logs.
The current state of the code and documentation is unsatisfactory to me. We
should at least improve the documentation to give clear guidance to operators
on how they can secure their systems under 4.0/tcnative, however I think we
should go further and make the encryption_option.protocol field behave as
intended.
Here's my proposal:
1) Interpret the current protocol string as a comma separated list of protocols
that are accepted. Replace the default
{{EncryptionOptions.protocol}} of {{"TLS"}} with null.
2) If protocol is non-null, call {{SslContextBuilder.protocols()}} with the
configured protocols in
{{org.apache.cassandra.security.SSLFactory#createNettySslContext}}
3) Special case the protocol configuration {{"TLS"}} to mean {{["TLSv1",
"TLSv1.1", "TLSv1.2”]}} for users that have uncommented the default value.
Passing {{“TLS”}} is invalid in the {{protocols()}} call.
4) Hard-code {{org.apache.cassandra.security.SSLFactory#createSSLContext}} to
pass {{"TLS"}} and then restrict to the protocols specified if non-null. It
still looks used by the JavaDriverClient and BulkLoader.
5) Make sure the protocol and cipher are propagated to the Clients table.
With those changes, operators should be able to restrict both the protocols and
ciphers as well as audit the configuration and past behavior of their system.
> Bring back the accepted encryption protocols list as configurable option
> ------------------------------------------------------------------------
>
> Key: CASSANDRA-13325
> URL: https://issues.apache.org/jira/browse/CASSANDRA-13325
> Project: Cassandra
> Issue Type: Improvement
> Components: Local/Config
> Reporter: Nachiket Patil
> Assignee: Nachiket Patil
> Priority: Low
> Fix For: 4.x
>
> Attachments: trunk.diff
>
>
> With CASSANDRA-10508, the hard coded list of accepted encryption protocols
> was eliminated. For some use cases, it is necessary to restrict the
> encryption protocols used for communication between client and server.
> Default JVM way of negotiations allows the best encryption protocol that
> client can use.
> e.g. I have set Cassandra to use encryption. Ideally client and server
> negotiate to use best protocol (TLSv1.2). But a malicious client might force
> TLSv1.0 which is susceptible to POODLE attacks.
> At the moment only way to restrict the encryption protocol is using the
> {{jdk.tls.client.protocols}} systems property. If I dont have enough access
> to modify this property, I dont have any way of restricting the encryption
> protocols.
> I am proposing bring back the accepted_protocols property but make it
> configurable. If not specified, let the JVM take care of the TLS negotiations.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]