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
- Severity: critical
- Severity: critical
- Severity: high
- Severity: high
- Severity: medium
- Severity: medium
- Severity: low
Which version, and is security actually on?
Section titled “Which version, and is security actually on?”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.
The “security is a paid feature” myth
Section titled “The “security is a paid feature” myth”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.
OpenSearch
Section titled “OpenSearch”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.
Where the config lives
Section titled “Where the config lives”/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.
sudo grep -vE '^\s*#|^\s*$' /etc/elasticsearch/elasticsearch.ymlcurl -sk -u elastic https://localhost:9200/_cluster/settings?include_defaults=trueThe API is the source of truth: settings can be applied at runtime and diverge from the file.
Reloading
Section titled “Reloading”Most security and network settings need a restart:
sudo systemctl restart elasticsearchSome 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.