Last updated: 2026-06-25
Elasticsearch TLS/SSL Configuration Guide
This guide provides recommended TLS/SSL settings for Elasticsearch. Elasticsearch has two network layers that need to be secured: the transport layer (node-to-node cluster communication) and the HTTP layer (client-to-node REST API communication).
Prerequisites
- Elasticsearch 9.x recommended (8.x is in maintenance); security is enabled by default in 8.0+
- Java 17 or later (Java 21 required for Elasticsearch 9.x)
- SSL certificates (PKCS12 or PEM format)
Elasticsearch 8.0+ enables security and TLS automatically on first startup, generating self-signed certificates. This guide covers how to configure TLS with your own certificates and stronger settings.
Certificate Generation
Elasticsearch provides the elasticsearch-certutil tool for generating certificates.
Generate a CA
bin/elasticsearch-certutil ca --out /etc/elasticsearch/ssl/elastic-stack-ca.p12 --pass ""
Generate Node Certificates
bin/elasticsearch-certutil cert --ca /etc/elasticsearch/ssl/elastic-stack-ca.p12 --ca-pass "" --out /etc/elasticsearch/ssl/elastic-certificates.p12 --pass ""
Generate HTTP Certificates
For client-facing HTTPS, generate a separate certificate:
bin/elasticsearch-certutil http
Follow the interactive prompts to generate certificates for each node. This creates a zip file containing the certificate and CA files.
Using PEM Files
If you prefer PEM files (e.g., from Let's Encrypt or your own CA):
bin/elasticsearch-certutil cert --ca /etc/elasticsearch/ssl/elastic-stack-ca.p12 --ca-pass "" --pem --out /etc/elasticsearch/ssl/certs.zip
Set appropriate permissions:
chmod 660 /etc/elasticsearch/ssl/*.p12
chown root:elasticsearch /etc/elasticsearch/ssl/*.p12
Transport Layer TLS
The transport layer handles all internal cluster communication between nodes. TLS is mandatory for the transport layer in production.
PKCS12 Configuration
xpack.security.transport.ssl:
enabled: true
verification_mode: full
keystore.path: /etc/elasticsearch/ssl/elastic-certificates.p12
truststore.path: /etc/elasticsearch/ssl/elastic-certificates.p12
PEM Configuration
xpack.security.transport.ssl:
enabled: true
verification_mode: full
certificate: /etc/elasticsearch/ssl/node.crt
key: /etc/elasticsearch/ssl/node.key
certificate_authorities: /etc/elasticsearch/ssl/ca.crt
Protocol and Cipher Settings
xpack.security.transport.ssl:
supported_protocols: [TLSv1.2, TLSv1.3]
cipher_suites:
- TLS_AES_256_GCM_SHA384
- TLS_AES_128_GCM_SHA256
- TLS_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
Elasticsearch uses Java (JSSE) cipher suite names. TLS 1.3 suites (
TLS_AES_*) require Java 11 or later.
HTTP Layer TLS
The HTTP layer handles REST API requests from clients, Kibana, and other applications.
PKCS12 Configuration
xpack.security.http.ssl:
enabled: true
keystore.path: /etc/elasticsearch/ssl/http.p12
PEM Configuration
xpack.security.http.ssl:
enabled: true
certificate: /etc/elasticsearch/ssl/http.crt
key: /etc/elasticsearch/ssl/http.key
certificate_authorities: /etc/elasticsearch/ssl/ca.crt
Protocol and Cipher Settings
xpack.security.http.ssl:
supported_protocols: [TLSv1.2, TLSv1.3]
cipher_suites:
- TLS_AES_256_GCM_SHA384
- TLS_AES_128_GCM_SHA256
- TLS_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
Complete Configuration
In elasticsearch.yml:
# Enable security
xpack.security.enabled: true
# Transport layer TLS (node-to-node)
xpack.security.transport.ssl:
enabled: true
verification_mode: full
keystore.path: /etc/elasticsearch/ssl/elastic-certificates.p12
truststore.path: /etc/elasticsearch/ssl/elastic-certificates.p12
supported_protocols: [TLSv1.2, TLSv1.3]
cipher_suites:
- TLS_AES_256_GCM_SHA384
- TLS_AES_128_GCM_SHA256
- TLS_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
# HTTP layer TLS (client-to-node)
xpack.security.http.ssl:
enabled: true
keystore.path: /etc/elasticsearch/ssl/http.p12
supported_protocols: [TLSv1.2, TLSv1.3]
cipher_suites:
- TLS_AES_256_GCM_SHA384
- TLS_AES_128_GCM_SHA256
- TLS_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
If using PKCS12 keystores with a password, add the passwords to the Elasticsearch keystore:
bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password
bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password
See RFC 8446 ยง4.3.2 for the TLS Certificate Request specification, and Wikipedia: Mutual authentication for a general overview.
Kibana Configuration
Configure Kibana to connect to Elasticsearch over HTTPS. In kibana.yml:
elasticsearch.hosts: ["https://elasticsearch.example.com:9200"]
elasticsearch.ssl.certificateAuthorities: ["/etc/kibana/ssl/ca.crt"]
elasticsearch.ssl.verificationMode: full
# Kibana's own HTTPS
server.ssl.enabled: true
server.ssl.certificate: /etc/kibana/ssl/kibana.crt
server.ssl.key: /etc/kibana/ssl/kibana.key
server.ssl.supportedProtocols: ["TLSv1.2", "TLSv1.3"]
Security Notes
Elasticsearch uses Java's JSSE (Java Secure Socket Extension) for TLS. Vulnerability fixes are tied to the JDK version in use:
- POODLE (CVE-2014-3566, 2014): SSL 3.0 disabled by default since Java 8u31 (January 2015). The recommended configuration explicitly excludes it.
- BEAST (CVE-2011-3389, 2011): TLS 1.0 disabled by default since Java 8u292 / Java 11.0.11 (April 2021); excluded from the recommended configuration.
- FREAK (CVE-2015-0204, 2015): EXPORT ciphers disabled by default since Java 8u40 (March 2015).
- Sweet32 (CVE-2016-2183, 2016): 3DES disabled by default since Java 8u151 (October 2017); excluded from the recommended cipher list.
- ROBOT (2017): Static RSA key exchange is excluded from the recommended configuration.
- Downgrade attacks: TLS_FALLBACK_SCSV supported since Java 8u31.
- LOGJAM (CVE-2015-4000, 2015): DHE with weak keys excluded; only ECDHE is recommended.
The following are not addressable through TLS configuration alone:
- Heartbleed (CVE-2014-0160, 2014): Not applicable. Java's JSSE is an independent TLS implementation not based on OpenSSL and was never affected by Heartbleed.
- BREACH (CVE-2013-3587, 2013): Elasticsearch serves an HTTP REST API. If HTTP response compression is enabled (
http.compression: true), apply BREACH countermeasures at the application layer; TLS configuration cannot prevent it. - DROWN (CVE-2016-0800, 2016): Not applicable. Java's JSSE does not support SSLv2.
Verification
Restart Elasticsearch:
systemctl restart elasticsearch
Verify HTTPS is working:
curl --cacert /etc/elasticsearch/ssl/ca.crt -u elastic https://localhost:9200
Check the cluster health over HTTPS:
curl --cacert /etc/elasticsearch/ssl/ca.crt -u elastic https://localhost:9200/_cluster/health?pretty
Check the SSL certificate details:
openssl s_client -connect localhost:9200
Verify the node TLS settings:
curl --cacert /etc/elasticsearch/ssl/ca.crt -u elastic https://localhost:9200/_nodes/settings?filter_path=**.ssl