How to configure Elasticsearch for TLS

TLS on the Elasticsearch HTTP endpoint protects passwords, API keys, and indexed data from passive interception and active tampering while traffic crosses local networks, proxies, or shared infrastructure.

On the HTTP layer, Elasticsearch presents a server certificate and private key to API clients, and clients validate that certificate chain against a trusted CA. The certificate's subjectAltName entries must cover every DNS name or IP address that clients use, or hostname verification will reject the connection even when the CA is trusted.

Current self-managed package installs usually start with security and HTTPS auto-configured on first startup. This workflow is for replacing that generated HTTP certificate set with managed PEM files, or for finishing manual HTTP TLS when auto-configuration was skipped. If security was explicitly disabled, re-enable it first, and on multi-node clusters keep transport TLS configured separately because this page changes only the HTTP interface.

Steps to configure Elasticsearch HTTP TLS:

  1. Create the certificate directory with access that allows the elasticsearch service account to traverse it.
    $ sudo install -d -o root -g elasticsearch -m 750 /etc/elasticsearch/certs

    Current package installs often already place auto-generated files such as /etc/elasticsearch/certs/http_ca.crt and /etc/elasticsearch/certs/http.p12 in this directory. These examples use separate PEM filenames so a managed certificate set can be staged without overwriting the generated files first.

  2. Install the CA certificate that signs the HTTP server certificate.
    $ sudo install -o root -g elasticsearch -m 644 /tmp/http-ca.crt /etc/elasticsearch/certs/http-ca.crt

    When the issuing chain includes intermediate certificates, keep them in the CA bundle or provide the full chain that clients must trust.

  3. Install the server certificate that Elasticsearch should present on port 9200.
    $ sudo install -o root -g elasticsearch -m 644 /tmp/http.crt /etc/elasticsearch/certs/http.crt

    The certificate must include every DNS name and IP address that clients use in the subjectAltName extension, or HTTPS requests will fail hostname verification.

  4. Install the matching private key with restricted permissions.
    $ sudo install -o root -g elasticsearch -m 640 /tmp/http.key /etc/elasticsearch/certs/http.key

    Overly broad private-key access weakens cluster security, while unreadable keys prevent Elasticsearch from starting.

  5. Confirm the elasticsearch service account can read the private key before changing the node settings.
    $ sudo -u elasticsearch test -r /etc/elasticsearch/certs/http.key
    $ echo $?
    0

    A 0 exit status confirms the running service account can read the key through the configured ownership and directory permissions.

  6. Configure the HTTP TLS settings in /etc/elasticsearch/elasticsearch.yml.
    xpack.security.http.ssl.enabled: true
    xpack.security.http.ssl.certificate: /etc/elasticsearch/certs/http.crt
    xpack.security.http.ssl.key: /etc/elasticsearch/certs/http.key
    xpack.security.http.ssl.certificate_authorities: ["/etc/elasticsearch/certs/http-ca.crt"]

    Keep the PEM settings together and do not mix them with xpack.security.http.ssl.keystore.path or xpack.security.http.ssl.truststore.path. If the certificate workflow produced http.p12 instead of PEM files, switch to the keystore-based settings instead. Current releases already default xpack.security.enabled to true, so this page only adds the HTTP certificate paths.

  7. Store the private-key passphrase in the Elasticsearch keystore when the PEM key is encrypted.
    $ sudo /usr/share/elasticsearch/bin/elasticsearch-keystore add xpack.security.http.ssl.secure_key_passphrase

    Skip this step when /etc/elasticsearch/certs/http.key is not encrypted. The older xpack.security.http.ssl.key_passphrase setting is deprecated.

  8. Restart the Elasticsearch service so the new TLS settings take effect.
    $ sudo systemctl restart elasticsearch
  9. Confirm the service returned to the running state after the restart.
    $ systemctl is-active elasticsearch.service
    active

    If the unit does not return active, inspect /var/log/elasticsearch/elasticsearch.log and any key-passphrase keystore entry before retrying.

  10. Verify that the HTTPS endpoint trusts the configured CA and now requires authentication.
    $ curl --silent --show-error --output /dev/null --write-out "%{http_code}\n" https://localhost:9200/
    401

    A validated 401 response confirms the TLS handshake succeeded and the HTTP layer is protected. For an authenticated follow-up check, add credentials with --user and keep the same trusted CA file.