How to Enable X‑Pack Security on Elasticsearch and Kibana (No More Anonymous Access)
When you spin up a fresh cluster you’ll often find the 9200/5601 ports wide open—anyone can curl your logs or hit your dashboards.
The steps below show how to lock down that access with X‑Pack Security, set up TLS, and create initial users and roles in under an hour.
Prerequisites
- Elasticsearch 7.x or 8.x installed (X‑Pack comes bundled).
- A machine with at least 2 GB RAM for the demo.
- openssl available for certificate generation.
- Root or sudo privileges on both ES and Kibana hosts.
Note: If you’re just tinkering locally on a laptop, you can skip TLS but you’ll still need to enable authentication; otherwise anyone with network access could read your data.
1. Enable the X‑Pack Security module in elasticsearch.yml
Open /etc/elasticsearch/elasticsearch.yml and add:
xpack.security.enabled: true xpack.security.transport.ssl.enabled: true xpack.security.http.ssl.enabled: true
Why this matters:
Turning on transport.ssl.enabled protects node‑to‑node traffic, while http.ssl.enabled encrypts browser/client requests. Without these, anyone who can reach your port 9200 gets unencrypted data and potentially credentials.
2. Generate SSL certificates for the cluster
Create a directory to hold them:
sudo mkdir -p /etc/elasticsearch/certs cd /etc/elasticsearch/certs
Generate a CA key, then a server cert signed by that CA:
openssl genrsa -out ca.key 4096 openssl req -x509 -new -nodes -key ca.key \ -subj "/CN=elasticsearch-ca" -days 3650 -out ca.crt openssl genrsa -out server.key 2048 openssl req -new -key server.key \ -subj "/CN=es-node1" -out server.csr openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ -days 3650 -sha256 -out server.crt
Why:
Elasticsearch will refuse to accept any connections without a trusted cert. The CA chain ensures that Kibana and clients can verify the node’s identity.
3. Create keystore and truststore
sudo bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password sudo bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password sudo bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password sudo bin/elasticsearch-keystore add xpack.security.http.ssl.truststore.secure_password
Then import the certs:
sudo bin/elasticsearch-keystore add -f /etc/elasticsearch/certs/server.key \ xpack.security.transport.ssl.keystore.secure_key sudo bin/elasticsearch-keystore add -f /etc/elasticsearch/certs/server.crt \ xpack.security.transport.ssl.keystore.secure_cert # Repeat for truststore with ca.crt
Why:
The keystore holds the private key; the truststore contains CA certificates. Separating them keeps your passwords out of elasticsearch.yml and lets you rotate one without touching the other.
4. Restart Elasticsearch
sudo systemctl restart elasticsearch
Verify that TLS is active:
curl -k https://localhost:9200 -u admin:admin | grep "status"
You should see a JSON response and no SSL errors.
Kibana configuration
Edit /etc/kibana/kibana.yml to point to the new Elasticsearch instance:
elasticsearch.hosts: ["https://es-node1:9200"] elasticsearch.username: "kibana_system" elasticsearch.password: "<password from keystore>" xpack.security.enabled: true
Why this matters:
Kibana needs the same credentials and a secure channel to talk to ES. If you forget xpack.security.enabled, Kibana will assume an unsecured cluster and fail to authenticate.
5. Create initial admin user
Elasticsearch ships with a built‑in elastic superuser that gets created automatically on first run. If you want to rename it or create additional roles, use the Security API:
# Change elastic password
curl -k -X POST "https://localhost:9200/_security/user/elastic/_password" \
-u elastic:changeme \
-H 'Content-Type: application/json' \
-d '{"password":"MyNewStrongPassword!"}'
# Add a new user with read/write on all indices
curl -k -X POST "https://localhost:9200/_security/user/dev_user" \
-u elastic:MyNewStrongPassword! \
-H 'Content-Type: application/json' \
-d '{"password":"devpass","roles":["superuser"],"full_name":"Dev User"}'
Real‑world observation:
I once saw a team forget to set a password on the default elastic user. Their logs were publicly accessible until someone posted a screenshot of a request showing “hello world” in JSON. After adding a proper password and disabling anonymous access, that accidental exposure disappeared.
6. Test everything
Open Kibana at https://kibana-host:5601.
You’ll be prompted for credentials; use the user you just created.
Try pulling data via Dev Tools:
GET /_cluster/health
If it returns a JSON blob instead of an error, your security stack is working.
Troubleshooting tips
| Symptom | Likely cause | Fix |
|---|---|---|
| Connection refused on 9200 from Kibana | ES not listening on TLS port | Check elasticsearch.yml for xpack.security.http.ssl.enabled:true. |
| “Forbidden” after login | User lacks role or wrong password | Verify the user’s roles in _security/user/. |
| SSL errors in browser | Wrong CA certificate | Ensure Kibana trusts the same CA you used for ES. |
That’s all there is to it: enable X‑Pack, spin up certificates, configure keystore/truststore, point Kibana, and create users. You’ve just turned a “no‑auth” cluster into a locked‑down fortress.