I have a server that I connect to through <Server-IP-Address>:22226
, my springboot app uses port 8099, while elasticsearch is installed on docker on the same server but with port 9200. Here is how I set up my config file related to elasticsearch.
- springboot version:
2.6.3
, - Elasticsearch Server version:
8.6.0
, - spring boot starter data elasticsearch version:
2.6.3
- spring data elasticsearch version:
4.3.1
(comes included with spring boot start data elasticsearch version)
application-development.yml
elasticsearch:
client:
certificate: MIIFWTCCA0GgAwIBAgIUGvdgD......jXvCY7poc= *(shortened for bravity)*
host: localhost:9200
username: elastic
password: GGAqcbLXobR8-eQjrRT2
The certificate I got from elasticsearch server by using this command to generate the http_ca.crt
:
docker cp esdemo01:/usr/share/elasticsearch/config/certs/http_ca.crt .
ElasticsearchConfig.class:
Here is the ElasticsearchConfig class, which is based on the answer to my other question: How to configure security in elasticsearch 8.5.3 using Starter Data Elasticsearch 3.0.1 in maven java springboot
@Configuration
@Log4j2
public class ElasticsearchConfig extends AbstractReactiveElasticsearchConfiguration
{
@NotBlank
@Value("${spring.elasticsearch.client.certificate}")
private String certificateBase64;
@Value("${spring.elasticsearch.client.host}")
private String host;
@Value("${spring.elasticsearch.client.username}")
private String username;
@Value("${spring.elasticsearch.client.password}")
private String password;
@Override
public @NonNull ReactiveElasticsearchClient reactiveElasticsearchClient()
{
final ClientConfiguration clientConfiguration;
try
{
clientConfiguration = ClientConfiguration.builder()
.connectedTo(host)
.usingSsl(getSSLContext(decodeCertificateBase64(certificateBase64)))
.withBasicAuth(username, password)
.build();
}
catch(ElasticsearchException e)
{
log.error("Error while creating elasticsearch client configuration ", e);
throw e;
}
return ReactiveRestClients.create(clientConfiguration);
}
private SSLContext getSSLContext(final byte[] decodedCertificate) throws ElasticsearchException
{
try
{
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate ca;
try(InputStream certificateInputStream = new ByteArrayInputStream(decodedCertificate))
{
ca = cf.generateCertificate(certificateInputStream);
}
String keyStoreType = "pkcs12";
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
SSLContextBuilder sslContextBuilder = SSLContexts.custom()
.loadTrustMaterial(keyStore, null);
final SSLContext sslContext = sslContextBuilder.build();
return sslContext;
}
catch(CertificateException | IOException | KeyStoreException | NoSuchAlgorithmException | KeyManagementException e)
{
throw new ElasticsearchException("Error while creating SSL context ", e);
}
}
private byte[] decodeCertificateBase64(final String certificateBase64)
{
return Base64.getDecoder().decode(certificateBase64);
}
}
Now, this code works if I call it like this in postman => <Server-IP-Address>:8099(springboot app port)
which the springboot app in turn calls elasticsearch through localhost:9200
, I also get results when I call <Server-IP-Address>:9200/_cat/indices
what I am trying to achieve is the ability to call elasticsearch externally from the springboot app, like, rather than hard coding springboot to listen to localhost:9200
I want it to listen to <Server-IP-Address>:9200
, but I cant figure this out, I managed to trace the issue to the config file itself, here is the error I am getting in the springboot app:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name
'loggingElasticsearchController' ...(ommitted for bravity).... nested exception is
org.springframework.data.elasticsearch.client.NoReachableHostException: Host '92.204.190.45:9200'
not reachable. Cluster state is offline.
While on the elasticsearch server, this is what I am getting in the logs:
{"@timestamp":"2023-01-20T14:21:11.622Z", "log.level": "WARN", "message":"http client
did not trust this server's
certificate, closing connection Netty4HttpChannel{localAddress=/172.18.0.2:9200,
remoteAddress=/193.227.174.146:57276}", "ecs.version": "1.2.0","service.name":"ES_ECS",
event.dataset":"elasticsearch.server","process.thread.name":"elasticsearch[24f3d2b8b774][transport_worker][T#8]",
"log.logger":"org.elasticsearch.xpack.security.transport.netty4.SecurityNetty4HttpServerTransport",
"elasticsearch.cluster.uuid":"g8TSlBMmS5aBx--9kmniwQ","elasticsearch.node.id":"_3ZfQJXzQse377jHO6JQsA",
"elasticsearch.node.name":"24f3d2b8b774","elasticsearch.cluster.name":"docker-cluster"}