Contents
Prerequisites
This time, we will install Suricata IDS and ElasticStack on the following server.
・First Server Suricata IDS & Filebeat : Fedora43 IP address(192.168.11.83)
・Second server ElasticStack & kibana : Ubuntu24.04 IP address(192.168.11.85)
Run as a sudo user other than root
Suricata
SURICATA IDS/IPS is an open source IDS that monitors communications on the network and detects suspicious traffic.
The basic mechanism is signature-based, so it can detect predefined unauthorized communications. Suricata is also characterized by its ability to provide protection as well as detection.
1.Preparation
①Activate the EPEL repository on your system
|
1 |
# dnf -y install epel-release |
②System Update
|
1 |
# dnf update -y |
2.Suricata Installation and Configuration
①Suricata install
|
1 2 3 4 5 |
# dnf -y install suricata Version Check # suricata -V This is Suricata version 7.0.12 RELEASE |
②Determine interface and IP address where Suricata will inspect network packets
|
1 2 3 |
# ip --brief add lo UNKNOWN 127.0.0.1/8 ens160 UP 192.168.11.83/24 |
③Edit configuration file
|
1 2 3 4 5 6 7 8 |
# vi /etc/suricata/suricata.yaml # Line 15: In the vars section, define the network. HOME_NET: "[192.168.11.0/24]" # Line 629: Set the interface name for the af-packet section af-packet: - interface: ens160 |
|
1 2 3 4 5 |
# vi /etc/sysconfig/suricata # Line 8: Specify the interface # Add options to be passed to the daemon OPTIONS="-i ens160 --user suricata " |
④Suricata rules update
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# suricata-update ---------------------------------------------- 4/11/2025 -- 09:31:32 - <Info> -- Loaded 62049 rules. 4/11/2025 -- 09:31:32 - <Info> -- Disabled 13 rules. 4/11/2025 -- 09:31:32 - <Info> -- Enabled 0 rules. 4/11/2025 -- 09:31:32 - <Info> -- Modified 0 rules. 4/11/2025 -- 09:31:32 - <Info> -- Dropped 0 rules. 4/11/2025 -- 09:31:32 - <Info> -- Enabled 136 rules for flowbit dependencies. 4/11/2025 -- 09:31:32 - <Info> -- Creating directory /var/lib/suricata/rules. 4/11/2025 -- 09:31:32 - <Info> -- Backing up current rules. 4/11/2025 -- 09:31:32 - <Info> -- Writing rules to /var/lib/suricata/rules/suricata.rules: total: 62049; enabled: 46240; added: 62049; removed 0; modified: 0 4/11/2025 -- 09:31:33 - <Info> -- Writing /var/lib/suricata/rules/classification.config 4/11/2025 -- 09:31:33 - <Info> -- Testing with suricata -T. 4/11/2025 -- 09:32:01 - <Info> -- Done. |
⑤Activate Suricata
|
1 2 |
# systemctl enable --now suricata Created symlink /etc/systemd/system/multiuser.target.wants/suricata.service → /usr/lib/systemd/system/suricata.service. |
⑥Confirm Suricata startup
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# systemctl status suricata ● suricata.service - Suricata Intrusion Detection Service Loaded: loaded (/usr/lib/systemd/system/suricata.service; enabled; preset: disabled) Drop-In: /usr/lib/systemd/system/service.d └─10-timeout-abort.conf Active: active (running) since Tue 2025-11-04 09:32:33 JST; 1min 12s ago Invocation: c68ae1bd155e4b8b9bb065088e628f23 Docs: man:suricata(1) Process: 2139 ExecStartPre=/bin/rm -f /var/run/suricata.pid (code=exited, status=0/SUCCESS) Main PID: 2141 (Suricata-Main) Tasks: 8 (limit: 4532) Memory: 461.6M (peak: 461.6M) CPU: 26.098s CGroup: /system.slice/suricata.service └─2141 /sbin/suricata -c /etc/suricata/suricata.yaml --pidfile /var/run/suricata.pid -i ens160 --us> Nov 04 09:32:33 Lepard systemd[1]: Starting suricata.service - Suricata Intrusion Detection Service... Nov 04 09:32:33 Lepard systemd[1]: Started suricata.service - Suricata Intrusion Detection Service. Nov 04 09:32:33 Lepard suricata[2141]: i: suricata: This is Suricata version 7.0.12 RELEASE running in SYSTEM mo> Nov 04 09:32:59 Lepard suricata[2141]: W: af-packet: ens160: AF_PACKET tpacket-v3 is recommended for non-inline > Nov 04 09:32:59 Lepard suricata[2141]: i: threads: Threads created -> W: 2 FM: 1 FR: 1 Engine started. |
Check Log
|
1 2 3 4 5 6 7 8 9 10 11 |
# tail /var/log/suricata/suricata.log [2141 - Suricata-Main] 2025-11-04 09:32:33 Info: logopenfile: fast output device (regular) initialized: fast.log [2141 - Suricata-Main] 2025-11-04 09:32:33 Info: logopenfile: eve-log output device (regular) initialized: eve.json [2141 - Suricata-Main] 2025-11-04 09:32:33 Info: logopenfile: stats output device (regular) initialized: stats.log [2141 - Suricata-Main] 2025-11-04 09:32:47 Info: detect: 1 rule files processed. 46240 rules successfully loaded, 0 rules failed, 0 [2141 - Suricata-Main] 2025-11-04 09:32:47 Info: threshold-config: Threshold config parsed: 0 rule(s) found [2141 - Suricata-Main] 2025-11-04 09:32:47 Info: detect: 46243 signatures processed. 965 are IP-only rules, 4420 are inspecting packet payload, 40627 inspect application layer, 109 are decoder event only [2141 - Suricata-Main] 2025-11-04 09:32:59 Warning: af-packet: ens160: AF_PACKET tpacket-v3 is recommended for non-inline operation [2141 - Suricata-Main] 2025-11-04 09:32:59 Info: runmodes: ens160: creating 2 threads [2141 - Suricata-Main] 2025-11-04 09:32:59 Info: unix-manager: unix socket '/var/run/suricata/suricata-command.socket' [2141 - Suricata-Main] 2025-11-04 09:32:59 Notice: threads: Threads created -> W: 2 FM: 1 FR: 1 Engine started. |
Check the stats.log file for statistics (updated every 8 seconds by default)
|
1 |
# tail -f /var/log/suricata/stats.log |
A more advanced output, EVE JSON, can be generated with the following command
|
1 |
# tail -f /var/log/suricata/eve.json |
3.Suricata Testing
①Run ping test with curl utility
|
1 2 |
# curl http://testmynids.org/uid/index.html uid=0(root) gid=0(root) groups=0(root) |
②Check the alert log to see if it has been logged
|
1 2 |
# cat /var/log/suricata/fast.log 11/04/2025-09:35:58.545566 [**] [1:2100498:7] GPL ATTACK_RESPONSE id check returned root [**] [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 143.204.80.119:80 -> 192.168.11.83:43710 |
4.Setting Suricata Rules
①Display of rule sets packaged in Suricata
|
1 2 3 4 5 6 |
# ls -al /var/lib/suricata/rules/ total 39644 drwxr-s--- 2 root suricata 57 Nov 4 09:31 . drwxrws--- 4 suricata suricata 33 Nov 4 09:31 .. -rw-r--r-- 1 root suricata 3228 Nov 4 09:31 classification.config -rw-r--r-- 1 root suricata 40590150 Nov 4 09:31 suricata.rules |
②Index list of sources providing rule sets
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# suricata-update list-sources Name: abuse.ch/feodotracker Vendor: Abuse.ch Summary: Abuse.ch Feodo Tracker Botnet C2 IP ruleset License: CC0-1.0 Name: abuse.ch/sslbl-blacklist Vendor: Abuse.ch Summary: Abuse.ch SSL Blacklist License: CC0-1.0 Replaces: sslbl/ssl-fp-blacklist Name: abuse.ch/sslbl-c2 Vendor: Abuse.ch Summary: Abuse.ch Suricata Botnet C2 IP Ruleset License: CC0-1.0 Name: abuse.ch/sslbl-ja3 Vendor: Abuse.ch Summary: Abuse.ch Suricata JA3 Fingerprint Ruleset License: CC0-1.0 Replaces: sslbl/ja3-fingerprints Name: abuse.ch/urlhaus Vendor: abuse.ch Summary: Abuse.ch URLhaus Suricata Rules License: CC0-1.0 Name: aleksibovellan/nmap Vendor: aleksibovellan Summary: Suricata IDS/IPS Detection Rules Against NMAP Scans License: MIT Name: et/open Vendor: Proofpoint Summary: Emerging Threats Open Ruleset License: MIT Name: et/pro Vendor: Proofpoint Summary: Emerging Threats Pro Ruleset License: Commercial Replaces: et/open Parameters: secret-code Subscription: https://www.proofpoint.com/us/threat-insight/et-pro-ruleset Name: etnetera/aggressive Vendor: Etnetera a.s. Summary: Etnetera aggressive IP blacklist License: MIT Name: oisf/trafficid Vendor: OISF Summary: Suricata Traffic ID ruleset License: MIT Name: pawpatrules Vendor: pawpatrules Summary: PAW Patrules is a collection of rules for IDPS / NSM Suricata engine License: CC-BY-SA-4.0 Name: ptrules/open Vendor: Positive Technologies Summary: Positive Technologies Open Ruleset License: Custom Name: scwx/enhanced Vendor: Secureworks Summary: Secureworks suricata-enhanced ruleset License: Commercial Parameters: secret-code Subscription: https://www.secureworks.com/contact/ (Please reference CTU Countermeasures) Name: scwx/malware Vendor: Secureworks Summary: Secureworks suricata-malware ruleset License: Commercial Parameters: secret-code Subscription: https://www.secureworks.com/contact/ (Please reference CTU Countermeasures) Name: scwx/security Vendor: Secureworks Summary: Secureworks suricata-security ruleset License: Commercial Parameters: secret-code Subscription: https://www.secureworks.com/contact/ (Please reference CTU Countermeasures) Name: stamus/lateral Vendor: Stamus Networks Summary: Lateral movement rules License: GPL-3.0-only Name: stamus/nrd-14-open Vendor: Stamus Networks Summary: Newly Registered Domains Open only - 14 day list, complete License: Commercial Parameters: secret-code Subscription: https://www.stamus-networks.com/stamus-labs/subscribe-to-threat-intel-feed Name: stamus/nrd-30-open Vendor: Stamus Networks Summary: Newly Registered Domains Open only - 30 day list, complete License: Commercial Parameters: secret-code Subscription: https://www.stamus-networks.com/stamus-labs/subscribe-to-threat-intel-feed Name: stamus/nrd-entropy-14-open Vendor: Stamus Networks Summary: Newly Registered Domains Open only - 14 day list, high entropy License: Commercial Parameters: secret-code Subscription: https://www.stamus-networks.com/stamus-labs/subscribe-to-threat-intel-feed Name: stamus/nrd-entropy-30-open Vendor: Stamus Networks Summary: Newly Registered Domains Open only - 30 day list, high entropy License: Commercial Parameters: secret-code Subscription: https://www.stamus-networks.com/stamus-labs/subscribe-to-threat-intel-feed Name: stamus/nrd-phishing-14-open Vendor: Stamus Networks Summary: Newly Registered Domains Open only - 14 day list, phishing License: Commercial Parameters: secret-code Subscription: https://www.stamus-networks.com/stamus-labs/subscribe-to-threat-intel-feed Name: stamus/nrd-phishing-30-open Vendor: Stamus Networks Summary: Newly Registered Domains Open only - 30 day list, phishing License: Commercial Parameters: secret-code Subscription: https://www.stamus-networks.com/stamus-labs/subscribe-to-threat-intel-feed Name: tgreen/hunting Vendor: tgreen Summary: Threat hunting rules License: GPLv3 |
③Enable source (if tgreen/hunting is enabled)
|
1 2 3 4 5 6 7 8 9 10 |
# suricata-update enable-source tgreen/hunting 4/11/2025 -- 09:38:38 - <Info> -- Using data-directory /var/lib/suricata. 4/11/2025 -- 09:38:38 - <Info> -- Using Suricata configuration /etc/suricata/suricata.yaml 4/11/2025 -- 09:38:38 - <Info> -- Using /usr/share/suricata/rules for Suricata provided rules. 4/11/2025 -- 09:38:38 - <Info> -- Found Suricata version 7.0.12 at /usr/sbin/suricata. 4/11/2025 -- 09:38:38 - <Warning> -- Source index does not exist, will use bundled one. 4/11/2025 -- 09:38:38 - <Warning> -- Please run suricata-update update-sources. 4/11/2025 -- 09:38:38 - <Info> -- Creating directory /var/lib/suricata/update/sources 4/11/2025 -- 09:38:38 - <Info> -- Enabling default source et/open 4/11/2025 -- 09:38:38 - <Info> -- Source tgreen/hunting enabled |
Perform update
|
1 |
# suricata-update |
Restart Suricata service
|
1 |
# systemctl restart suricata |
5.Creating Suricata Custom Rules
①Create files containing customer rules
|
1 2 3 |
# vi /var/lib/suricata/rules/local.rules Please include the following information: alert icmp any any -> any any (msg:"ICMP Ping"; sid:100000; rev:1;) |
②Edit configuration file (define new rule paths)
|
1 2 3 4 5 6 7 8 |
# vi /etc/suricata/suricata.yaml # Add around line 2224 default-rule-path: /var/lib/suricata/rules rule-files: - suricata.rules - local.rules |
③Testing the configuration file
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# suricata -T -c /etc/suricata/suricata.yaml -v Notice: suricata: This is Suricata version 7.0.12 RELEASE running in SYSTEM mode Info: cpu: CPUs/cores online: 2 Info: suricata: Running suricata under test mode Info: suricata: Setting engine mode to IDS mode by default Info: exception-policy: master exception-policy set to: auto Info: logopenfile: fast output device (regular) initialized: fast.log Info: logopenfile: eve-log output device (regular) initialized: eve.json Info: logopenfile: stats output device (regular) initialized: stats.log Info: detect: 2 rule files processed. 46496 rules successfully loaded, 0 rules failed, 0 Info: threshold-config: Threshold config parsed: 0 rule(s) found Info: detect: 46499 signatures processed. 966 are IP-only rules, 4538 are inspecting packet payload, 40764 inspect application layer, 109 are decoder event only Notice: suricata: Configuration provided was successfully loaded. Exiting. |
Restart Suricat service
|
1 |
# systemctl restart suricata |
④Testing the application of Custom Rules
Ping another device on the same local network to see if it was logged
|
1 2 3 4 |
# cat /var/log/suricata/fast.log 11/04/2025-09:52:00.947463 [**] [1:200000:1] ICMP Ping [**] [Classification: (null)] [Priority: 3] {ICMP} 192.168.11.6:8 -> 192.168.11.83:0 11/04/2025-09:52:00.947535 [**] [1:200000:1] ICMP Ping [**] [Classification: (null)] [Priority: 3] {ICMP} 192.168.11.83:0 -> 192.168.11.6:0 |
To get logs in JSON format, install jq on your system
|
1 |
# dnf install jq |
|
1 |
# systemctl restart suricata |
Execute the following command to ping another device on the same local network
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# tail -f /var/log/suricata/eve.json | jq 'select(.event_type=="alert")' When you run ping, the console displays the following: { "timestamp": "2025-11-04T10:07:52.564692+0900", "flow_id": 173537366066176, "in_iface": "ens160", "event_type": "alert", "src_ip": "192.168.11.6", "dest_ip": "192.168.11.83", "proto": "ICMP", "icmp_type": 8, "icmp_code": 0, "pkt_src": "wire/pcap", "alert": { "action": "allowed", "gid": 1, "signature_id": 100000, "rev": 1, "signature": "ICMP Ping", "category": "", "severity": 3 }, "direction": "to_server", "flow": { "pkts_toserver": 1, "pkts_toclient": 0, "bytes_toserver": 74, "bytes_toclient": 0, "start": "2025-11-04T10:07:52.564692+0900", "src_ip": "192.168.11.6", "dest_ip": "192.168.11.83" } } |
6. Configuring Suricata as an IPS
Configure Suricata to start in IPS mode to drop malicious network traffic.
①Edit the SURICATA configuration file located at /etc/sysconfig/suricata
|
1 2 3 4 5 6 7 |
# vi /etc/sysconfig/suricata Find the line OPTIONS="-i ens160 --user suricata " and add a # at the beginning of the line to comment it out. Next, add the line OPTIONS="-q 0 -vvv --user suricata" to instruct SURICATA to run in IPS mode. . . . # OPTIONS="-i ens160 --user suricata" OPTIONS="-q 0 -vvv --user suricata" |
➁Restart Suricata
|
1 |
# systemctl restart suricata.service |
➂Direct incoming network traffic to Suricata's NFQUEUE
Firewalld is installed and enabled, so add the necessary rules for Suricata to Firewalld.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Add a FORWARD rule so that when the server acts as a gateway for other systems, all that traffic is also sent to SURICATA for processing. # firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 0 -j NFQUEUE # firewall-cmd --permanent --direct --add-rule ipv6 filter FORWARD 0 -j NFQUEUE The last two INPUT and OUTPUT rules send all remaining traffic that is not SSH traffic to Suricata for processing. # firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 1 -j NFQUEUE # firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 1 -j NFQUEUE Do the same for IPv6. # firewall-cmd --permanent --direct --add-rule ipv6 filter INPUT 1 -j NFQUEUE # firewall-cmd --permanent --direct --add-rule ipv6 filter OUTPUT 1 -j NFQUEUE Reload Firewalld # firewall-cmd --reload |
④Verify that SURICATA is correctly dropping traffic.
If there is a rule matching sid:2100498 in /var/lib/suricata/rules/suricata.rules, comment it out and add the rule to /var/lib/suricata/rules/local.rules.
|
1 2 3 |
# vi /var/lib/suricata/rules/local.rules drop ip any any -> any any (msg:"GPL ATTACK_RESPONSE id check returned root"; content:"uid=0|28|root|29|"; classtype:bad-unknown; sid:2100498; rev:7; metadata:created_at 2010_09_23, updated_at 2010_09_23;) |
⑤Suricata Update
|
1 |
# suricata-update |
⑥Test this rule using curl
|
1 2 |
# curl --max-time 5 http://testmynids.org/uid/index.html curl: (28) Operation timed out after 5000 milliseconds with 0 bytes received |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# jq 'select(.alert .signature_id==2100498)' /var/log/suricata/eve.json { "timestamp": "2025-11-04T10:41:13.526043+0900", "flow_id": 506626641592029, "event_type": "alert", "src_ip": "143.204.80.119", "src_port": 80, "dest_ip": "192.168.11.83", "dest_port": 32900, "proto": "TCP", "pkt_src": "wire/pcap", "tx_id": 0, "tx_guessed": true, "alert": { "action": "blocked", "gid": 1, "signature_id": 2100498, "rev": 7, "signature": "GPL ATTACK_RESPONSE id check returned root", "category": "Potentially Bad Traffic", "severity": 2, "metadata": { "created_at": [ "2010_09_23" ], "updated_at": [ "2010_09_23" ] } }, |
"action": "blocked", is set
Elastic stack 9.x Install
Install and configure the Elastic Stack to visualize and search SURICATA logs
This section is primarily performed on a second Ubuntu 24.04 server.
①Install the Elastic Stack 9.x repository signing key
|
1 |
# apt update |
|
1 |
# apt install gnupg2 -y |
|
1 2 |
# wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | \ gpg --dearmor -o /etc/apt/trusted.gpg.d/elastic.gpg |
➁Install the Elastic Stack 9.x repository
|
1 |
# echo "deb https://artifacts.elastic.co/packages/9.x/apt stable main" > /etc/apt/sources.list.d/elastic-9.x.list |
update
|
1 |
# apt update |
➂Installing Elasticsearch 9.x on Ubuntu 24.04
|
1 |
# apt install elasticsearch -y |
During installation, security features are enabled by default;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
--------------------------- Security autoconfiguration information ------------------------------ Authentication and authorization are enabled. TLS for the transport and HTTP layers is enabled and configured. The generated password for the elastic built-in superuser is : mZCL0fKEzs8O7oOK4zYU If this node should join an existing cluster, you can reconfigure this with '/usr/share/elasticsearch/bin/elasticsearch-reconfigure-node --enrollment-token <token-here>' after creating an enrollment token on your existing cluster. You can complete the following actions at any time: Reset the password of the elastic built-in superuser with '/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic'. Generate an enrollment token for Kibana instances with '/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana'. Generate an enrollment token for Elasticsearch nodes with '/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node'. ------------------------------------------------------------------------------------------------- |
Authentication and authorization are enabled.
TLS is enabled and configured at the transport layer and HTTP layer.
An Elastic superuser account (elastic) and its password will be created.
④Configuring Elasticsearch 9.x on Ubuntu
Since this is a basic single-node cluster, we will use the default settings.
Checking the Elasticsearch configuration file /etc/elasticsearch/elasticsearch.yml reveals that security settings are enabled.
|
1 |
# cat /etc/elasticsearch/elasticsearch.yml |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#----------------------- BEGIN SECURITY AUTO CONFIGURATION ----------------------- # # The following settings, TLS certificates, and keys have been automatically # generated to configure Elasticsearch security features on 12-10-2025 06:16:28 # # -------------------------------------------------------------------------------- # Enable security features xpack.security.enabled: true xpack.security.enrollment.enabled: true # Enable encryption for HTTP API client connections, such as Kibana, Logstash, and Agents xpack.security.http.ssl: enabled: true keystore.path: certs/http.p12 # 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: ["Lan"] # 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 #----------------------- END SECURITY AUTO CONFIGURATION ------------------------- |
⑤Starting Elasticsearch
Start Elasticsearch and configure it to run at system startup.
|
1 |
# systemctl daemon-reload |
|
1 2 |
# systemctl enable --now elasticsearch # systemctl start elasticsearch |
Check the status
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# systemctl status elasticsearch ● elasticsearch.service - Elasticsearch Loaded: loaded (/usr/lib/systemd/system/elasticsearch.service; enabled; preset: enabled) Active: active (running) since Sun 2025-10-12 15:21:07 JST; 21s ago Docs: https://www.elastic.co Main PID: 9244 (java) Tasks: 103 (limit: 4548) Memory: 2.3G (peak: 2.3G) CPU: 54.439s CGroup: /system.slice/elasticsearch.service tq9244 /usr/share/elasticsearch/jdk/bin/java -Xms4m -Xmx64m -XX:+UseSerialGC -Dcli.name=server -Dcli.script=/usr/share/elasticsearch/bin/elasticsearch -Dcl> tq9303 /usr/share/elasticsearch/jdk/bin/java -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -XX:+AlwaysPreTouch -Xss1m -Djava.a> mq9323 /usr/share/elasticsearch/modules/x-pack-ml/platform/linux-x86_64/bin/controller Oct 12 15:20:35 Lan systemd[1]: Starting elasticsearch.service - Elasticsearch... Oct 12 15:21:07 Lan systemd[1]: Started elasticsearch.service - Elasticsearch. |
You can also use the curl command to check the status of Elasticsearch. Replace the IP address as appropriate.
|
1 |
# curl https://192.168.11.85:9200 --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic |
When prompted, enter the Elasticsearch password generated during Elasticsearch installation.
The output will appear as follows:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Enter host password for user 'elastic': { "name" : "Lion", "cluster_name" : "elasticsearch", "cluster_uuid" : "xvn64e0VQiSJD3V4GIjYhg", "version" : { "number" : "9.1.5", "build_flavor" : "default", "build_type" : "deb", "build_hash" : "90ee222e7e0136dd8ddbb34015538f3a00c129b7", "build_date" : "2025-10-02T22:07:12.966975992Z", "build_snapshot" : false, "lucene_version" : "10.2.2", "minimum_wire_compatibility_version" : "8.19.0", "minimum_index_compatibility_version" : "8.0.0" }, "tagline" : "You Know, for Search" } |
Also, ensure that both the HTTP port and the transport port are open;
|
1 2 3 4 5 |
# ss -altnp | grep -E "9200|9300" LISTEN 0 4096 0.0.0.0:9200 0.0.0.0:* users:(("java",pid=27019,fd=580)) LISTEN 0 4096 127.0.0.1:9300 0.0.0.0:* users:(("java",pid=27019,fd=578)) |
⑥Resetting Elasticsearch Passwords
The automatically generated Elastic user password is too complex, so reset it using the /usr/share/elasticsearch/bin/elasticsearch-reset-password command.
To reset the password, execute the command.
|
1 |
# /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic -i |
|
1 2 3 4 5 6 7 8 |
This tool will reset the password of the [elastic] user. You will be prompted to enter the password. Please confirm that you would like to continue [y/N]y Enter password for [elastic]: Re-enter password for [elastic]: Password for the [elastic] user successfully reset. |
⑦Elasticsearch Logs
Elasticsearch writes logs to the /var/log/elasticsearch path. The log file you need to check when there is an issue with the Elasticsearch instance is /var/log/elasticsearch/CLUSTER_NAME.log.
CLUSTER_NAME is the value of the cluster.name option in the elasticsearch.yaml file. If this value is not changed, the default is elasticsearch, and the log file will be located at /var/log/elasticsearch/elasticsearch.log.
|
1 |
# tail -f /var/log/elasticsearch/elasticsearch.log |
ログ
|
1 2 3 4 5 6 7 8 9 10 |
[2025-10-12T15:21:13,183][INFO ][o.e.x.i.IndexLifecycleTransition] [Lan] moving index [.ds-.logs-elasticsearch.deprecation-default-2025.10.12-000001] from [{"phase":"hot","action":"unfollow","name":"branch-check-unfollow-prerequisites"}] to [{"phase":"hot","action":"rollover","name":"check-rollover-ready"}] in policy [.deprecation-indexing-ilm-policy] [2025-10-12T15:21:13,222][INFO ][o.e.c.m.MetadataMappingService] [Lan] [.ds-.logs-elasticsearch.deprecation-default-2025.10.12-000001/5KSvPPbdSVCn8_yXs-qaHQ] update_mapping [_doc] [2025-10-12T15:21:18,121][INFO ][o.e.c.m.MetadataCreateIndexService] [Lan] creating index [.ds-ilm-history-7-2025.10.12-000001] in project [default], cause [initialize_data_stream], templates [provided in request], shards [1]/[1] [2025-10-12T15:21:18,122][INFO ][o.e.c.m.MetadataCreateDataStreamService] [Lan] adding data stream [ilm-history-7] with write index [.ds-ilm-history-7-2025.10.12-000001], backing indices [], and aliases [] [2025-10-12T15:21:18,123][INFO ][o.e.c.r.a.AllocationService] [Lan] in project [default] updating number_of_replicas to [0] for indices [.ds-ilm-history-7-2025.10.12-000001] [2025-10-12T15:21:18,234][INFO ][o.e.c.r.a.AllocationService] [Lan] current.health="GREEN" message="Cluster health status changed from [YELLOW] to [GREEN] (reason: [shards started [[.ds-ilm-history-7-2025.10.12-000001][0]]])." previous.health="YELLOW" reason="shards started [[.ds-ilm-history-7-2025.10.12-000001][0]]" [2025-10-12T15:23:59,517][INFO ][o.e.x.s.a.f.FileUserPasswdStore] [Lan] users file [/etc/elasticsearch/users] changed. updating users... [2025-10-12T15:23:59,521][INFO ][o.e.x.s.a.f.FileUserRolesStore] [Lan] users roles file [/etc/elasticsearch/users_roles] changed. updating users roles... [2025-10-12T15:24:19,534][INFO ][o.e.x.s.a.f.FileUserPasswdStore] [Lan] users file [/etc/elasticsearch/users] changed. updating users... [2025-10-12T15:24:19,535][INFO ][o.e.x.s.a.f.FileUserRolesStore] [Lan] users roles file [/etc/elasticsearch/users_roles] changed. updating users roles... |
Kibana 9.x
This section is primarily performed on a second Ubuntu 24.04 server.
①Install
|
1 |
# apt install kibana |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Reading package lists... Done Building dependency tree... Done Reading state information... Done The following NEW packages will be installed: kibana 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 0 B/362 MB of archives. After this operation, 1,137 MB of additional disk space will be used. Selecting previously unselected package kibana. (Reading database ... 129060 files and directories currently installed.) Preparing to unpack .../kibana_9.1.5_amd64.deb ... Unpacking kibana (9.1.5) ... Setting up kibana (9.1.5) ... Creating kibana group... OK Creating kibana user... OK Created Kibana keystore in /etc/kibana/kibana.keystore |
➁Configuring Kibana 9
Kibana is configured by default to run on localhost:5601. To allow external access, edit the configuration file and replace the value of server.host with the interface IP.
|
1 |
# vi /etc/kibana/kibana.yml |
Rewrite as follows:
|
1 2 3 4 5 6 7 8 9 |
# Kibana is served by a back end server. This setting specifies the port to use. # Line 6: Uncomment server.port: 5601 ... # Add around line 12 # To allow connections from remote users, set this parameter to a non-loopback address. #server.host: "localhost" server.host: "192.168.11.85" |
➂Generating a Kibana-Elasticsearch Enrollment Token
To configure a Kibana instance to communicate with an existing Elasticsearch cluster with security enabled, an enrollment token is required. An enrollment token for Kibana can be generated using the following command:
|
1 |
# /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana |
|
1 |
eyJ2ZXIiOiI4LjE0LjAiLCJhZHIiOlsiMTkyLjE2OC4xMS44NTo5MjAwIl0sImZnciI6IjMwYzRiYWNjMjgxZDkzMGY5NzMyMzM5N2Q1ZjUxNTYzYzQyZDk1NTdmNDNlNDIwZjkxMWFjMTgzMjFmMzUwMjciLCJrZXkiOiI1ejVPWDVnQi1hWGhacW92LTR4MDp6VzJrMGNTVW03NEpBQkxSYVduTG13In0= |
④Generating Kibana Encryption Keys
Kibana uses encryption keys in several areas, from encrypting data in Kibana-related indices to storing session information. The required keys are as follows:
xpack.encryptedSavedObjects.encryptionKey:Used to encrypt saved objects such as dashboards and visualizations.xpack.reporting.encryptionKey: Used for encrypting saved reportsxpack.security.encryptionKey: Used for encrypting session information
These are generated using the following command:
|
1 |
# /usr/share/kibana/bin/kibana-encryption-keys generate |
The output will be as follows:
|
1 2 3 4 |
Settings: xpack.encryptedSavedObjects.encryptionKey: 88441050bba328d35b790294b5a3a0c4 xpack.reporting.encryptionKey: 02c4eb1bdef134d38b40a385c1591268 xpack.security.encryptionKey: f8a32f0bbd0885cbe8b6f72609157aac |
Insert the above into Kibana's configuration file kibana.yml.
|
1 2 3 |
# echo -e "xpack.encryptedSavedObjects.encryptionKey: 88441050bba328d35b790294b5a3a0c4 xpack.reporting.encryptionKey: 02c4eb1bdef134d38b40a385c1591268 xpack.security.encryptionKey: f8a32f0bbd0885cbe8b6f72609157aac" >> /etc/kibana/kibana.yml |
⑤Running Kibana
Launch Kibana 9 and configure it to run at system startup.
|
1 2 |
# systemctl enable --now kibana # systemctl start kibana |
status
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# systemctl status kibana ● kibana.service - Kibana Loaded: loaded (/usr/lib/systemd/system/kibana.service; enabled; preset: enabled) Active: active (running) since Sun 2025-10-12 15:33:10 JST; 3min 21s ago Docs: https://www.elastic.co Main PID: 9781 (node) Tasks: 11 (limit: 4548) Memory: 360.1M (peak: 483.7M) CPU: 16.703s CGroup: /system.slice/kibana.service mq9781 /usr/share/kibana/bin/../node/glibc-217/bin/node /usr/share/kibana/bin/../src/cli/dist Oct 12 15:33:12 Lan kibana[9781]: Native global console methods have been overridden in production environment. Oct 12 15:33:18 Lan kibana[9781]: [2025-10-12T15:33:18.305+09:00][INFO ][root] Kibana is starting Oct 12 15:33:18 Lan kibana[9781]: [2025-10-12T15:33:18.348+09:00][INFO ][node] Kibana process configured with roles: [background_tasks, ui] Oct 12 15:33:28 Lan kibana[9781]: [2025-10-12T15:33:27.957+09:00][INFO ][plugins-service] The following plugins are disabled: "cloudChat,cloudExperiments,cloudFullStory> Oct 12 15:33:28 Lan kibana[9781]: [2025-10-12T15:33:28.063+09:00][INFO ][http.server.Preboot] http server running at http://192.168.11.85:5601 Oct 12 15:33:28 Lan kibana[9781]: [2025-10-12T15:33:28.195+09:00][INFO ][plugins-system.preboot] Setting up [1] plugins: [interactiveSetup] Oct 12 15:33:28 Lan kibana[9781]: [2025-10-12T15:33:28.223+09:00][INFO ][preboot] "interactiveSetup" plugin is holding setup: Validating Elasticsearch connection config> Oct 12 15:33:28 Lan kibana[9781]: [2025-10-12T15:33:28.257+09:00][INFO ][root] Holding setup until preboot stage is completed. Oct 12 15:33:35 Lan kibana[9781]: Go to http://192.168.11.85:5601/?code=446458 to get started. |
The following appears toward the end of the output:
|
1 |
Go to http://192.168.11.85:5601/?code=446458 to get started. |
Copy the provided Kibana URL (including the code) and use it in your browser to access Kibana and complete the setup.
Similarly, Kibana logs are available in /var/log/kibana/kibana.log and /var/log/syslog.
⑥Accessing the Kibana 9 Dashboard
accsess to http://192.168.11.85:5601/?code=446458
(Copy each person's appropriate address)
If UFW is running, open the Kibana port.
|
1 2 3 4 |
# ufw allow 5601/tcp Rule added # ufw reload Firewall reloaded |
When you access Kibana 9, the welcome page prompts you to configure Elastic.
First, enter the generated registration token.
Copy the generated Kibana token and paste it into the box.
accsess to http://192.168.11.85:5601/?code=446458

Paste the token, and Kibana will automatically connect to Elasticsearch.
Click Configure Elastic. The settings will be saved, and Elasticsearch will be configured and restarted.

Proceed to the login page. Log in using the generated Elastic user credentials.
Username : elastic
Password : Password regenerated for clarity

On the welcome page, click "Explore on my own" to proceed to the Kibana 9.x dashboard.

Installing Filebeat 9
To collect and monitor logs from Fedora 43 using the ELK Stack, you need to install Filebeat.
This task will be performed on the first server, Fedora 43, with the IP address 192.168.11.83.
①Install Elastic Repos
On Red Hat-based distributions, create a file named elasticsearch.repo in the /etc/yum.repos.d/ directory and include the following configuration:
# vi /etc/yum.repos.d/elasticsearch.repo
[elasticsearch]name=Elasticsearch repository for 9.x packages
baseurl=https://artifacts.elastic.co/packages/9.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=0
type=rpm-md
Install
|
1 |
# dnf install --enablerepo=elasticsearch filebeat |
➁Filebeat Logging Configuration
The default Filebeat configuration file is located at /etc/filebeat/filebeat.yml.
To configure Filebeat to write logs to its own log file, enter the following setting in the configuration file:
|
1 2 3 4 5 6 7 8 9 |
# cat >> /etc/filebeat/filebeat.yml << 'EOL' logging.level: info logging.to_files: true logging.files: path: /var/log/filebeat name: filebeat keepfiles: 7 permissions: 0640 EOL |
➂Connect Filebeat to the data processing system
Configure Filebeat to connect to the data processing system. In this case, it is Elasticsearch.
To send logs directly to Elasticsearch, edit the Filebeat configuration file and update the output configuration section.
Connecting to Elasticsearch 9 requires SSL and authentication.
Verify that you can connect to Elasticsearch's port 9200/tcp (ensure port 9200 is open on the second server beforehand).
|
1 2 3 4 5 6 7 |
# dnf install telnet # telnet 192.168.11.85 9200 Trying 192.168.11.85... Connected to 192.168.11.85. Escape character is '^]'. |
④Creating an Elasticsearch CA Certificate
Download the Elasticsearch CA certificate and save it to any directory (in this case, save it as /etc/filebeat/elastic-ca.crt).
|
1 2 3 |
# openssl s_client -connect 192.168.11.85:9200 \ -showcerts </dev/null 2>/dev/null | \ openssl x509 -outform PEM > /etc/filebeat/elastic-ca.crt |
Retrieve the credentials Filebeat uses for Elasticsearch authentication. In this case, use the credentials for the default superuser, the Elastic user.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# vi /etc/filebeat/filebeat.yml Around line 138, modify the Kibana section as follows (Kibana server and port) #host: "localhost:5601" host: "192.168.11.85:5601" Starting around line 161, modify the Elasticsearch Output section as follows: output.elasticsearch: # Array of hosts to connect to. #hosts: ["localhost:9200"] hosts: ["192.168.11.85:9200"] # Performance preset - one of "balanced", "throughput", "scale", # "latency", or "custom". preset: balanced # Protocol - either `http` (default) or `https`. protocol: "https" ssl.certificate_authorities: ["/etc/filebeat/elastic-ca.crt"] # Authentication credentials - either API key or username/password. #api_key: "id:api_key" username: "elastic" password: "Password" ←Password for Elastic created on the second server |
⑤Configuration File Test
|
1 2 |
# filebeat test config Config OK |
⑥Testing Filebeat's output connection
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# filebeat test output elasticsearch: https://192.168.11.85:9200... parse url... OK connection... parse host... OK dns lookup... OK addresses: 192.168.11.85 dial up... OK TLS... security: server's certificate chain verification is enabled handshake... OK TLS version: TLSv1.3 dial up... OK talk to server... OK version: 9.1.5 |
⑦Enable the Suricata module for Filebeat
Modify modules.d/suricata.yml as follows:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# vi /etc/filebeat/modules.d/suricata.yml # Module: suricata # Docs: https://www.elastic.co/guide/en/beats/filebeat/main/filebeat-module-suricata.html - module: suricata # All logs eve: enabled: true var.paths: ["/var/log/suricata/eve.json"] # Set custom paths for the log files. If left empty, # Filebeat will choose the paths depending on your OS. #var.paths: |
Enable the Suricata module for Filebeat
|
1 |
# filebeat modules enable suricata |
⑧Set up the initial environment
Load SIEM dashboards and pipelines into Elasticsearch
Execute the filebeat setup command
|
1 2 3 4 5 6 |
# filebeat setup -e ---------------------------------------------------------------------------- o","file.line":134},"message":"Elasticsearch pipeline loaded.","service.name":"filebeat","pipeline":"filebeat-9.1.5-suricata-eve-tls","ecs.version":"1.6.0"} {"log.level":"info","@timestamp":"2025-10-13T08:33:02.556+0900","log.logger":"modules","log.origin":{"function":"github.com/elastic/beats/v7/filebeat/fileset.LoadPipeline","file.name":"fileset/pipelines.go","file.line":134},"message":"Elasticsearch pipeline loaded.","service.name":"filebeat","pipeline":"filebeat-9.1.5-suricata-eve-http","ecs.version":"1.6.0"} Loaded Ingest pipelines |
⑨Start the Filebeat service
|
1 |
# systemctl start filebeat.service |
⑩Check in Kibana
Log back into Kibana. http://192.168.11.85:5601
Enter "Suricata Events Overview" in the top search field, then click [Filebeat Suricata]Events Overview.

All Suricata events from the past 15 minutes are displayed.

To display alerts for malicious traffic, click the "Alerts" text next to the Suricata logo.

Create a new user account so you don't need to use the elastic superuser account.
Click the three-line icon in the upper left corner and select [Stack Management] under [Management].

Select "Security" and "Users"

Click the "Create user" button in the upper right corner.

Enter the new user information, assign the kibana_admin, kibana_system, monitoring_user, and editor roles under Privileges, and finally click [Create user].

Log out of the current profile and verify that you can log in with the newly created user account.
