Configure ELK stack for centralized logging with Elasticsearch 8, Logstash 8, and Kibana 8

Intermediate 45 min Apr 26, 2026 89 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up a production-grade ELK stack with Elasticsearch 8, Logstash 8, and Kibana 8 for centralized log management. Configure authentication, SSL encryption, and log processing pipelines across multiple data sources.

Prerequisites

  • 4GB RAM minimum
  • 20GB disk space
  • Java 17 compatible system
  • Root or sudo access

What this solves

The ELK stack (Elasticsearch, Logstash, Kibana) provides centralized logging for distributed systems, allowing you to collect, process, and visualize logs from multiple sources in one place. This tutorial sets up a production-ready ELK stack with authentication, SSL encryption, and automated log processing pipelines.

Step-by-step installation

Install Java 17 for Elasticsearch and Logstash

The ELK stack requires Java 17 to run. Install OpenJDK from your distribution's package manager.

sudo apt update
sudo apt install -y openjdk-17-jdk
sudo dnf update -y
sudo dnf install -y java-17-openjdk java-17-openjdk-devel

Add Elastic repository and GPG key

Configure the official Elastic repository to install Elasticsearch, Logstash, and Kibana packages.

wget -qO - 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
cat <

Install Elasticsearch 8

Install Elasticsearch and save the automatically generated password for the elastic user.

sudo apt install -y elasticsearch
sudo dnf install -y --enablerepo=elasticsearch elasticsearch

Configure Elasticsearch cluster settings

Configure Elasticsearch for a single-node cluster with proper memory allocation and network settings.

cluster.name: elk-cluster
node.name: elk-node-1
network.host: 0.0.0.0
http.port: 9200
discovery.type: single-node
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
xpack.security.http.ssl:
  enabled: true
  keystore.path: certs/http.p12
xpack.security.transport.ssl:
  enabled: true
  verification_mode: certificate
  keystore.path: certs/transport.p12
  truststore.path: certs/transport.p12
cluster.initial_master_nodes: ["elk-node-1"]

Set JVM heap size for Elasticsearch

Configure JVM memory allocation to use half of your available RAM, with a maximum of 32GB.

-Xms2g
-Xmx2g

Start and enable Elasticsearch

Enable Elasticsearch to start on boot and start the service.

sudo systemctl daemon-reload
sudo systemctl enable --now elasticsearch

Generate SSL certificates for Elasticsearch

Create SSL certificates for secure communication between ELK stack components.

sudo /usr/share/elasticsearch/bin/elasticsearch-certutil ca --out /etc/elasticsearch/elastic-stack-ca.p12 --pass ""
sudo /usr/share/elasticsearch/bin/elasticsearch-certutil cert --ca /etc/elasticsearch/elastic-stack-ca.p12 --out /etc/elasticsearch/certs/elastic-certificates.p12 --pass ""
sudo chown -R elasticsearch:elasticsearch /etc/elasticsearch/certs/

Reset Elasticsearch passwords

Generate new passwords for built-in users including the elastic superuser.

sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic --batch
Save this password. You'll need it to configure Kibana and authenticate API requests.

Install Logstash 8

Install Logstash to process and transform log data before sending to Elasticsearch.

sudo apt install -y logstash
sudo dnf install -y --enablerepo=elasticsearch logstash

Configure Logstash pipeline

Create a basic Logstash pipeline that accepts syslog input and outputs to Elasticsearch.

input {
  beats {
    port => 5044
  }
  syslog {
    port => 5514
  }
  tcp {
    port => 5000
    codec => json_lines
  }
}

filter {
  if [type] == "syslog" {
    grok {
      match => { "message" => "%{SYSLOGTIMESTAMP:timestamp} %{IPORHOST:host} %{DATA:program}(?:\[%{POSINT:pid}\])?: %{GREEDYDATA:message}" }
    }
    date {
      match => [ "timestamp", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss" ]
    }
  }
  
  if [fields][log_type] == "nginx" {
    grok {
      match => { "message" => "%{NGINXACCESS}" }
    }
  }
  
  mutate {
    remove_field => [ "host", "agent" ]
  }
}

output {
  elasticsearch {
    hosts => ["https://localhost:9200"]
    user => "elastic"
    password => "${ELASTIC_PASSWORD}"
    ssl => true
    ssl_certificate_verification => false
    index => "logs-%{+YYYY.MM.dd}"
  }
  
  stdout {
    codec => rubydebug
  }
}

Set Elasticsearch password for Logstash

Store the Elasticsearch password as an environment variable for Logstash.

ELASTIC_PASSWORD="your_elastic_password_here"

Configure Logstash JVM settings

Optimize Logstash memory usage for your server capacity.

-Xms1g
-Xmx1g
-XX:+UseG1GC
-XX:+UseG1GCApplicationConcurrentTime
-XX:+UnlockExperimentalVMOptions
-XX:+UseCGroupMemoryLimitForHeap

Start and enable Logstash

Enable Logstash to start on boot and start the service.

sudo systemctl enable --now logstash

Install Kibana 8

Install Kibana for visualizing and analyzing log data stored in Elasticsearch.

sudo apt install -y kibana
sudo dnf install -y --enablerepo=elasticsearch kibana

Generate Kibana enrollment token

Create an enrollment token to securely connect Kibana to Elasticsearch.

sudo /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana
Save this token. You'll use it to configure Kibana's connection to Elasticsearch.

Configure Kibana settings

Configure Kibana to connect to Elasticsearch with SSL and proper network settings.

server.port: 5601
server.host: "0.0.0.0"
server.name: "elk-kibana"
elasticsearch.hosts: ["https://localhost:9200"]
elasticsearch.username: "kibana_system"
elasticsearch.password: "kibana_system_password"
elasticsearch.ssl.certificateAuthorities: ["/etc/kibana/certs/ca.crt"]
server.ssl.enabled: true
server.ssl.certificate: "/etc/kibana/certs/kibana.crt"
server.ssl.key: "/etc/kibana/certs/kibana.key"
xpack.security.encryptionKey: "something_at_least_32_characters_long_for_encryption"

Set up Kibana SSL certificates

Extract SSL certificates from Elasticsearch for Kibana to use.

sudo mkdir -p /etc/kibana/certs
sudo /usr/share/elasticsearch/bin/elasticsearch-certutil ca --out /tmp/elastic-stack-ca.p12 --pass ""
sudo /usr/share/elasticsearch/bin/elasticsearch-certutil cert --name kibana --ca /tmp/elastic-stack-ca.p12 --out /tmp/kibana.p12 --pass ""
sudo openssl pkcs12 -in /tmp/kibana.p12 -out /etc/kibana/certs/kibana.crt -clcerts -nokeys -passin pass:""
sudo openssl pkcs12 -in /tmp/kibana.p12 -out /etc/kibana/certs/kibana.key -nocerts -nodes -passin pass:""
sudo openssl pkcs12 -in /tmp/elastic-stack-ca.p12 -out /etc/kibana/certs/ca.crt -clcerts -nokeys -passin pass:""
sudo chown -R kibana:kibana /etc/kibana/certs/
sudo chmod 600 /etc/kibana/certs/*

Reset kibana_system user password

Generate a new password for the kibana_system user that Kibana uses to authenticate with Elasticsearch.

sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u kibana_system --batch
Update kibana.yml. Replace "kibana_system_password" in /etc/kibana/kibana.yml with the generated password.

Start and enable Kibana

Enable Kibana to start on boot and start the service.

sudo systemctl enable --now kibana

Configure firewall rules

Open the necessary ports for ELK stack communication.

sudo ufw allow 9200/tcp comment "Elasticsearch"
sudo ufw allow 5601/tcp comment "Kibana"
sudo ufw allow 5044/tcp comment "Logstash Beats"
sudo ufw allow 5000/tcp comment "Logstash TCP"
sudo ufw allow 5514/tcp comment "Logstash Syslog"
sudo firewall-cmd --permanent --add-port=9200/tcp
sudo firewall-cmd --permanent --add-port=5601/tcp
sudo firewall-cmd --permanent --add-port=5044/tcp
sudo firewall-cmd --permanent --add-port=5000/tcp
sudo firewall-cmd --permanent --add-port=5514/tcp
sudo firewall-cmd --reload

Configure log sources

Set up rsyslog to forward system logs to Logstash for centralized collection.

# Forward all logs to Logstash
. @@localhost:5514
sudo systemctl restart rsyslog

Verify your setup

Check that all ELK stack components are running and communicating properly.

# Check service status
sudo systemctl status elasticsearch
sudo systemctl status logstash
sudo systemctl status kibana

Test Elasticsearch API

curl -k -u elastic:your_elastic_password https://localhost:9200

Check Elasticsearch cluster health

curl -k -u elastic:your_elastic_password https://localhost:9200/_cluster/health

Test log ingestion

echo '{"message": "Test log entry", "timestamp": "'$(date -Iseconds)'"}' | nc localhost 5000

Check for indices

curl -k -u elastic:your_elastic_password https://localhost:9200/_cat/indices

Access Kibana web interface at https://your-server-ip:5601 and login with username elastic and the password you generated.

Configure index patterns and dashboards

Create index pattern in Kibana

Set up an index pattern to view your logs in Kibana.

  1. Open Kibana at https://your-server-ip:5601
  2. Navigate to Management > Stack Management > Index Patterns
  3. Click "Create index pattern"
  4. Enter logs-* as the index pattern
  5. Select @timestamp as the time field
  6. Click "Create index pattern"

Configure log retention policy

Set up Index Lifecycle Management to automatically delete old logs and manage storage.

curl -k -u elastic:your_elastic_password -X PUT "https://localhost:9200/_ilm/policy/logs-policy" -H "Content-Type: application/json" -d'
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_size": "10GB",
            "max_age": "7d"
          },
          "set_priority": {
            "priority": 100
          }
        }
      },
      "warm": {
        "min_age": "7d",
        "actions": {
          "set_priority": {
            "priority": 50
          },
          "allocate": {
            "number_of_replicas": 0
          }
        }
      },
      "delete": {
        "min_age": "30d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}'

Set up centralized log collection

Install Filebeat on client servers

Install Filebeat on servers you want to collect logs from.

sudo apt install -y filebeat
sudo dnf install -y --enablerepo=elasticsearch filebeat

Configure Filebeat

Configure Filebeat to collect system and application logs and send them to Logstash.

filebeat.inputs:
  • type: log
enabled: true paths: - /var/log/*.log - /var/log/syslog - /var/log/auth.log fields: log_type: system fields_under_root: true
  • type: log
enabled: true paths: - /var/log/nginx/access.log - /var/log/nginx/error.log fields: log_type: nginx fields_under_root: true output.logstash: hosts: ["your-elk-server-ip:5044"] logging.level: info logging.to_files: true logging.files: path: /var/log/filebeat name: filebeat keepfiles: 7 permissions: 0644

Enable and start Filebeat

Start Filebeat to begin sending logs to your ELK stack.

sudo systemctl enable --now filebeat

Common issues

Symptom Cause Fix
Elasticsearch won't start Insufficient heap memory or wrong Java version Check sudo journalctl -u elasticsearch -f and adjust heap size in jvm.options
Kibana shows "Kibana server not ready" Cannot connect to Elasticsearch or wrong credentials Verify Elasticsearch is running and check kibana_system password
No logs appearing in Kibana Logstash configuration error or pipeline not running Check sudo journalctl -u logstash -f and test pipeline with echo "test" | nc localhost 5000
SSL certificate errors Certificate path incorrect or permissions wrong Verify certificate files exist and have correct ownership with ls -la /etc/kibana/certs/
High memory usage JVM heap size too large for system RAM Reduce heap size to max 50% of system RAM in jvm.options files
Filebeat connection refused Logstash not listening on beats port or firewall blocking Test with telnet elk-server-ip 5044 and check firewall rules

Security hardening

Create custom Kibana user

Create a dedicated user for Kibana access instead of using the elastic superuser.

curl -k -u elastic:your_elastic_password -X POST "https://localhost:9200/_security/user/kibana_admin" -H "Content-Type: application/json" -d'
{
  "password": "secure_kibana_password",
  "roles": ["kibana_admin", "monitoring_user"],
  "full_name": "Kibana Administrator"
}'

Configure IP restrictions

Restrict access to ELK stack components by IP address.

# Allow only specific IP ranges
sudo ufw delete allow 5601/tcp
sudo ufw allow from 203.0.113.0/24 to any port 5601
sudo ufw delete allow 9200/tcp
sudo ufw allow from 203.0.113.0/24 to any port 9200
sudo firewall-cmd --remove-port=5601/tcp --permanent
sudo firewall-cmd --remove-port=9200/tcp --permanent
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port protocol="tcp" port="5601" accept' --permanent
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port protocol="tcp" port="9200" accept' --permanent
sudo firewall-cmd --reload

Performance optimization

Configure Elasticsearch indices optimization

Optimize index settings for better search performance and storage efficiency.

curl -k -u elastic:your_elastic_password -X PUT "https://localhost:9200/_template/logs-template" -H "Content-Type: application/json" -d'
{
  "index_patterns": ["logs-*"],
  "settings": {
    "number_of_shards": 2,
    "number_of_replicas": 0,
    "refresh_interval": "30s",
    "index.codec": "best_compression"
  },
  "mappings": {
    "properties": {
      "@timestamp": {
        "type": "date"
      },
      "message": {
        "type": "text",
        "analyzer": "standard"
      },
      "level": {
        "type": "keyword"
      }
    }
  }
}'

This ELK stack setup provides a solid foundation for centralized logging. You can extend it by adding more data sources, creating custom dashboards, and implementing alerting rules. For integration with existing monitoring systems, consider configuring rsyslog for additional log forwarding or implementing security hardening measures to protect your logging infrastructure.

Next steps

Running this in production?

Need enterprise-grade logging? Setting up ELK once is straightforward. Keeping it patched, monitored, optimized and highly available across environments is the harder part. See how we run infrastructure like this for European SaaS and e-commerce teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle managed devops services for businesses that depend on uptime. From initial setup to ongoing operations.