Install and configure Elasticsearch 8 with security and performance optimization

Intermediate 45 min Mar 31, 2026 26 views
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

Set up a production-ready Elasticsearch 8 cluster with SSL/TLS security, optimized JVM settings, and automated backups. Includes memory tuning, index mapping strategies, and common troubleshooting fixes.

Prerequisites

  • Root or sudo access
  • At least 4GB RAM
  • Java 11 or later
  • 10GB free disk space

What this solves

Elasticsearch 8 brings enhanced security features, improved performance, and stricter default configurations compared to earlier versions. This tutorial shows you how to install and configure a production-ready Elasticsearch instance with proper security hardening, memory optimization, and backup strategies.

Step-by-step installation

Update system packages and install Java

Elasticsearch 8 requires Java 11 or later. Install OpenJDK and update your package manager.

sudo apt update && sudo apt upgrade -y
sudo apt install -y openjdk-11-jdk curl gnupg apt-transport-https
sudo dnf update -y
sudo dnf install -y java-11-openjdk-devel curl gnupg

Add Elasticsearch repository

Import the Elasticsearch GPG key and add the official repository to ensure you get authentic packages and updates.

curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
sudo apt update
sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
sudo tee /etc/yum.repos.d/elasticsearch.repo > /dev/null <

Install Elasticsearch 8

Install Elasticsearch and save the automatically generated security credentials that appear during installation.

sudo apt install -y elasticsearch
sudo dnf --enablerepo=elasticsearch install -y elasticsearch
Important: Save the elastic user password and enrollment token that appear during installation. You'll need these for initial configuration.

Configure JVM heap size

Set the JVM heap size to half of your available RAM, with a maximum of 32GB. This prevents memory swapping and optimizes garbage collection.

sudo cp /etc/elasticsearch/jvm.options /etc/elasticsearch/jvm.options.backup
# Set heap size to half of available RAM (example for 8GB system)
-Xms4g
-Xmx4g

Enable G1GC for better performance with large heaps

-XX:+UseG1GC -XX:G1HeapRegionSize=32m -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:MaxGCPauseMillis=50

Prevent swapping

-XX:+AlwaysPreTouch

Configure Elasticsearch settings

Set up cluster name, network binding, and security settings. This configuration enables external access while maintaining security.

sudo cp /etc/elasticsearch/elasticsearch.yml /etc/elasticsearch/elasticsearch.yml.backup
# Cluster configuration
cluster.name: production-cluster
node.name: node-1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

Network configuration

network.host: 0.0.0.0 http.port: 9200 transport.port: 9300

Discovery configuration (single node)

discovery.type: single-node

Security configuration

xpack.security.enabled: true xpack.security.enrollment.enabled: true xpack.security.http.ssl.enabled: true xpack.security.http.ssl.keystore.path: certs/http.p12 xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.verification_mode: certificate xpack.security.transport.ssl.client_authentication: required xpack.security.transport.ssl.keystore.path: certs/transport.p12 xpack.security.transport.ssl.truststore.path: certs/transport.p12

Performance settings

indices.memory.index_buffer_size: 20% indices.queries.cache.size: 20% thread_pool.write.queue_size: 1000

Set proper file permissions

Elasticsearch runs as the elasticsearch user and needs proper ownership of its directories. Never use chmod 777 as it compromises security.

sudo chown -R elasticsearch:elasticsearch /etc/elasticsearch
sudo chown -R elasticsearch:elasticsearch /var/lib/elasticsearch
sudo chown -R elasticsearch:elasticsearch /var/log/elasticsearch
sudo chmod 750 /etc/elasticsearch
sudo chmod 660 /etc/elasticsearch/elasticsearch.yml
Never use chmod 777. It gives every user on the system full access to your files. Instead, fix ownership with chown and use minimal permissions like 750 for directories and 660 for config files.

Configure system limits

Increase file descriptor and virtual memory limits to prevent Elasticsearch from failing under load.

elasticsearch soft nofile 65535
elasticsearch hard nofile 65535
elasticsearch soft nproc 4096
elasticsearch hard nproc 4096
elasticsearch soft memlock unlimited
elasticsearch hard memlock unlimited
echo 'vm.max_map_count=262144' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Configure firewall rules

Open the necessary ports for Elasticsearch while maintaining security. Only allow access from trusted networks.

sudo ufw allow from 203.0.113.0/24 to any port 9200
sudo ufw allow from 203.0.113.0/24 to any port 9300
sudo ufw reload
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port protocol="tcp" port="9200" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port protocol="tcp" port="9300" accept'
sudo firewall-cmd --reload

Start and enable Elasticsearch

Enable Elasticsearch to start automatically on boot and start the service now.

sudo systemctl daemon-reload
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch
sudo systemctl status elasticsearch

Reset the elastic user password

Generate a new password for the elastic superuser to ensure you have access to your cluster.

sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic -i
Note: Save this password securely. You'll need it to access Elasticsearch APIs and configure additional users.

Configure SSL certificate for external access

Extract the HTTP CA certificate to verify SSL connections from external clients.

sudo /usr/share/elasticsearch/bin/elasticsearch-certutil ca --silent --pem -out /tmp/ca.zip
sudo unzip /tmp/ca.zip -d /tmp/
sudo cp /tmp/ca/ca.crt /etc/elasticsearch/certs/http_ca.crt
sudo chown elasticsearch:elasticsearch /etc/elasticsearch/certs/http_ca.crt
sudo chmod 644 /etc/elasticsearch/certs/http_ca.crt

Create optimized index template

Set up an index template with performance-optimized mappings and settings for common use cases.

curl -X PUT "https://localhost:9200/_index_template/optimized_template" \
  -H "Content-Type: application/json" \
  -u elastic:YOUR_PASSWORD \
  --cacert /etc/elasticsearch/certs/http_ca.crt \
  -d '{
    "index_patterns": ["logs-", "metrics-"],
    "template": {
      "settings": {
        "number_of_shards": 1,
        "number_of_replicas": 0,
        "refresh_interval": "30s",
        "index.codec": "best_compression",
        "index.mapping.total_fields.limit": 2000
      },
      "mappings": {
        "properties": {
          "@timestamp": {
            "type": "date",
            "format": "strict_date_optional_time||epoch_millis"
          },
          "message": {
            "type": "text",
            "analyzer": "standard"
          },
          "level": {
            "type": "keyword"
          }
        }
      }
    }
  }'

Configure snapshot repository

Set up a local snapshot repository for automated backups. This enables point-in-time recovery and data protection.

sudo mkdir -p /var/backups/elasticsearch
sudo chown elasticsearch:elasticsearch /var/backups/elasticsearch
sudo chmod 750 /var/backups/elasticsearch
curl -X PUT "https://localhost:9200/_snapshot/backup_repository" \
  -H "Content-Type: application/json" \
  -u elastic:YOUR_PASSWORD \
  --cacert /etc/elasticsearch/certs/http_ca.crt \
  -d '{
    "type": "fs",
    "settings": {
      "location": "/var/backups/elasticsearch",
      "compress": true
    }
  }'

Set up automated backup script

Create a script to automatically create daily snapshots with retention policies.

#!/bin/bash

Elasticsearch backup script

ES_HOST="https://localhost:9200" ES_USER="elastic" ES_PASS="YOUR_PASSWORD" CA_CERT="/etc/elasticsearch/certs/http_ca.crt" REPO_NAME="backup_repository" DATE=$(date +%Y-%m-%d) SNAPSHOT_NAME="snapshot-${DATE}"

Create snapshot

curl -X PUT "${ES_HOST}/_snapshot/${REPO_NAME}/${SNAPSHOT_NAME}" \ -H "Content-Type: application/json" \ -u "${ES_USER}:${ES_PASS}" \ --cacert "${CA_CERT}" \ -d "{ \"indices\": \"*\", \"ignore_unavailable\": true, \"include_global_state\": false }"

Delete snapshots older than 30 days

OLD_DATE=$(date -d "30 days ago" +%Y-%m-%d) OLD_SNAPSHOT="snapshot-${OLD_DATE}" curl -X DELETE "${ES_HOST}/_snapshot/${REPO_NAME}/${OLD_SNAPSHOT}" \ -u "${ES_USER}:${ES_PASS}" \ --cacert "${CA_CERT}" 2>/dev/null echo "Backup completed: ${SNAPSHOT_NAME}"
sudo chmod 750 /usr/local/bin/elasticsearch-backup.sh
sudo chown root:elasticsearch /usr/local/bin/elasticsearch-backup.sh

Configure cron for automated backups

Schedule daily backups at 2 AM to minimize impact on production workloads.

echo "0 2   * elasticsearch /usr/local/bin/elasticsearch-backup.sh >> /var/log/elasticsearch/backup.log 2>&1" | sudo tee -a /etc/crontab

Verify your setup

Test your Elasticsearch installation and verify security, performance, and backup configurations.

# Check cluster health
curl -X GET "https://localhost:9200/_cluster/health" \
  -u elastic:YOUR_PASSWORD \
  --cacert /etc/elasticsearch/certs/http_ca.crt

Verify node information

curl -X GET "https://localhost:9200/_nodes/stats" \ -u elastic:YOUR_PASSWORD \ --cacert /etc/elasticsearch/certs/http_ca.crt

Test index creation and search

curl -X POST "https://localhost:9200/test-index/_doc/1" \ -H "Content-Type: application/json" \ -u elastic:YOUR_PASSWORD \ --cacert /etc/elasticsearch/certs/http_ca.crt \ -d '{"message": "Hello Elasticsearch", "timestamp": "2024-01-15T10:00:00Z"}'

Verify snapshot repository

curl -X GET "https://localhost:9200/_snapshot/backup_repository" \ -u elastic:YOUR_PASSWORD \ --cacert /etc/elasticsearch/certs/http_ca.crt

Check service status

sudo systemctl status elasticsearch

Common issues

SymptomCauseFix
Service fails to start with "Permission denied"Incorrect file ownershipsudo chown -R elasticsearch:elasticsearch /etc/elasticsearch /var/lib/elasticsearch
"max virtual memory areas vm.max_map_count is too low"Insufficient virtual memoryecho 'vm.max_map_count=262144' | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
OutOfMemoryError in logsHeap size too large or memory swappingSet heap to max 50% of RAM and enable bootstrap.memory_lock: true
SSL connection errorsMissing or incorrect CA certificateUse --cacert /etc/elasticsearch/certs/http_ca.crt in curl commands
Cluster status yellow or redShard allocation issuesCheck /_cluster/allocation/explain and adjust replica settings
High CPU usage during indexingToo frequent refresh intervalIncrease refresh_interval to 30s or disable during bulk operations

Next steps

Automated install script

Run this to automate the entire setup

#elasticsearch #search-engine #security #ssl #performance #backup #clustering #jvm

Need help?

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.

Talk to an engineer