Can't connect to Elasticsearch with Node.Js on Kubernetes (self signed certificate in certificate chain) Can't connect to Elasticsearch with Node.Js on Kubernetes (self signed certificate in certificate chain) elasticsearch elasticsearch

Can't connect to Elasticsearch with Node.Js on Kubernetes (self signed certificate in certificate chain)


The solution is to configure SSL and the Elastic user when creating the Client

const client = new elasticsearch.Client({  node: process.env.elasticsearch_node,  auth: {    username: "elastic",    password: process.env.elasticsearch_password || "changeme",  },  ssl: {    ca: process.env.elasticsearch_certificate,    rejectUnauthorized: false,  },});

The password and the certificate are provided by Elastic. They are stored inside Kubernetes secrets.So I've just passed the password and the certificate into my NodeJs service via environment variables like this:

apiVersion: apps/v1kind: Deploymentmetadata:  name: search-deploymentspec:  selector:    matchLabels:      app: search  replicas: 1  template:    metadata:      labels:        app: search    spec:      containers:        - name: search          image: search:placeholder_name          imagePullPolicy: Always          env:            - name: elasticsearch_node              value: https://elasticsearch-es-http.default.svc.cluster.local:9200            - name: elasticsearch_certificate              valueFrom:                secretKeyRef:                  name: elasticsearch-es-http-ca-internal                  key: tls.crt            - name: elasticsearch_password              valueFrom:                secretKeyRef:                  name: elasticsearch-es-elastic-user                  key: elastic


I'd like to build on top of @Florian Ludewig's answer on 2 points, since I struggled myself to have it work on my side.

1. Don't turn off rejectUnauthorized

const client = new elasticsearch.Client({  node: 'node httpS url here',  ssl: {    ca: process.env.elasticsearch_certificate,    rejectUnauthorized: true, // <-- this is important  },});

If you set rejectUnauthorized to false, the underlying nodejs https agent will bypass the certificate check. Of course if you are confident in the security of your cluster, you could disable it, but it renders the idea of providing the CA cert useless in the first place.

2. Make sure you provide a PEM CA cert - not the base64 encoded version

Perhaps you are providing the CA cert from your own config file without using Kubernetes' secret injection - possibly because the ES client application is in a different namespace and thus cannot access the CA secret.

In this case you may find it useful to store the CA cert as a base64 string, in a config file, but you should not forget to provide a decoded string to your client:

const config = loadConfigFromFile('config.yml');const caCertificate = Buffer.from(config.base64CaCertificate, 'base64').toString();const client = new elasticsearch.Client({  node: 'node httpS url here',  ssl: {    ca: caCertificate,    rejectUnauthorized: true  },});


In order to resolve your issue you will need to trust the CA, you should be able to do so using the following. Also found the following Question here.

If you wish to import the CA as a env variable as discussed you might be able to do something like:

- name: NODE_EXTRA_CA_CERTS    valueFrom:      secretKeyRef:        name: elasticsearch-ca        key: tls.crt

Note: I've not tried the above, an alternative would be to mound the secret as a volume and import it that way :)

Please note that If you wish to disable TLS on your Elasticsearch deployment you can do so as follows:

spec:  http:    tls:      selfSignedCertificate:        disabled: true

Please note that disabling TLS isn't recommended.