2

I was able to create an elasticsearch 8.5.3 server as a docker image, but with security completely disabled, and in my springboot application I am using ElasticsearchRepository to perform insert,update, and delete and ElasticsearchOperations to perform selection and search, both of these classes/interfaces are included in the Spring Boot Starter Data Elasticsearch 3.0.1 dependency, and I am also using the following application.yaml property to tell both where the server is at

spring:
 elasticsearch:
  uris = 
   - http://localhost:9700
# username: elastic
# password: 123

Now, here is my issue: I set up another elasticsearch server with complete security features to test my springboot code in a real life scenario, but I can't figure out how to change the application.yaml to add the certificate portion of the security options, I've been stuck on this portion for a week now, I know it contains options like spring.elasticsearch.username and spring.elasticsearch.password, which aren't the issue, but where is the option for the certificate, and how can I make the certificate work on both ElasticsearchRepository and ElasticsearchOperation? I gathered from the majority of tutorials that I need to construct a @configuration class, however the point is that, most, if not all of the tutorials use deprecated methods(I am stuck in a 'This is deprecated' loop), like for example High Level Rest Client. I'm confused as to how to make ElasticsearchRepository and ElasticsearchOperation utilize the specified @Configuration, and what is the alternative to the High Level Rest Client (I think its RestClient based on what I read on the official documentations, but I cant figure out how to implement it with spring boot elasticsearch data starter)

SpaceSloth
  • 85
  • 7

2 Answers2

2

What you can do is to extend ElasticsearchConfiguration and override clientConfiguration method. There you can use usingSsl method and pass SSLContext :

@Configuration
class ElasitcSearchConfig extends ElasticsearchConfiguration {

    @Value("${spring.elasticsearch.client.certificate}")
    private String certificateBase64;

    @Override
    ClientConfiguration clientConfiguration() {
        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo("localhost:9200")
                .usingSsl(getSSLConetxt())
                .withBasicAuth("elastic", "changeme")
                .build();
        return clientConfiguration;
    }

    private SSLContext getSSLContext() {
        byte[] decode = Base64.decoder.decode(certificateBase64)

        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        Certificate ca;
        try (InputStream certificateInputStream = new ByteArrayInputStream(decode)) {
            ca = cf.generateCertificate(certificateInputStream);
        }

        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);

        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = 
   TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);
        return context;
    }

}

certificateBase64 will hold elasticsearch certificate encoded in base64 format and can be injected through properties file or environment variable (name of the property spring.elasticsearch.client.certificate). The code to create ssl context was originally taken from this answer.

Michał Krzywański
  • 15,659
  • 4
  • 36
  • 63
  • Yes, but the issue just as I described in the other answer is that I am unable to import the ElasticsearchConfiguration, its not found at all, this is what threw me off and forced me to find alternatives in the first place, this is what I get everytime I attempt to extend ElasticsearchConfiguration: https://ibb.co/wC8PxXT https://ibb.co/XxdSsLh And as you can see in this picture: https://ibb.co/dkjMLCJ The documentation says: import org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration; but as you can see from the picture there is no .elk package – SpaceSloth Jan 11 '23 at 13:12
  • So there is something wrong with your maven/gradle setup. I use `spring-boot-starter-data-elasticsearch` and everything works for me. I use similiar configuration with integration tests with elastisearch docker container and I can connect to it using certificate. – Michał Krzywański Jan 11 '23 at 13:16
  • I discovered the issue, by analyzing pom.xml, apprently, the spring boot version where it is not working is old, version 2.6.3, so, the elasticsearch starter 3.0.1 was downloading an older version of spring data elasticsearch(version 4.3.1) which still uses High level rest client and Transport clients. I tested this theory by creating a new springboot project version 3.0.1 . Had to exclude the old version that is being downloaded, and I add the spring data elasticsearch 5.0.0 menually. – SpaceSloth Jan 11 '23 at 14:09
  • I managed to make it work at last, but now I have another question, is there a more elegant way of creating an SSL certificate other than having to extract the http certificate, and then pasting it in the properties file. – SpaceSloth Jan 12 '23 at 08:50
  • Don't know how you set up your project, but for me a Spring Boot 3.0.1 setup pulls in Spring Data Elasticsearch 5.0.0 via it's starter. – P.J.Meisch Jan 14 '23 at 15:47
  • @P.J.Meisch Yes, I did an analysis on the maven dependencies, between two projects the 2nd one uses the most up to date spring boot, and I found out that, the starter was downloading an older version of Spring Data Elasticsearch, while I am under the impression that it was 5.0.0, it is now solved, thanks for the help. It's not functioning properly, and I can add data to it. – SpaceSloth Jan 15 '23 at 22:14
1

You can configure the client used by Spring Data Elasticsearch by providing a configuration bean, this is described in the documentation at https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.clients.restclient. Details for the client configuration are a little further down the docs: https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.clients.configuration.

This gives you the possibility to configure authentication and ssl setup (there is also a usingSsl method taking a ssl context which can be customized further).

I can't tell you which properties to set in the application configuration, this is a Spring Boot topic, Spring Data Elasticsearch does not read or use any configured values by itself.

P.J.Meisch
  • 18,013
  • 6
  • 50
  • 66