The ELK Stack — Elasticsearch, Logstash, and Kibana — is a battle-tested open-source platform for centralizing, parsing, and visualizing log data at scale. Elasticsearch stores and indexes logs, Logstash ingests and transforms them, and Kibana provides a browser-based interface for searching and dashboarding. Running the ELK Stack on RHEL 9 gives you a self-hosted alternative to commercial log-management services with full control over your data. This tutorial installs all three components and walks through a basic pipeline that ships a log file into Elasticsearch.

Prerequisites

  • RHEL 9 server with at least 4 GB RAM (8 GB recommended for production)
  • Root or sudo access
  • Java 11 or later (Elasticsearch bundles its own JDK, but Logstash requires a system JDK)
  • Firewalld running
  • At least 20 GB free disk space

Step 1 — Add the Elastic Repository

Import the Elastic GPG key and add the Elasticsearch 8.x repository before installing any packages.

# Import the GPG key
sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch

# Add the repository
sudo tee /etc/yum.repos.d/elasticsearch.repo > /dev/null <<'EOF'
[elasticsearch]
name=Elasticsearch repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
EOF

Step 2 — Install and Configure Elasticsearch

Install Elasticsearch, adjust the main configuration file, then start and enable the service. For a single-node lab setup, disable security features to simplify the initial configuration.

sudo dnf install -y elasticsearch

# Configure Elasticsearch
sudo tee /etc/elasticsearch/elasticsearch.yml > /dev/null <<'EOF'
cluster.name: my-cluster
node.name: node-1
network.host: localhost
http.port: 9200
discovery.type: single-node

# Disable security for single-node lab (re-enable for production)
xpack.security.enabled: false
xpack.security.http.ssl.enabled: false
EOF

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

Verify Elasticsearch is responding:

curl -s http://localhost:9200
# Expected output includes: "cluster_name" : "my-cluster"

Step 3 — Install and Configure Kibana

Install Kibana from the same Elastic repository. Configure it to listen on all interfaces so you can reach the UI from your workstation.

sudo dnf install -y kibana

# Configure Kibana
sudo tee /etc/kibana/kibana.yml > /dev/null <<'EOF'
server.port: 5601
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://localhost:9200"]
EOF

sudo systemctl enable --now kibana

# Open firewall ports
sudo firewall-cmd --permanent --add-port=9200/tcp
sudo firewall-cmd --permanent --add-port=5601/tcp
sudo firewall-cmd --reload

Kibana can take 30–60 seconds to start. Access it at http://<your-server-ip>:5601.

Step 4 — Install Logstash and Java

Logstash requires a Java runtime. Install OpenJDK 17 and then install Logstash from the Elastic repository.

sudo dnf install -y java-17-openjdk-headless
java -version

sudo dnf install -y logstash
sudo systemctl enable logstash

Step 5 — Create a Logstash Pipeline

Create a pipeline configuration that reads from a log file, parses lines with a grok filter, and ships parsed events to Elasticsearch. Place pipeline configs in /etc/logstash/conf.d/.

sudo tee /etc/logstash/conf.d/syslog.conf > /dev/null < "/var/log/messages"
    start_position => "beginning"
    sincedb_path => "/var/lib/logstash/sincedb_syslog"
    type => "syslog"
  }
}

filter {
  if [type] == "syslog" {
    grok {
      match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:[%{POSINT:syslog_pid}])?: %{GREEDYDATA:syslog_message}" }
    }
    date {
      match => [ "syslog_timestamp", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss" ]
    }
  }
}

output {
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "syslog-%{+YYYY.MM.dd}"
  }
  stdout { codec => rubydebug }
}
EOF

sudo systemctl start logstash
sudo systemctl status logstash

Step 6 — Verify Data in Kibana

Once Logstash has started and ingested some events, check that the index exists in Elasticsearch, then create a Kibana data view to explore the logs.

# Check index was created
curl -s http://localhost:9200/_cat/indices?v | grep syslog

# List all indices
curl -s http://localhost:9200/_cat/indices?v

# Sample a document from the index (replace the date)
curl -s "http://localhost:9200/syslog-$(date +%Y.%m.%d)/_search?pretty&size=1"

In Kibana, go to Stack Management → Index Patterns (Data Views), create a pattern matching syslog-*, set the time field to @timestamp, and then navigate to Discover to search and filter your log data in real time.

Conclusion

You now have a functioning single-node ELK Stack on RHEL 9 ingesting syslog data through a Logstash pipeline and making it searchable in Kibana. This foundation can be extended by adding Filebeat agents on remote hosts to ship logs centrally without running a full Logstash instance on each server. For production deployments, re-enable xpack.security in elasticsearch.yml, configure TLS between components, and consider setting index lifecycle management (ILM) policies to control disk usage over time.

Next steps: How to Install Prometheus and Grafana on RHEL 9, How to Install Zabbix on RHEL 9, and How to Configure Logrotate for Application Logs on RHEL 9.