Which certificate do I need for an external Java client linked to a self-hosted docker Elasticsearch 8.x, since the self-signed http_ca.crt does not function unless the Java client is installed locally on the same server?

I understand that when I set up a docker image of elasticsearch version 8.x, the security is automatically activated, and three certificates are produced in the config/certs/ directory, which are:

  • http_ca.crt: The CA certificate that is used to sign the certificates for the HTTP layer
  • http.p12: Keystore that contains the key and certificate for the HTTP layer
  • transport.p12: Keystore that contains the key and certificate for the transport layer

I also created a Java client that accepts a CA certificate and converts it to an SSLContext. I obtained the CA certificate by copying and opening the http ca.crt certificate using the following command:

docker cp esdemo01:/usr/share/elasticsearch/config/certs/http_ca.crt .

Now, when I try to connect the external Java client to the elasticsearch server using http ca.crt and using the url <server-IP-address>:9200, it refuses to connect. Using this command:

docker logs esdemo01

I can see that there is an issue in the elasticsearch logs which is :
http client did not trust this server's certificate, closing connection

But when I test a Java client which is found locally on the same server as the elasticsearch, and uses the same exact http_ca.crt certificate and connects to the elasticsearch via localhost:9200 its working fine, and is allowing me to add and call data.

So, which certificate do I need, what certificate do I need, what am I missing? I even followed the instructions for creating a elastic-stack-ca.p12, but I don't know how to proceed after this, I don't know if the elastic-stack-ca.p12 has worked or not.

The HTTP certificate's subjectAlternativeNames (localhost etc) do not match your docker container's external IP address. SSL by default verifies hostname and it fails because they do not match.

You can either create your own HTTP certificate with matching subjectAlternativeNames or configure your HTTP client to skip hostname verification.

3 Likes

Thanks for answering. I am trying to figure out the terms you just gave me, and how they all link to each other and my own problem:

  • HTTP certificate's subjectAlternativeNames: Is this field related to why in another test project I got the following error:
    Host name '<Server-IP-Address>' does not match the certificate subject provided by the peer (CN=b641a36b1bc9)
  • docker container's external IP address
  • hostname

After using this command

sudo docker container inspect esdemo01

Several properties caught my eye:

Is This the hostname you are talking about??

image

And is this the docker container's external IP address you talked about??
image

So, what you are telling me is that the http_ca.crt is created with a HTTP certificate's subjectAlternativeNames for the
"Hostname": "b641a36b1bc9" for the IP address "IPAddress": "172.20.0.2" and not the <Server-IP-Address>:9200 and that if I want to fix the issue I have to create one for the <Server-IP-Address>:9200 instead of 172.20.0.2

After a lot of digging, I finally managed to get it to work, I am leaving the way I did it here for anyone facing the same issue I had:

  1. use the following command to generate a new http keystore
./bin/elasticsearch-certutil http
./bin/elasticsearch-certutil http

Generate a CSR? [y/N] N
Use an existing CA? [y/N] N
Do you wish to change any of these options? [y/N] y

CA Name [CN=Elasticsearch HTTP CA] [server-ip-address]

CA Validity [5y] 60y

We recommend that you use one of 2048, 3072 or 4096 bits for your key.
Key Size [2048] [ENTER]

Do you wish to change any of these options? [y/N] [N]

CA password:  [<ENTER> for none] 123456
Repeat password to confirm: 123456

For how long should your certificate be valid? [5y] [ENTER]
Generate a certificate per node? [y/N]N

Enter all the hostnames that you need, one per line.
When you are done, press <ENTER> once more to move on to the next step.

[server-ip-address]:[port]

You entered the following hostnames.

 - [server-ip-address]

Is this correct [Y/n]Y

Key Name: [info]
Subject DN: CN=[info], DC=[info], DC=[info]
Key Size: 2048

Do you wish to change any of these options? [y/N]N

If you wish to use a blank password, simply press <enter> at the prompt below.
Provide a password for the "http.p12" file:  [<ENTER> for none] 123456
Repeat password to confirm: 123456

What filename should be used for the output zip file? [/usr/share/elasticsearch/elasticsearch-ssl-http.zip] [ENTER]

Zip file written to [docker-cotainer]:/usr/share/elasticsearch/elasticsearch-ssl-http.zip

exit the container after you finish using the command exit

  1. Move the zip file outside the docker container using the following command:
docker cp [container-name]:/usr/share/elasticsearch/**elasticsearch-ssl-http.zip .**

It is important to move the file outside the docker container so we can manipulate it with the linux commands that do not exist inside the docker container itself.

  1. Unzip the default file: elasticsearch-ssl-http.zip using the unzip linux library with this command:
unzip elasticsearch-ssl-http.zip

In case the unzip linux library does not exist, you need to install it, using the command

sudo apt install unzip
  1. After you unzip the files, we want its content, the http.p12 found in the path /elasticsearch/ , we want to replace the default http.p12 in the docker image in config/certs/http.p12 with the one in the unziped folder at elasticsearch/http.p12 . To replace folders in any docker container: just copy over it using the docker cp command:
docker cp [name-of-the-file-we-want-to-copy] [dokcer-container-name]:/usr/share/elasticsearch/config/certs/http.p12
  1. Re-eneter the docker container(like we did in step 1) and Change the default password of the replaced default http.p12 keystore, using the following command
./bin/elasticsearch-keystore add "xpack.security.http.ssl.keystore.secure_password" 

exit the container after you finish using the command exit

  1. Do not forget to restart the docker container so changes can take effect
docker restart [name-of-container]
  1. Generate the .pem file to use in external clients, using this command:
openssl pkcs12 -nodes -in http.p12 -out http.pem
  1. Open the generated .pem file using the following command:
cat http.pem

Copy the contained charachters to the java client, and make sure its in a straight line(minified), I usually do it by copying and pasting it in google chrome searchbar which condenses it.

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