[ https://issues.apache.org/jira/browse/CASSANDRA-20484?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17951338#comment-17951338 ]
Maulin Vasavada edited comment on CASSANDRA-20484 at 5/14/25 6:54 AM: ---------------------------------------------------------------------- Okay, so few more questions, # When you use `-f` option to specify cassandra.yaml path, are you inheriting/copying the same file that you use for the Cassandra service/server? (i.e. either you are running sstablesloader from one of the server nodes (hence can access the same file) OR copied the file over to a VM where you are running sstableloader from) # If you are NOT using the same file (either by sharing the location or copying it over) as the server's cassandra.yaml, then you must be creating a new/separate cassandra.yaml file just to use it for the sstableloader, correct? ## If this is the case, in my opinion what you specify in the client_encryption_options AND server_encryption_options must be the same config because to the Cassandra target nodes you connect with (for native transport or storage port) your VM is a 'client' and whatever server configured for SSL you need to comply with. This means if the server configured to require_client_auth you will need to have keystore for providing your client certs AND truststore to trust server cert. If the server configured required_client_auth as false you ONLY need a truststore to be able to trust server cert. Now, coming to you original question/ask - That if your config file used for the ssltableloader tool (not the config file inherited/copying from the server's config) specified the `require_client_auth` false you should not require truststore - does not logically make sense to me. This is because as a client you don't control if you require the client to auth with server or not and as a client if you do have to use SSL (since server configured client_encryption_options as enabled on its side) you MUST need a truststore always to be able to validate server's cert. Btw, I do agree with your code pointers that the code is using two distinct paths - one to use client_encryption_options from the config file (the init() method in the NativeSSTableLoaderClient uses those ssl options to fetch metadata etc) AND second to use server_encryption_options from the config file for the storage port connection (via BulkLoadConnectionFactory(serverEncOptions, storagePort) ). Also, when I think about the sstableloader options from the documentation standpoint ([link|#usage]]) - From the command line it ONLY has "Client SSL" options overrides and not server encryption options overrides - why? I think its because no matter how you see sstableloader communicating to the server (native or streaming way) - it is still a client to a SSL server. Overall, either I fail to completely understand the current sstableloader documentation/code OR the documentation could be better in clearly calling out (how Google Gemini AI search results tell the story- see the screenshot below) - specially focus on the #2 it says similar to what I suggest here. It is interesting to notice here that while the below search result have corresponding link for each point, actually those link don't tell the story as clearly as the AI result did :) ) !image-2025-05-13-23-42-19-536.png! was (Author: maulin.vasavada): Okay, so few more questions, # When you use `-f` option to specify cassandra.yaml path, are you inheriting/copying the same file that you use for the Cassandra service/server? (i.e. either you are running sstablesloader from one of the server nodes (hence can access the same file) OR copied the file over to a VM where you are running sstableloader from) # If you are NOT using the same file (either by sharing the location or copying it over) as the server's cassandra.yaml, then you must be creating a new/separate cassandra.yaml file just to use it for the sstableloader, correct? ## If this is the case, in my opinion what you specify in the client_encryption_options AND server_encryption_options must be the same config because to the Cassandra target nodes you connect with (for native transport or storage port) your VM is a 'client' and whatever server configured for SSL you need to comply with. This means if the server configured to require_client_auth you will need to have keystore for providing your client certs AND truststore to trust server cert. If the server configured required_client_auth as false you ONLY need a truststore to be able to trust server cert. Now, coming to you original question/ask - That if your config file used for the ssltableloader tool (not the config file inherited/copying from the server's config) specified the `require_client_auth` false you should not require truststore - does not logically make sense to me. This is because as a client you don't control if you require the client to auth with server or not and as a client if you do have to use SSL (since server configured client_encryption_options as enabled on its side) you MUST need a truststore always to be able to validate server's cert. Btw, I do agree with your code pointers that the code is using two distinct paths - one to use client_encryption_options from the config file (the init() method in the NativeSSTableLoaderClient uses those ssl options to fetch metadata etc) AND second to use server_encryption_options from the config file for the storage port connection (via BulkLoadConnectionFactory(serverEncOptions, storagePort) ). Also, when I think about the sstableloader options from the documentation standpoint ([link|#usage]]) - From the command line it ONLY has "Client SSL" options overrides and not server encryption options overrides - why? I think its because no matter how you see sstableloader communicating to the server (native or streaming way) - it is still a client to a SSL server. Overall, either I fail to completely understand the current sstableloader documentation/code OR the documentation could be better in clearly calling out (how Google Gemini AI search results tell the story- see the screenshot below) - specially focus on the #2 it says similar to what I suggest here. !image-2025-05-13-23-42-19-536.png! > Bulkloader requires truststore path even when required_client_auth is false > in cassandra.yaml > --------------------------------------------------------------------------------------------- > > Key: CASSANDRA-20484 > URL: https://issues.apache.org/jira/browse/CASSANDRA-20484 > Project: Apache Cassandra > Issue Type: Bug > Components: Tool/bulk load > Reporter: Niket Vilas Bagwe > Assignee: Maulin Vasavada > Priority: Normal > Attachments: image-2025-05-13-23-42-19-536.png > > > If client_encryption_options are enabled in cassandra.yaml with > require_client_auth false *and* Sstableloader command is used with -f option > (for cassandra.yaml path), sstableloader fails with "NoSuchFileException: > conf/.truststore". > Sample sstableloader command is as follows. > |sstableloader /opt/cassandra/data/keyspace/table -d 127.0.0.1 -p 9042 -ssp > 7001 -sp 7000 -f */opt/nosql/clusters/cassandra-6382/conf/cassandra.yaml* -u > "caas" -pw *******| > Exception encountered is as follows: > > {code:java} > Exception in thread "main" java.lang.RuntimeException: Could not create SSL > Context. > at > org.apache.cassandra.tools.BulkLoader.buildSSLOptions(BulkLoader.java:271) > at org.apache.cassandra.tools.BulkLoader.load(BulkLoader.java:72) > at org.apache.cassandra.tools.BulkLoader.main(BulkLoader.java:58) > Caused by: javax.net.ssl.SSLException: failed to build trust manager store > for secure connections > at > org.apache.cassandra.security.FileBasedSslContextFactory.buildTrustManagerFactory(FileBasedSslContextFactory.java:196) > at > org.apache.cassandra.security.AbstractSslContextFactory.createJSSESslContext(AbstractSslContextFactory.java:155) > at > org.apache.cassandra.security.SSLFactory.createSSLContext(SSLFactory.java:127) > at > org.apache.cassandra.tools.BulkLoader.buildSSLOptions(BulkLoader.java:267) > ... 2 more > Caused by: java.nio.file.NoSuchFileException: conf/.truststore > at > java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92) > at > java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111) > at > java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116) > at > java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:219) > at java.base/java.nio.file.Files.newByteChannel(Files.java:371) > at java.base/java.nio.file.Files.newByteChannel(Files.java:422) > at > java.base/java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:420) > at java.base/java.nio.file.Files.newInputStream(Files.java:156) > at > org.apache.cassandra.security.FileBasedSslContextFactory.buildTrustManagerFactory(FileBasedSslContextFactory.java:183) > ... 5 more {code} > The reason for this is that sslcontext for native connection in BulkLoader is > always created with EncryptionOptions.ClientAuth set to true at > [line|https://github.com/apache/cassandra/blob/f278f6774fc76465c182041e081982105c3e7dbb/src/java/org/apache/cassandra/tools/BulkLoader.java#L267] > irrespective of the value of require_client_auth present in cassandra.yaml. > Because of this BulkLoader always expects to have a truststore file inorder > to verify the client certificates. Copying below the errorneous code block > for reference. > {code:java} > private static SSLOptions buildSSLOptions(EncryptionOptions > clientEncryptionOptions) > { if (!clientEncryptionOptions.getEnabled()) > { > return null; > } SSLContext sslContext; > try > { > ################ problematic line > sslContext = SSLFactory.createSSLContext(clientEncryptionOptions, > true); > ################ > } > catch (IOException e) > { > throw new RuntimeException("Could not create SSL Context.", e); > } {code} > -- This message was sent by Atlassian Jira (v8.20.10#820010) --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org