You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by "Jon Meredith (Jira)" <ji...@apache.org> on 2020/10/01 23:29:00 UTC

[jira] [Commented] (CASSANDRA-13325) Bring back the accepted encryption protocols list as configurable option

    [ 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: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org