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.
$ 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.
$ 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.
$ 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.
$ 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.
$ 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.
$ 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
$ sudo cp /etc/elasticsearch/elasticsearch.yml /etc/elasticsearch/elasticsearch.yml.pre-http-tls
$ sudo vi /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.
$ 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.
$ 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
$ sudo systemctl is-active elasticsearch.service active
$ 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
$ 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.