Deploying a Wazuh Cluster to my home network

Share
Deploying a Wazuh Cluster to my home network

Deploying this was the equivalent of more staff than customers. On a quick side note, writing this was like looking back on things that have come and gone because the razer decided to give up again. Meaning you guessed it...time to rebuild it all over again...

Throughout my jobs I have had to deal with a fair amount of SOC alerts as well as deploy and maintain SIEM/SOC environments for different clients. Obviously that led me onto start seeing if I could deploy one to my home environment.

High Level Cluster Architecture for an environment that barely has 20 devices

Creating the environemnt

Deploying the management nodes

Wazuh does not specify exact hardware requirements, but it is recommended to have a server with at least a few CPU cores, 8 GB of RAM, and sufficient disk space to handle log data. The 100GB on my nodes is excessive, however, speaking from experience, the last thing I want to deal with is my SIEM environment locking up due to insufficient storage. We are using LXC containers instead of VM's because it allows for a lightweight deployment for Wazuh instead of the added bloat of running a normal version of Ubuntu desktop.

A rough indication for the specification of both nodes.

ComponentRecommended Specifications for my lightweight environment
CPU4 Cores or more
RAM8 GB or more
Storage50GB or more
Network1 Gbps or higher

Successful creation of the management node

The same process can be followed for the other management node if you wish to do this on Proxmox

Deploying WAZ-INDEX-01

![[Pasted image 20251119175649.png]]

Deploying WAZ-SIEM-01

Pre-Wazuh Configuration Steps

The SSH Mishap

Configuring proxmox ssh configuration within my internal network, but then going down a rabbit hole and configuring a shared network drive, because at the time, I could not work out the issue, but it turned out to be the reoccuring theme on this project, firewall rules. Whilst that was not working, I went down the rabbit hole of creating a shared network drive that both nodes could access. This was the alternative I did instead of trying to sort out ssh and intern scp so I could grab the wazuh files from an NFS drive instead.

Just as I was about to get on with the next part of bringing all my nodes together, my mesh wifi decided to go on strike and stop working, typical Sunday evening. This is becoming more of a journal at this point, someone wasn't looking at what they were rebooting and typed reboot on the main node...

waz-mgt-01 - 192.168.50.185
waz-mgt-02 - 192.168.50.189
waz-index-01 - 192.168.50.120
waz-index-02 - 192.168.50.186
waz-siem-01 - 192.168.50.49

nodes:

# Wazuh indexer nodes

indexer:

- name: waz-index-01

ip: "<INDEXER-01-IP>"

- name: waz-index-02

ip: "<INDEXER-02-IP>"

#- name: node-3

# ip: "<indexer-node-ip>"

  

# Wazuh server nodes

# If there is more than one Wazuh server

# node, each one must have a node_type

server:

- name: waz-mgt-01

ip: "<MANAGER-01-IP>"

node_type: master

- name: waz-mgt-02

ip: "<MANAGER-02-IP>"

node_type: worker

#- name: wazuh-3

# ip: "<wazuh-manager-ip>"

# node_type: worker

  

# Wazuh dashboard nodes

dashboard:

- name: waz-siem-01

ip: "<DASHBOARD-IP>"

initialising the nodes in the cluster -

root@WAZ-INDEX-01:~# tar -axf wazuh-install-files.tar wazuh-install-files/wazuh-passwords.txt -O | grep -P "\'admin\'" -A 1
  indexer_username: 'admin'
  indexer_password: 'REDACTED'
root@WAZ-INDEX-01:~# ip a | grep 192
    inet 192.168.50.120/24 brd 192.168.50.255 scope global eth0

Ensuring the indexer cluster exists

root@WAZ-INDEX-01:~# curl -k -u admin https://<INDEXER-01-IP>:9200
Enter host password for user 'admin':
{
  "name" : "WAZ-INDEX-01",
  "cluster_name" : "wazuh-indexer-cluster",
  "cluster_uuid" : "REDACTED",
  "version" : {
    "number" : "7.10.2",
    "build_type" : "deb",
    "build_hash" : "REDACTED",
    "build_date" : "2025-11-08T12:00:46.843930578Z",
    "build_snapshot" : false,
    "lucene_version" : "9.12.2",
    "minimum_wire_compatibility_version" : "7.10.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "The OpenSearch Project: https://opensearch.org/"
}

Ensuring the nodes are communicating with each other

root@WAZ-INDEX-01:~# curl -k -u admin https://<INDEXER-01-IP>:9200/_cat/nodes?v
Enter host password for user 'admin':
Unauthorizedroot@WAZ-INDEX-01:~# curl -k -u admin https://<INDEXER-01-IP>:9200/_cat/nodes?v
Enter host password for user 'admin':
ip             heap.percent ram.percent cpu load_1m load_5m load_15m node.role node.roles                               cluster_manager name
192.168.50.186           63          75   2    0.39    0.33     0.28 dimr      data,ingest,master,remote_cluster_client -               WAZ-INDEX-02
192.168.50.120           25          57   0    0.27    0.33     0.34 dimr      data,ingest,master,remote_cluster_client *               WAZ-INDEX-01
root@WAZ-INDEX-01:~# 

The same process is replciated for WAZ-INDEX-02

root@WAZ-INDEX-02:~# ip a | grep 192
    inet 192.168.50.186/24 brd 192.168.50.255 scope global eth0
root@WAZ-INDEX-02:~# tar -axf wazuh-install-files.tar wazuh-install-files/wazuh-passwords.txt -O | grep -P "\'admin\'" -A 1
  indexer_username: 'REDACTED'
  indexer_password: 'REDACTED'
root@WAZ-INDEX-02:~# curl -k -u admin https://<INDEXER-02-IP>:9200
Enter host password for user 'admin':
{
  "name" : "WAZ-INDEX-02",
  "cluster_name" : "wazuh-indexer-cluster",
  "cluster_uuid" : "REDACTED",
  "version" : {
    "number" : "7.10.2",
    "build_type" : "deb",
    "build_hash" : "REDACTED",
    "build_date" : "2025-11-08T12:00:46.843930578Z",
    "build_snapshot" : false,
    "lucene_version" : "9.12.2",
    "minimum_wire_compatibility_version" : "7.10.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "The OpenSearch Project: https://opensearch.org/"
}
root@WAZ-INDEX-02:~# curl -k -u admin https://<INDEXER-02-IP>:9200/_cat/nodes?v
Enter host password for user 'admin':
ip             heap.percent ram.percent cpu load_1m load_5m load_15m node.role node.roles                               cluster_manager name
192.168.50.120           24          57   0    0.14    0.31     0.34 dimr      data,ingest,master,remote_cluster_client *               WAZ-INDEX-01
192.168.50.186           62          75   2    0.30    0.31     0.27 dimr      data,ingest,master,remote_cluster_client -               WAZ-INDEX-02
root@WAZ-INDEX-02:~# 

WAZ-SIEM-01 (dashboard output)

root@WAZ-SIEM-01:~# bash wazuh-install.sh -v --wazuh-dashboard WAZ-SIEM-01
09/12/2025 16:59:57 DEBUG: Checking root permissions.

Reading package lists...
09/12/2025 17:00:02 INFO: --- Dependencies ----
09/12/2025 17:00:02 INFO: Installing gawk.

Created symlink /etc/systemd/system/multi-user.target.wants/wazuh-dashboard.service -> /etc/systemd/system/wazuh-dashboard.service.

09/12/2025 17:01:27 INFO: --- Summary ---
09/12/2025 17:01:27 INFO: You can access the web interface https://<DASHBOARD-IP>:443
    User: 'REDACTED'
    Password:  'REDACTED'
09/12/2025 17:01:31 DEBUG: Restoring Wazuh repository.
09/12/2025 17:01:31 INFO: Installation finished.
root@WAZ-SIEM-01:~# 

The usual security risk will appear when first going to your wazuh dashboard address, this is fine, and to save the hassle in the future, you can add the certificate to your browser which will mitigate the security risk from appearing again. ![[Pasted image 20251209170539.png]]

![[Pasted image 20251209170602.png]]

Here is me thinking it would be easy, however.... ![[Pasted image 20251209170834.png]]

![[Pasted image 20251209220632.png]]

INFO: No current API selected 
INFO: Getting API hosts... 
INFO: API hosts found: 1 
INFO: Checking API host id [default]... 
INFO: Could not connect to API id [default]: timeout of 20000ms exceeded 
INFO: Removed [navigate] cookie 
ERROR: No API available to connect

After looking around, the issue that was staring at me straight in the face was that I had forgot to configure the firewall rules that would allow all of the nodes to communicate with each other, so after running the following commands on the management node, Wazuh was up an running on my home environment. All it took was a couple of firewall changes on the main nodes, and allowing the ports so they can communicate with each other and it was all up and running. However, for some reason I wanted to throw a spanner in the works.

ComponentPortProtocolPurpose
Wazuh server1514TCP (default)Agent connection service
Wazuh server1514UDP (optional)Agent connection service (disabled by default)
Wazuh server1515TCPAgent enrollment service
Wazuh server1516TCPWazuh cluster daemon
Wazuh server514UDP (default)Wazuh Syslog collector (disabled by default)
Wazuh server514TCP (optional)Wazuh Syslog collector (disabled by default)
Wazuh server55000TCPWazuh server RESTful API
Wazuh indexer9200TCPWazuh indexer RESTful API
Wazuh indexer9300–9400TCPWazuh indexer cluster communication
Wazuh dashboard443TCPWazuh web user interface

Losing the drive

Someone thought it was a good idea to move the laptop and in the process of doing so knock the usb‑c m.2 enclosure off the desk. This meant one of the indexers went offline due to its disk file being on there... whilst it was running. This began to lock up the proxmox environment and causing both nodes to go offline. However, after re‑mounting the shared disk, restarting the node, the cluster recovered.

5. YAML Cluster Configuration

nodes:

  indexer:
  - name: Civic-01
    ip: "<INDEXER-01-IP>"
  - name: Porsche-02
    ip: "<INDEXER-02-IP>"

  server:
  - name: Mustang-01
    ip: "<MANAGER-01-IP>"
    node_type: master
  - name: Camry-02
    ip: "<MANAGER-02-IP>"
    node_type: worker

  dashboard:
  - name: Accord-01
    ip: "<DASHBOARD-IP>"

Common Pitfalls & Fixes

IssueFix
Dashboard SSL warningImport the self‑signed cert to browser trust store
API time‑outsEnsure all firewall ports are open
Node “offline” after USB‑C removalRe‑mount the shared disk, restart the node
Agent not reportingVerify firewall and correct IP in agent.conf

Summary of Results

  • Management nodes: 2 (Mustang‑01, Camry‑02) – act as master/worker.
  • Indexer nodes: 2 (Civic‑01, Porsche‑02) – cluster of 2 for high‑availability.
  • Dashboard: 1 (Accord‑01) – secure HTTPS UI.
  • Agents: A handful of laptops/servers (no sensitive names shown).
Takeaway – a home‑lab SIEM can be as lightweight as 5 nodes while still providing all core functionality (logging, correlation, dashboards).

All personal passwords, user names, and any other strings that could reveal confidential configuration have been replaced with REDACTED or generic placeholders. Feel free to substitute the placeholders with your actual values when deploying in your environment.