Bind Elasticsearch to a private interface
/etc/elasticsearch/elasticsearch.ymlnetwork.host: 127.0.0.1# or, to serve a private network explicitly:# network.host: 10.0.1.5# http.host: 10.0.1.5# transport.host: 127.0.0.1sudo systemctl restart elasticsearchWhy it matters
Section titled “Why it matters”network.host sets the address Elasticsearch binds. The default is loopback,
which is safe and useless for anything but a single-node local setup — so people
change it, and the change is where the exposure comes from.
The failure mode is specific and common: someone needs a remote client to
connect, sets network.host: 0.0.0.0, and now the cluster listens on every
interface — including the public one, if there is one. Combined with
security disabled, that is the exact
configuration behind most of the Elasticsearch data breaches.
0.0.0.0 is almost never what you actually want. You want the one private
interface your clients use.
The two ports do different jobs
Section titled “The two ports do different jobs”Elasticsearch listens on two ports, and conflating them is a common mistake:
| Port | Purpose | Who should reach it |
|---|---|---|
| 9200 | HTTP / REST API | Your applications and Kibana |
| 9300 | Transport (inter-node) | Only other cluster nodes |
The transport port is the more dangerous exposure. It’s how nodes join the cluster and replicate data, and it should never be reachable from anywhere except your other nodes. You can split them:
http.host: 10.0.1.5 # apps reach the API heretransport.host: 127.0.0.1 # or the private cluster interface onlyOn a single node, bind transport to loopback. On a multi-node cluster, bind it to the private interface the nodes share — and nothing else.
Production mode is a safety feature, not an obstacle
Section titled “Production mode is a safety feature, not an obstacle”This is the part worth understanding rather than working around.
When you set network.host to anything other than a loopback address,
Elasticsearch switches from development mode to production mode and enforces
bootstrap checks. These are hard preconditions — vm.max_map_count, heap
settings, discovery configuration, file descriptor limits — and if any fails,
the node refuses to start.
People hit a bootstrap check failure, find that reverting network.host to
loopback makes it start, and conclude the checks are the problem. They are not.
The checks are Elasticsearch saying “you are about to run this where it matters,
and these settings would bite you under load.” A node that only passes because
it’s bound to loopback is a node that will fall over the first time it’s stressed.
Fix the checks it names — they’re documented and specific — rather than dodging them by staying in development mode. The bootstrap checks are one of the better safety mechanisms in any service on this site.
Related
Section titled “Related”- Enable security — do this too; binding alone isn’t enough.
- Enable TLS — the transport port needs it between nodes.
- Elasticsearch exposed to the internet — what 0.0.0.0 plus no auth means.