Skip to content

Hardening Elasticsearch

Elasticsearch spent years as the most breached database on the internet, for one reason: it shipped open. No authentication, bound to a routable address in enough setups to matter, and holding exactly the kind of data — logs, user records, search indexes — that aggregates into headlines. Billions of records leaked from Elasticsearch clusters that nobody had to attack.

Version 8.0 changed that. Since 8.0 (2022), a fresh Elasticsearch enables security automatically on first start: it generates TLS certificates, turns on authentication, and prints a password for the elastic user. For the first time, the default is closed.

So this cluster has two audiences, and the first question decides which one you are:

7 controls

Which version, and is security actually on?

Section titled “Which version, and is security actually on?”
Terminal window
curl -s localhost:9200 | grep number # version (may need -k -u once secured)
Version Security default What you do
9.x (current, 9.4 series mid-2026) On, auto-configured Verify it stayed on; don’t undo it
8.x (8.19 maintained) On, auto-configured Same
7.x (end of life) Off Turn it on, then upgrade — 7.x is unsupported

If you’re on 7.x, security is disabled unless someone enabled it, and the version itself no longer receives fixes. Both are reasons this cluster’s first control exists. If you’re on 8.x or 9.x, the auto-configuration did the hard part — your job is confirming nobody switched it off to make something work.

The most common way a modern, secure-by-default Elasticsearch ends up exposed is someone setting xpack.security.enabled: false because a client wouldn’t connect, which is the first control.

You will still find guides — and colleagues — who believe Elasticsearch security requires a commercial license. That was true a long time ago and has not been since 2019: authentication, role-based access control, and TLS moved into the free Basic tier in 6.8 / 7.1. Nothing on this checklist except audit logging needs a subscription.

If a document tells you to buy a license to enable auth, it predates 2019 and everything else in it deserves a second look.

If you’re on OpenSearch — the Apache-2.0 fork AWS created in 2021 after Elastic left open source — most of this applies, but the security plugin is configured differently (its own opensearch-security config, not xpack.* settings). The concepts map one to one; the setting names don’t. Where a page says xpack.security.*, OpenSearch has an equivalent under plugins.security.*. Elastic returned to open source in 2024 (adding AGPLv3 alongside SSPL and ELv2), but the fork long predates that and the two have diverged.

/etc/elasticsearch/elasticsearch.yml, YAML. Auto-configuration writes its TLS and security settings there on first start, in a marked block — don’t hand-edit that block; use the tools.

Terminal window
sudo grep -vE '^\s*#|^\s*$' /etc/elasticsearch/elasticsearch.yml
curl -sk -u elastic https://localhost:9200/_cluster/settings?include_defaults=true

The API is the source of truth: settings can be applied at runtime and diverge from the file.

Most security and network settings need a restart:

Terminal window
sudo systemctl restart elasticsearch

Some settings are updatable at runtime via _cluster/settings (transient is lost on restart; persistent survives). Network binding, TLS and xpack.security.enabled are not among them — they are node settings and need the restart.