The ELK Stack (Elasticsearch, Logstash, and Kibana) is a powerful
open-source
log management and analytics platform. Elasticsearch, its core
component,
supports replication, allowing data to be copied across multiple
nodes.
This ensures high availability by preventing data loss in case of
node
failures.
Replication in Elasticsearch improves query performance by
distributing search
requests across replicas. It also enhances scalability, allowing
systems to
handle more queries efficiently. By default, Elasticsearch creates one
replica per
shard, but this can be adjusted based on requirements. Proper replication strategies
help in
load balancing, fault tolerance, and overall system reliability.
Elasticsearch is a distributed search and analytics engine designed for handling large volumes of data in real time. It stores data in a NoSQL format using JSON documents and provides fast full-text search capabilities. Data is indexed using an inverted index, allowing quick retrieval and analysis. Elasticsearch is scalable, supporting horizontal scaling by adding more nodes to a cluster. It offers replication and sharding, ensuring data redundancy and high availability. Common use cases include log analysis, security monitoring, and business intelligence.
Logstash is a data processing pipeline that collects, transforms, and sends data to various destinations, including Elasticsearch. It can ingest data from multiple sources such as logs, metrics, databases, and message queues. Logstash processes data using a powerful filtering system, allowing transformation, enrichment, and parsing. It supports various plugins to handle different data formats, including JSON, CSV, and syslog. Logstash is often used for log collection, data transformation, and real-time data processing before storage.
Kibana is a visualization and analytics tool designed to interact with data stored in Elasticsearch. It provides an intuitive dashboard interface for creating visualizations like charts, graphs, and maps. Kibana enables real-time data exploration, making it easy to analyze logs and monitor system performance. It includes features like machine learning, security monitoring, and alerting. Users can build interactive dashboards and set up alerts for anomalies in data. Kibana is widely used for log analysis, security event monitoring, and business intelligence reporting.
Before we begin, ensure you have:
If Java is installed on the machine, the following output will be displayed:
openjdk version "1.8.0_442"
OpenJDK Runtime Environment (build 1.8.0_442-8u442-b06~us1-0ubuntu1~20.04-b06)
OpenJDK 64-Bit Server VM (build 25.442-b06, mixed mode)
Update System Package : sudo apt update && sudo apt upgrade -y
Download Elasticsearch 8.17.3 :
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.17.3-amd64.deb
Install elasticsearch : sudo dpkg -i elasticsearch-8.17.3-amd64.deb
Configure elasticsearch :
sudo nano /etc/elasticsearch/elasticsearch.yml
# Network settings
network.host: 0.0.0.0
http.port: 9200
# Cluster settings
cluster.name: my-cluster
node.name: node-1
# Security settings
xpack.security.enabled: true
Start and Enable elasticsearch :
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch
Check the status to see if Elasticsearch is running properly; the result should appear as shown below:
Loaded: loaded (/lib/systemd/system/elasticsearch.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2025-03-25 11:59:26 IST; 16min ago
Docs: https://www.elastic.co
Main PID: 1554 (java)
Tasks: 92 (limit: 18932)
Memory: 8.5G
CGroup: /system.slice/elasticsearch.service
├─1554 /usr/share/elasticsearch/jdk/bin/java -Xms4m -Xmx64m -XX:+UseSerialGC -Dcli.name=server -Dcli.script=/usr/share/elasticsearch/bin/e>
├─2134 /usr/share/elasticsearch/jdk/bin/java -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -XX:+AlwaysPreTouc>
└─2158 /usr/share/elasticsearch/modules/x-pack-ml/platform/linux-x86_64/bin/controller
Mar 25 11:58:11 host systemd[1]: Starting Elasticsearch...
Mar 25 11:58:47 host systemd-entrypoint[2134]: CompileCommand: dontinline java/lang/invoke/MethodHandle.setAsTypeCache bool dontinline = true
Mar 25 11:58:47 host systemd-entrypoint[2134]: CompileCommand: dontinline java/lang/invoke/MethodHandle.asTypeUncached bool dontinline = true
Mar 25 11:59:26 host systemd[1]: Started Elasticsearch.
lines 1-16/16 (END)
Generate Password for elasticsearch. By Default the username and password is necessary to connect the elasticsearch version 8.17.3
Use the following command to generate the Elasticsearch password:
sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic
Verify Installation:
After the password is generated successfully, run the following command to verify it:
elasticsearch version 8.17.3 properly installed .
curl -k http://localhost:9200 -u elastic:your_password
If the elasticsearch has properly configured the below results exists :
{
"name" : "hostname",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "kKzyHzjcTGGei6ikXndcFA",
"version" : {
"number" : "8.17.3",
"build_flavor" : "default",
"build_type" : "deb",
"build_hash" : "a091390de485bd4b127884f7e565c0cad59b10d2",
"build_date" : "2025-02-28T10:07:26.089129809Z",
"build_snapshot" : false,
"lucene_version" : "9.12.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}
TLS/SSL configuration in elasticsearch 8.17.3 :
Elasticsearch 8.17.3 includes built-in security and requires TLS/SSL for communication. Follow these steps to configure TLS/SSL for both HTTP and transport layers.
Elasticsearch includes a built-in tool to generate certificates. Use the following command to generate a certificate:
sudo /usr/share/elasticsearch/bin/elasticsearch-certutil cert --silent --pem --keep-ca-key --out /etc/elasticsearch/certs.zip
Extract the certificates :
sudo apt install unzip -y
sudo mkdir -p /etc/elasticsearch/certs
sudo unzip /etc/elasticsearch/certs.zip -d /etc/elasticsearch/certs/
sudo chmod -R 750 /etc/elasticsearch/certs
sudo chown -R elasticsearch:elasticsearch /etc/elasticsearch/certs
2. Configure the elasticsearch for TLS/SSL:
Edit the elasticsearch configuration file using the below command:
sudo nano /etc/elasticsearch/elasticsearch.yml
Add or update the settings:
If the features below are not present in elasticsearch.yml, add them. If they already exist, set or enable them to true.
# Enable security features
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
# Enable encryption and mutual authentication between cluster nodes
xpack.security.transport.ssl:
enabled: true
verification_mode: certificate
keystore.path: certs/transport.p12
truststore.path: certs/transport.p12
# Create a new cluster with the current node only
# Additional nodes can still join the cluster later
cluster.initial_master_nodes: ["hostname"]
# Allow HTTP API connections from anywhere
# Connections are encrypted and require user authentication
http.host: 0.0.0.0
# Allow other nodes to join the cluster from anywhere
# Connections are encrypted and mutually authenticated
#transport.host: 0.0.0.0
Restart Elasticsearch :
Restart the elasticsearch to apply the changes :
sudo systemctl restart elasticsearch.service
Afterward, check whether Elasticsearch is running using the command below:
:
sudo systemctl status elasticsearch.service
Verify Elasticsearch TLS/SSL Configuration :
By default our certificate exists in the below directory
sudo /etc/elasticsearch/certs
Use the following command to verify the TLS/SSL installation:
curl -k --cacert /etc/elasticsearch/certs/ca.crt -u elastic:password 'https://localhost:9200'
When Elasticsearch is configured correctly for TLS/SSL, the result appears as shown below:
{
"name" : "hostname",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "kKzyHzjcTGGei6ikXndcFA",
"version" : {
"number" : "8.17.3",
"build_flavor" : "default",
"build_type" : "deb",
"build_hash" : "a091390de485bd4b127884f7e565c0cad59b10d2",
"build_date" : "2025-02-28T10:07:26.089129809Z",
"build_snapshot" : false,
"lucene_version" : "9.12.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}
Install Logstash :
Download Logstash 8.17.3
wget https://artifacts.elastic.co/downloads/logstash/logstash-8.17.3-amd64.deb
Install Logstash 8.17.3
sudo dpkg -i logstash-8.17.3-amd64.deb
Verify Logstash Installation :
Check whether Logstash version 8.17.3 is installed using the command below. If the version is displayed, it means Logstash is installed correctly on our machine.
/usr/share/logstash/bin/logstash --version
The result looks like :
Using bundled JDK: /usr/share/logstash/jdk
logstash 8.17.3
Start and Enable logstash :
sudo systemctl enable logstash
sudo systemctl start logstash
Check the status for Logstash installation
:
sudo systemctl status logstash
The output is as follows:
logstash.service - logstash
Loaded: loaded (/lib/systemd/system/logstash.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2025-03-25 12:55:40 IST; 11s ago
Main PID: 4519 (java)
Tasks: 24 (limit: 18932)
Memory: 344.9M
CGroup: /system.slice/logstash.service
└─4519 /usr/share/logstash/jdk/bin/java -Xms1g -Xmx1g -Djava.awt.headless=true
-Dfile.encoding=UTF-8 -Djruby.compile.invokedynamic=true -XX:+HeapDumpOnOutOfMemoryError
->
Mar 25 12:55:40 hostname systemd[1]: Started logstash.
Mar 25 12:55:40 hostname logstash[4519]: Using bundled JDK: /usr/share/logstash/jdk
lines 1-11/11 (END)
1. Logstash writes logs to /var/log/logstash/logstash-plain.log. View logs using:
sudo tail -f /var/log/logstash/logstash-plain.log
2. To check Logstash logs is using journalctl
sudo journalctl -u logstash -f
Download Kibana 8.17.3
To download Kibana 8.17.3, use the below command:
wget https://artifacts.elastic.co/downloads/kibana/kibana-8.17.3-amd64.deb
Install Kibana 8.17.3 :
sudo dpkg -i kibana-8.17.3-amd64.deb
Configure kibana 8.17.3 :
Follow the below steps to configure Kibana
Step-1:
Open the kibana configuration file :sudo nano /etc/kibana/kibana.yml
Step-2:
Uncomment and modify the below setting :
server.port: "5601"
server.host: "localhost"
elasticsearch.hosts: ["http://localhost:9200"]
elasticsearch.username: "kibana_system"
elasticsearch.password: "password"
elasticsearch.maxSockets: 1024
After modifying the settings, save and exit the configuration.
Start and Enable Kibana:
sudo systemctl enable kibana
sudo systemctl start kibana
To check whether Kibana is configured properly, the results appear as shown below:
Loaded: loaded (/lib/systemd/system/kibana.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2025-03-25 15:14:22 IST; 9min ago
Docs: https://www.elastic.co
Main PID: 1554 (java)
Main PID: 9690 (node)
Tasks: 11 (limit: 18932)
Memory: 598.2M
CGroup: /system.slice/kibana.service
└─9690 /usr/share/kibana/bin/../node/glibc-217/bin/node /usr/share/kibana/bin/../src/cli/dist
Mar 25 15:17:09 hostname kibana[9690]: [2025-03-25T15:17:09.848+05:30][ERROR][http] 400 Bad Request
Mar 25 15:19:46 hostname kibana[9690]: [2025-03-25T15:19:46.504+05:30][INFO ][plugins.securitySolution] Fetch risk engine metrics
Mar 25 15:19:46 hostname kibana[9690]: [2025-03-25T15:19:46.860+05:30][INFO ][plugins.cloudSecurityPosture] Cloud Security telemetry: Resources payload was sent successfully
Mar 25 15:19:46 hostname kibana[9690]: [2025-03-25T15:19:46.861+05:30][INFO ][plugins.cloudSecurityPosture] Cloud Security telemetry: Accounts payload was sent successfully
Mar 25 15:19:46 hostname kibana[9690]: [2025-03-25T15:19:46.862+05:30][INFO ][plugins.cloudSecurityPosture] Cloud Security telemetry: Rules payload was sent successfully
Mar 25 15:19:47 hostname kibana[9690]: [2025-03-25T15:19:47.193+05:30][INFO ][plugins.cloudSecurityPosture] Cloud Security telemetry: Alerts payload was sent successfully
Mar 25 15:19:47 hostname kibana[9690]: [2025-03-25T15:19:47.199+05:30][INFO ][plugins.cloudSecurityPosture] Cloud Security telemetry: Cloud Accounts payload was sent successfully
Mar 25 15:19:47 hostname kibana[9690]: [2025-03-25T15:19:47.336+05:30][INFO ][plugins.cloudSecurityPosture] Cloud Security telemetry: Muted Rules payload was sent successfully
Mar 25 15:19:47 hostname kibana[9690]: [2025-03-25T15:19:47.372+05:30][INFO ][plugins.cloudSecurityPosture] Cloud Security telemetry: Installation payload was sent successfully
Mar 25 15:19:47 hostname kibana[9690]: [2025-03-25T15:19:47.406+05:30][INFO ][plugins.cloudSecurityPosture] Cloud Security telemetry: Indices payload was sent successfully
Open kibana in browser :
Once Kibana is configured properly, open it using the following URL:
http://<server_ip>:5601
For example :http://localhost:5601
Configure kibana 8.17.3 with TLS/SSL:
If Elasticsearch is already configured with TLS/SSL (HTTPS), you need to configure Kibana to communicate securely with it.
Now, let's see how to set up Kibana with TLS/SSL:
Step-1 :
Open the configuration file :sudo nano /etc/kibana/kibana.yml
Step-2 :
Copy the certficate from the elasticsearch certs directory to
the kibana certs directory :
cp /etc/elasticsearch/certs/elastic-stack-ca.crt /etc/kibana/
Set the corrector permissions for certificates :
chown kibana:kibana /etc/kibana/elastic-stack-ca.crt
chmod 600 /etc/kibana/elastic-stack-ca.crt
Verify the file ownership and permissions :
ls -l /etc/kibana/elastic-stack-ca.crt
The output appears as follows:
-rwxr-x--- 1 kibana kibana 1915 Mar 25 13:56 /etc/kibana/elastic-stack-ca.crt
Step-3 :
Uncomment and modify the below setting :
server.port: 5601
server.host : "localhost"
elasticsearch.hosts: ["https://localhost:9200"]
elasticsearch.username: "kibana_system"
elasticsearch.password: "password"
elasticsearch.maxSockets: 1024
elasticsearch.ssl.certificateAuthorities: [ "/etc/kibana/http_ca.crt" ]
Finally save and exit the kibana configurations.
If you want to access Kibana over HTTPS
instead of http://localhost:5601, configure TLS in kibana.yml:
Add these settings:
server.ssl.enabled: true
server.ssl.certificate: "/etc/kibana/kibana.crt"
server.ssl.key: "/etc/kibana/kibana.key"
Step-4 :
Restart the Kibana to get the changes applied:
sudo systemctl restart kibana.service
If you do not have the Elasticsearch user, use the command below to manually reset the password.
Use the following command in your terminal:
sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u <username> -i
If you're using Kibana HTTPS, use:
https://localhost:5601
If Kibana SSL is disabled, use:
http://localhost:5601
If Kibana is running on a remote server, replace localhost with the server's IP:
http://your-server-ip:5601
Download MQTT Broker and Running in our machine and it looks like the
Elasticsearch Connector Configuration
The Elasticsearch Connector in CrystalMQ allows seamless data retrieval from the broker and efficient indexing into Elasticsearch. It ensures secure authentication, encrypted communication, and reliable data storage, making it an essential component for managing and analyzing IoT data.
1. Authentication in Elasticsearch Connector
Elasticsearch supports multiple authentication methods to ensure secure access.
Basic Authentication
By default, Elasticsearch requires a username and password for authentication. Without valid credentials, the connection will fail, leading to authentication errors. This method is simple and widely used for securing access.
PKI (Public Key Infrastructure) Authentication
PKI authentication uses digital certificates instead of passwords for secure access. In this approach:
JWT (JSON Web Token) Authentication
JWT authentication provides token-based access control, where an Access Token is used instead of traditional credentials.
2. Encryption: SSL/TLS in Elasticsearch
To protect data in transit, Elasticsearch supports SSL/TLS encryption, ensuring that communication between clients and the server remains private and secure.
Setting Up SSL/TLS Encryption
1. CA Certificate - A trusted certificate authority that signs other certificates.
2. Client Certificate - Identifies the client to Elasticsearch.
3. Client Key - A private key used to authenticate the client certificate.
By configuring authentication and encryption properly, the Elasticsearch Connector in CrystalMQ provides a secure, scalable, and efficient solution for managing IoT data.

In the Elasticsearch connector, basic authentication (username and password) is required, so it can be configured as the default.

Enter the configurations in the Elasticsearch connector, including the Elasticsearch index, to establish the connection.
Once all configuration fields are completed, select 'Save' to save the configurations to the database.
If the Elasticsearch connector is connected successfully, the Enable/Disable toggle button will show green. If there is an issue with the connector, the button will display red.

In the above configuration, only Basic Authentication is used, without enabling TLS/SSL encryption.
Use Logstash to view data from Elasticsearch. Let’s see how we can use the Logstash pipeline to capture this data.
Logstash offers various methods to output data, depending on how you want to store, visualize, or forward it. Some common output options include:
Step -1 :
Configure Logstash to retrieve data from Elasticsearch:
input {
elasticsearch {
hosts => ["http://your-elasticsearch-host:9200"]
index => "your-index-name"
user => "your-username"
password => "your-password"
}
}
output {
stdout {
codec => json
}
}
Run Logstash
Start Logstash using the following command:
In case Logstash has been installed through a package manager:
sudo /usr/share/logstash/bin/logstash -f
/etc/logstash/conf.d/elasticsearch_logstash.conf
For example : sudo /usr/share/logstash/bin/logstash -f
~/Documents/elasticsearch_logstash.conf
After configuring Logstash, use the command below to verify that the configuration has been applied correctly.
sudo /usr/share/logstash/bin/logstash --path.settings
/etc/logstash -f
path/to/elasticsearch_logstash.conf
--config.test_and_exit
If the configuration is correct, the output is as follows:
Using bundled JDK: /usr/share/logstash/jdk
Sending Logstash logs to /var/log/logstash which is now configured via
log4j2.properties
[2025-03-26T11:40:50,375][WARN ][logstash.runner ] NOTICE: Running
Logstash as a superuser is strongly discouraged as it poses a security risk.
Set 'allow_superuser' to false for better security.
[2025-03-26T11:40:50,386][INFO ][logstash.runner ] Log4j configuration
path used is: /etc/logstash/log4j2.properties
[2025-03-26T11:40:50,388][INFO ][logstash.runner ] Starting Logstash
{"logstash.version"=>"8.17.3", "jruby.version"=>"jruby 9.4.9.0 (3.1.4) 2024-11-
04 547c6b150e OpenJDK 64-Bit Server VM 21.0.6+7-LTS on 21.0.6+7-LTS +indy
+jit [x86_64-linux]"}
[2025-03-26T11:40:50,392][INFO ][logstash.runner ] JVM bootstrap
flags: [-Xms1g, -Xmx1g, -Djava.awt.headless=true, -Dfile.encoding=UTF-8, -
Djruby.compile.invokedynamic=true, -
XX:+HeapDumpOnOutOfMemoryError, -
Djava.security.egd=file:/dev/urandom, -
Dlog4j2.isThreadContextMapInheritable=true, -Dlogstash.jackson.stream-
read-constraints.max-string-length=200000000, -
Dlogstash.jackson.stream-read-constraints.max-number-length=10000, -
Djruby.regexp.interruptible=true, -Djdk.io.File.enableADS=true, --add-
exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED, --add-
exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED, --add-
exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED, --add-
exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED, --add-
exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED, --add-
opens=java.base/java.security=ALL-UNNAMED, --add-
opens=java.base/java.io=ALL-UNNAMED, --add-
opens=java.base/java.nio.channels=ALL-UNNAMED, --add-
opens=java.base/sun.nio.ch=ALL-UNNAMED, --add-
opens=java.management/sun.management=ALL-UNNAMED, -
Dio.netty.allocator.maxOrder=11]
[2025-03-26T11:40:50,462][INFO]
[org.logstash.jackson.StreamReadConstraintsUtil] Jackson default value
override `logstash.jackson.stream-read-constraints.max-string-length`
configured to `200000000`
[2025-03-26T11:40:50,463][INFO]
[org.logstash.jackson.StreamReadConstraintsUtil] Jackson default value
override `logstash.jackson.stream-read-constraints.max-number-length`
configured to `10000`
[2025-03-26T11:40:50,755][WARN ][logstash.config.source.multilocal]
Ignoring the 'pipelines.yml' file because modules or command line options
are specified
[2025-03-26T11:40:51,186][INFO ][org.reflections.Reflections] Reflections
took 177 ms to scan 1 urls, producing 152 keys and 530 values
[2025-03-26T11:40:51,846][INFO ][logstash.javapipeline ] Pipeline `main` is
configured with `pipeline.ecs_compatibility: v8` setting. All plugins in this
pipeline will default to `ecs_compatibility => v8` unless explicitly
configured otherwise.
Configuration OK
[2025-03-26T11:40:51,848][INFO ][logstash.runner ] Using
config.test_and_exit mode. Config Validation Result: OK. Exiting Logstash
Check the Logstash logs using the command below to verify that data is being retrieved from Elasticsearch and displayed in Logstash.
The Logstash log appears as shown below:
Using bundled JDK: /usr/share/logstash/jdk
[WARN ] 2025-03-25 18:16:42.180 [main] runner - 'pipeline.buffer.type'
setting is not explicitly defined.Before moving to 9.x set it to 'heap' and
tune heap size upward, or set it to 'direct' to maintain existing behavior.
[INFO ] 2025-03-25 18:16:42.181 [main] runner - Starting Logstash
{"logstash.version"=>"8.17.3", "jruby.version"=>"jruby 9.4.9.0 (3.1.4) 2024-11-
04 547c6b150e OpenJDK 64-Bit Server VM 21.0.6+7-LTS on 21.0.6+7-LTS +indy
+jit [x86_64-linux]"}
[INFO ] 2025-03-25 18:16:42.185 [main] runner - JVM bootstrap flags: [-Xms1g,
-Xmx1g, -Djava.awt.headless=true, -Dfile.encoding=UTF-8, -
Djruby.compile.invokedynamic=true, -
XX:+HeapDumpOnOutOfMemoryError, -
Djava.security.egd=file:/dev/urandom, -
Dlog4j2.isThreadContextMapInheritable=true, -Dlogstash.jackson.stream-
read-constraints.max-string-length=200000000, -
Dlogstash.jackson.stream-read-constraints.max-number-length=10000, -
Djruby.regexp.interruptible=true, -Djdk.io.File.enableADS=true, --add-
exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED, --add-
exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED, --add-
exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED, --add-
exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED, --add-
exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED, --add-
opens=java.base/java.security=ALL-UNNAMED, --add-
opens=java.base/java.io=ALL-UNNAMED, --add-
opens=java.base/java.nio.channels=ALL-UNNAMED, --add-
opens=java.base/sun.nio.ch=ALL-UNNAMED, --add-
opens=java.management/sun.management=ALL-UNNAMED, -
Dio.netty.allocator.maxOrder=11]
[INFO ] 2025-03-25 18:16:42.373 [main] StreamReadConstraintsUtil - Jackson
default value override `logstash.jackson.stream-read-constraints.max-
string-length` configured to `200000000`
[INFO ] 2025-03-25 18:16:42.373 [main] StreamReadConstraintsUtil - Jackson
default value override `logstash.jackson.stream-read-constraints.max-
number-length` configured to `10000`
[WARN ] 2025-03-25 18:16:42.655 [LogStash::Runner] multilocal - Ignoring
the 'pipelines.yml' file because modules or command line options are
specified
[INFO ] 2025-03-25 18:16:43.449 [Api Webserver] agent - Successfully started
Logstash API endpoint {:port=>9601, :ssl_enabled=>false}
[INFO ] 2025-03-25 18:16:43.805 [Converge PipelineAction::Create
Reflections - Reflections took 169 ms to scan 1 urls, producing 152 keys and
[INFO ] 2025-03-25 18:16:44.521 [Converge PipelineAction::Create
javapipeline - Pipeline `main` is configured with
`pipeline.ecs_compatibility: v8` setting. All plugins in this pipeline will
default to `ecs_compatibility => v8` unless explicitly configured
otherwise.
[INFO ] 2025-03-25 18:16:44.579 [[main]-pipeline-manager] javapipeline -
Starting pipeline {:pipeline_id=>"main", "pipeline.workers"=>4,
"pipeline.batch.size"=>125, "pipeline.batch.delay"=>50,
"pipeline.max_inflight"=>500,
"pipeline.sources"=>["/home/bevywise/Documents/elasticsearch_logstash.
conf"], :thread=>"#<Thread:0x612a9b3c /usr/share/logstash/logstash-
core/lib/logstash/java_pipeline.rb:138 run>"}
[INFO ] 2025-03-25 18:16:45.277 [[main]-pipeline-manager] javapipeline -
Pipeline Java execution initialization time {"seconds"=>0.7}
[INFO ] 2025-03-25 18:16:45.591 [[main]-pipeline-manager] elasticsearch -
`search_api => auto` resolved to `search_after` {:elasticsearch=>"8.17.3"}
[INFO ] 2025-03-25 18:16:45.593 [[main]-pipeline-manager] elasticsearch -
ECS compatibility is enabled but `target` option was not specified. This
may cause fields to be set at the top-level of the event where they are
likely to clash with the Elastic Common Schema. It is recommended to set
the `target` option to avoid potential schema conflicts (if your data is ECS
compliant or non-conflicting, feel free to ignore this message)
[INFO ] 2025-03-25 18:16:45.597 [[main]-pipeline-manager] javapipeline -
Pipeline started {"pipeline.id"=>"main"}
[INFO ] 2025-03-25 18:16:45.600 [[main]<elasticsearch] searchafter - Create
point in time (PIT)
[INFO ] 2025-03-25 18:16:45.619 [Agent thread] agent - Pipelines running
{:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
[INFO ] 2025-03-25 18:16:45.630 [[main]<elasticsearch] searchafter - Query
start
[INFO ] 2025-03-25 18:16:45.703 [[main]<elasticsearch] searchafter - Query
completed
[INFO ] 2025-03-25 18:16:45.704 [[main]<elasticsearch] searchafter - Closing
point in time (PIT)
{
"message" => "{\"sensor_id\": \"sensor_123\", \"temperature\": 25.5, \"humidity\": 60,
\"status\": \"active\"}",
"topic" => "test/search",
"client_id" => "Bevywise-fQ4kK3aI2uQ0",
"timestamp" => 1742478868,
"properties" => "{}",
"@version" => "1",
"@timestamp" => 2025-03-25T12:46:45.691895415Z
}
{
"message" => "{\"sensor_id\": \"sensor123\", \"temperature\": 27, \"humidity\": 712,
\"status\": \"active\"}",
"topic" => "test/moniting",
"client_id" => "Bevywise-qI8mQ7rI9uM3",
"timestamp" => 1742817477,
"properties" => "{}",
"@version" => "1",
"@timestamp" => 2025-03-25T12:46:45.693859511Z
}
{
"message" => "{\"sensor_id\": \"sensor123\", \"temperature\": 27, \"humidity\": 712,
\"status\": \"active\"}",
"topic" => "test/moniting",
"client_id" => "Bevywise-eP3cT2xW0vA4",
"timestamp" => 1742817662,
"properties" => "{}",
"@version" => "1",
"@timestamp" => 2025-03-25T12:46:45.693957511Z
}
Use Kibana to visualize the data once Elasticsearch has received it from the CrystalMQ Elasticsearch Connector.
Step-1:
Open the browser url like http://<host_ip>:5601
Step-2: Create an Index Pattern
Before visualizing data, you need to define an index pattern to access your MQTT logs.
Step-3: Chart for MQTT Messages Over Time
Before visualizing data, you need to define an index pattern to access your MQTT logs.
Step-4: The chart looks as follows:
Bar chart :

Pie-chart :

Table View :

Now, we will use Elasticsearch with TLS/SSL encryption to establish a connection and send messages through Data Connectors in CrystalMQ:
Step-1 : Verify that all certificate paths in the Elasticsearch configuration are provided correctly. If any changes are made, restart Elasticsearch to apply them.
Step-2 : Open the Kibana configuration file and verify that all settings are properly configured for TLS/SSL.
Step-3 : Run CrystalMQ and use the Elasticsearch connector in Data Connectors to connect to Elasticsearch with SSL/TLS encryption.
Step-4 : For SSL/TLS encryption, the CA root certificate is required to connect to Elasticsearch. The client certificate and client key are optional—uploading just the CA root certificate is sufficient to establish the connection.

Step-5 : After uploading all the certificates, save the configuration and enable the connector using the Enable/Disable toggle button.

Step-6 : The Elasticsearch connector with TLS/SSL encryption has now been successfully connected in CrystalMQ.
Use Logstash to view the logs from the Elasticsearch connector:
Configure Logstash to Retrieve Data from Elasticsearch:
input {
elasticsearch {
hosts => ["https://your_elasticsearch_host:9200"]
user => "elastic"
password => "your_password"
index => "your_index_pattern"
ssl => true
cacert => "/path/to/elasticsearch-ca.crt"
}
}
output {
stdout {
codec => rubydebug
}
}
Save the configuration and use the command below to verify whether it has been established correctly:
sudo /usr/share/logstash/bin/logstash --path.settings /etc/logstash
-f
path/to/elasticsearch_logstash.conf --config.test_and_exit
Use Logstash to capture the data from elasticsearch with TLS/SSL :
If you've installed Logstash via a package manager:
sudo /usr/share/logstash/bin/logstash -f
/etc/logstash/conf.d/elasticsearch_logstash.conf
For example : sudo /usr/share/logstash/bin/logstash -f
~/Documents/elasticsearch_logstash.conf
Now Configure the Kibana with elasticsearch TLS/SSL:
Refer to the steps above to configure kibana.yml for Elasticsearch with TLS/SSL encryption.
Open the browser at https://<host_ip>:5601 and visualize the data in Kibana using the instructions above, with options such as bar charts, pie charts, and data views.
In Elasticsearch version 8.17.3, we are using the basic license, so PKI and JWT cannot be used to establish the connection.
To use JWT and PKI authentication, an upgrade to the Platinum license is required.
Using PKI authentication in CrystalMQ:
In PKI authentication, the client certificate and client key are required, while the CA root certificate is optional.
Save the configuration and enable the connector toggle button to connect to Elasticsearch using PKI authentication.
Elasticsearch is now configured with PKI authentication.
If we want to encrypt the data, we can use SSL/TLS with PKI authentication.
To encrypt the data, SSL/TLS can be used along with PKI authentication.
In PKI authentication with SSL/TLS, the client certificate and client key are required, while for SSL-only connections, only the CA root certificate is needed to connect to Elasticsearch.

Using JWT authentication in CrystalMQ:
In JWT (JSON Web Tokens) authentication, the access token is used to connect to Elasticsearch.
Use an authentication provider, such as Keycloak or Google Console, to obtain the access key.
Now, use the access key with the command below to obtain the access token:
curl --cacert /etc/keycloak.crt -X POST
"https://localhost:8443/realms/myrealm/protocol/openid-
connect/token["](https://localhost:8443/realms/myrealm/protocol/openid-
connect/token")
\
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=elasticsearch" \
-d "client_secret=ACCESS_KEY"
In this command, the Keycloak authentication provider is used to obtain the authentication token.
After obtaining the access token, use it in the Elasticsearch data connector to connect to Elasticsearch using JWT authentication.

If we want to encrypt the data, we can use SSL/TLS with PKI authentication.

When using SSL/TLS with JWT, simply upload the CA root certificate to connect to Elasticsearch.