Connecting to TLS/SSL secured elastic cluster through transport client

Hi,
I configured each node in the cluster to identify itself using its signed certificate and enable TLS on the transport layer.
Set up passwords for Elastic Stack.
I was able to successfully, connect to cluster through CURL.
Facing issue in connecting to this cluster through Transport Client.
Thank you

Please share your nodes configuration, your client configuration, the error message you get and relevant logs from elasticsearch. Your description has nothing to allow us to help you in any meaningful way

Steps to create certificate
./elasticsearch/bin/elasticsearch-certutil ca --pem
./elasticsearch/bin/elasticsearch-certutil cert --ca-cert ca/ca.crt --ca-key ca/ca.key

Configuration elasticsearch.yml
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.key: ca/ca.key
xpack.security.transport.ssl.certificate: ca/ca.crt
xpack.security.transport.ssl.certificate_authorities: [ "ca/ca.crt" ]

Java code

  Settings settings = Settings.builder().put("cluster.name", "cluster1")
            .put( "client.transport.ignore_cluster_name", true )
            .put("xpack.security.user", "username:password")
            .put("xpack.ssl.key", "instance/instance.key")
            .put("xpack.ssl.certificate", "instance/instance.crt")
            .put("xpack.ssl.certificate_authorities", "ca/ca.crt")
            .put("xpack.security.transport.ssl.enabled", "true")
            .build();
    TransportClient transportClient = new PreBuiltXPackTransportClient(settings)
            .addTransportAddresses(new TransportAddress(InetAddress.getByName("localhost"), 9300));

ERROR
Java End NoNodeAvailableException[None of the configured nodes are available:
Cluster client did not trust this server's certificate, closing connection Netty4TcpChannel

This is incorrect. The CA key and certificates should not be used as key/certificate for the nodes, they should only be used to sign the certificates that will be used for the nodes. You need to use the instance.key and instance.crt for this.

Then you need to create an extra pair of certificates, signed by the same CA with

./elasticsearch/bin/elasticsearch-certutil cert --ca-cert ca/ca.crt --ca-key ca/ca.key --pem --name client --out client.zip

This will create a zip archive that contains a client.key and a client.crt files. Copy these to the client and use that to set

.put("xpack.ssl.key", "client.key")
.put("xpack.ssl.certificate", "client.crt")
final CredentialsProvider credentialsProvider =  new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials("username", "password"));
        RestClientBuilder builder = RestClient.builder(
                new HttpHost(HOST, PORT_ONE, SCHEME))
                .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                    @Override
                    public HttpAsyncClientBuilder customizeHttpClient(
                            HttpAsyncClientBuilder httpClientBuilder) {
                        return httpClientBuilder
                                .setDefaultCredentialsProvider(credentialsProvider);
                    }
                });
        RestHighLevelClient client = new RestHighLevelClient(builder);

ERROR on elastic end: Caused by: javax.net.ssl.SSLException: Received fatal alert: unknown_caPreformatted text

Hi @Meet,

Please format the code snippets as it becomes difficult to go through the code. You can use the "Preformatted text" option
preformat

From the error message, the client is lacking support for TLS and unable to handle TLS connections.

Caused by: javax.net.ssl.SSLException: Received fatal alert: unknown_ca

You need to make your client be able to consume HTTPs urls, to do this you will need to customize the http client using the builder and set an appropriate TLS/SSL transport level security strategy.

an example:

try {
                KeyStore keyStore = KeyStore.getInstance(<keyStoreType>);
                try (InputStream is = Files.newInputStream(path)) {
                    keyStore.load(is, keystorePass.toCharArray());
                }
                SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keyStore, null).build();
                SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sslcontext);
                builder.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setSSLStrategy(sessionStrategy));
} catch (KeyStoreException |NoSuchAlgorithmException |KeyManagementException |CertificateException e) {
                throw new RuntimeException("Error setting up ssl", e);
}

Hope this helps.

Thanks and Regards,
Yogesh Gaikwad

Hi @ikakavas,

I followed the method you mentioned in this reply and I got a error below:

client did not trust this server's certificate, closing connection Netty4TcpChannel{localAddress=0.0.0.0/0.0.0.0:9300, remoteAddress=/172.16.3.137:53814}

The configuration in elasticsearch.yml -
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.key: instance/instance.key
xpack.security.transport.ssl.certificate: instance/instance.crt
xpack.security.transport.ssl.certificate_authorities: [ "ca/ca.crt" ]

and java code -
Settings.Builder builder = Settings.builder();
builder.put("cluster.name", es_server_clustername);
builder.put("xpack.security.user", "username:password");
builder.put("xpack.ssl.key", "/mypath/client.key");
builder.put("xpack.ssl.certificate", "/mypath/client.crt");
builder.put("xpack.ssl.certificate_authorities", "/mypath/ca.crt");
builder.put("xpack.security.transport.ssl.enabled", "true");
Settings settings = builder.build();
client = new PreBuiltXPackTransportClient(settings);

The Java program I executed was on another computer and I copied the certificate、key and ca from the ES node.

I hope you can reply me, thank you!

Hi @yeziblo,

Please resist posting into another thread as that is unrelated to the OPs questions.
I see you have already opened a thread for your problem, it would be good to discuss over there than posting on other threads.

Thanks and Regards,
Yogesh Gaikwad

Hi @Yogesh_Gaikwad
I didn't get a reply to my question. I saw that the question was similar to my situation, so I repeated my question here.

I'm sorry.

Hi @yeziblo,

Adding the following line
.put("xpack.security.transport.ssl.verification_mode","certificate");
solved my issue.
Another thing to be noticed, This will help you communicate through Transport client to your secured cluster. If u want to communicate through REST on HTTPS, Java doesn't trust self signed certificate generated by elastic search. In that case, you have to create another certificate signed by the same crt authority for the Java and add it Java key store.

Thanks,
Meet

1 Like

Hi @Meet
It really worked,Thank you so much!

Best regards!
yeziblo

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.