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.