How to configure Elasticsearch HTTP TLS

Configuring Elasticsearch HTTP TLS replaces or enables the certificate that API clients see on port 9200. A managed certificate lets curl, Kibana, Beats, Logstash, and application clients trust the endpoint through the CA and hostnames used in your environment.

Self-managed package installs already create HTTP TLS material under /etc/elasticsearch/certs during automatic security setup. The PEM configuration path is for replacing those generated HTTP files with a certificate, private key, and CA bundle supplied by an internal or public CA.

HTTP TLS is separate from transport TLS on port 9300. Keep transport certificates and cluster membership work outside this change, and make sure every DNS name or IP address used by clients appears in the HTTP certificate's subjectAltName extension before restarting the node.

Steps to configure Elasticsearch HTTP TLS:

  1. Confirm that the new HTTP CA certificate, server certificate, and private key are staged on the node.
    $ sudo ls -l /tmp/http-ca.crt /tmp/http.crt /tmp/http.key
    -rw-r--r-- 1 root root 1326 Jun 18 09:30 /tmp/http-ca.crt
    -rw-r--r-- 1 root root 1363 Jun 18 09:30 /tmp/http.crt
    -rw------- 1 root root 1704 Jun 18 09:30 /tmp/http.key

    Replace the filenames with the output from your certificate authority or PKI system. The server certificate must include the DNS names or IP addresses that clients use to reach Elasticsearch.

  2. Create the package certificate directory with group access for the elasticsearch service account.
    $ sudo install -d -o root -g elasticsearch -m 750 /etc/elasticsearch/certs

    Package installs often already contain /etc/elasticsearch/certs/http_ca.crt and /etc/elasticsearch/certs/http.p12 from automatic security setup. The managed PEM files use separate names so they can be staged before the configuration switch.

  3. Install the CA certificate that clients must trust.
    $ sudo install -o root -g elasticsearch -m 644 /tmp/http-ca.crt /etc/elasticsearch/certs/http-ca.crt

    Include intermediate certificates in this CA bundle when the issuing chain requires them.

  4. Install the HTTP server certificate.
    $ sudo install -o root -g elasticsearch -m 644 /tmp/http.crt /etc/elasticsearch/certs/http.crt

    A certificate without the required subjectAltName entries can start successfully while client HTTPS requests fail hostname verification.

  5. 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 the node, while an unreadable key prevents Elasticsearch from starting.

  6. Check the staged file ownership and permissions.
    $ sudo ls -l /etc/elasticsearch/certs/http-ca.crt /etc/elasticsearch/certs/http.crt /etc/elasticsearch/certs/http.key
    -rw-r--r-- 1 root elasticsearch 1326 Jun 18 09:31 /etc/elasticsearch/certs/http-ca.crt
    -rw-r--r-- 1 root elasticsearch 1363 Jun 18 09:31 /etc/elasticsearch/certs/http.crt
    -rw-r----- 1 root elasticsearch 1704 Jun 18 09:31 /etc/elasticsearch/certs/http.key
  7. Back up the package configuration file.
    $ sudo cp /etc/elasticsearch/elasticsearch.yml /etc/elasticsearch/elasticsearch.yml.pre-http-tls
  8. Open the Elasticsearch package configuration file.
    $ sudo vi /etc/elasticsearch/elasticsearch.yml
  9. Set the HTTP TLS PEM settings in /etc/elasticsearch/elasticsearch.yml.
    /etc/elasticsearch/elasticsearch.yml
    xpack.security.http.ssl.enabled: true
    xpack.security.http.ssl.certificate_authorities: ["/etc/elasticsearch/certs/http-ca.crt"]
    xpack.security.http.ssl.certificate: /etc/elasticsearch/certs/http.crt
    xpack.security.http.ssl.key: /etc/elasticsearch/certs/http.key

    Keep PEM settings separate from xpack.security.http.ssl.keystore.path and xpack.security.http.ssl.truststore.path. If your certificate workflow produced http.p12 instead of PEM files, use the PKCS#12 keystore settings instead. If xpack.security.enabled was explicitly set to false, set it back to true before enabling HTTP TLS.

  10. Store the private-key passphrase when the PEM key is encrypted.
    $ sudo /usr/share/elasticsearch/bin/elasticsearch-keystore add xpack.security.http.ssl.secure_key_passphrase
    Enter value for 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.

  11. Restart the Elasticsearch service so the HTTP TLS settings take effect.
    $ sudo systemctl restart elasticsearch.service

    Elasticsearch does not provide a separate syntax-test command for /etc/elasticsearch/elasticsearch.yml, so keep a second terminal available and inspect /var/log/elasticsearch/elasticsearch.log if the restart fails.
    Related: How to manage the Elasticsearch service with systemctl in Linux

  12. Confirm that the service returned to the running state.
    $ sudo systemctl is-active elasticsearch.service
    active
  13. Verify that the HTTPS endpoint trusts the configured CA and requires authentication.
    $ curl --silent --show-error --cacert /etc/elasticsearch/certs/http-ca.crt --output /dev/null --write-out "%{http_code}\n" https://localhost:9200/
    401

    A 401 response means the TLS handshake reached Elasticsearch and the HTTP security layer rejected an unauthenticated request. Certificate, issuer, or SAN errors must be fixed before client rollout.
    Tool: TLS Handshake Trace

  14. Run an authenticated cluster check through the same HTTPS path.
    $ curl --silent --show-error --cacert /etc/elasticsearch/certs/http-ca.crt --user elastic:$ELASTIC_PASSWORD https://localhost:9200/_cluster/health?pretty
    {
      "cluster_name" : "elasticsearch",
      "status" : "green",
      "timed_out" : false,
      "number_of_nodes" : 1,
      ##### snipped #####
      "active_shards_percent_as_number" : 100.0
    }

    Replace localhost with the client-facing DNS name when validating SAN coverage through a load balancer or reverse proxy.