Complete step-by-step walkthrough of the SOCHomeLab server setup — from bare Fedora 42 to a fully operational Wazuh stack with SSL, Filebeat, and OpenSearch.
| Hardware | Intel NUC mini PC |
| OS | Fedora 42 |
| Server IP | 192.168.1.33 — DHCP reservation on router |
| Gateway | 192.168.1.254 |
| Interface | wlp2s0 (WiFi) |
| RAM | 15 GB |
| Workstation | ThinkPad T14 — Fedora 42 — 192.168.1.185 |
cat /etc/fedora-release uname -r
sudo dnf update -y && sudo dnf upgrade -y
Rather than configuring a static IP on the OS side, we used a DHCP reservation on the router. The router always assigns 192.168.1.33 to the NUC based on its MAC address. This is cleaner than OS-level static IP config.
ip a ping google.com -c 4
# Create account with sudo access sudo useradd -m -G wheel katato sudo passwd katato # Verify wheel group membership getent group wheel
sudo dnf install -y openssh-server sudo systemctl enable --now sshd sudo systemctl status sshd
ssh-keygen -t ed25519 -C "katato" ssh-copy-id -p 7389 katato@192.168.1.33
ssh -p 7389 katato@192.168.1.33
Port 7389 PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys MaxAuthTries 3
sudo systemctl restart sshd
Host intelnuc
HostName 192.168.1.33
User katato
Port 7389
Now just type ssh intelnuc to connect from anywhere.
| Port | Service | Purpose |
|---|---|---|
| 7389 | SSH | Remote access — non-default port for security |
| 443 | HTTPS | Wazuh dashboard |
| 1514 | TCP | Wazuh agent communication |
| 1515 | TCP | Wazuh agent registration |
| 9200 | TCP | OpenSearch / Wazuh indexer |
| 55000 | TCP | Wazuh API |
sudo systemctl enable --now firewalld # Custom SSH port sudo firewall-cmd --permanent --add-port=7389/tcp sudo firewall-cmd --permanent --remove-service=ssh # Application ports sudo firewall-cmd --permanent --add-port=443/tcp sudo firewall-cmd --permanent --add-port=1514/tcp sudo firewall-cmd --permanent --add-port=1515/tcp sudo firewall-cmd --permanent --add-port=9200/tcp sudo firewall-cmd --permanent --add-port=55000/tcp # Apply and verify sudo firewall-cmd --reload sudo firewall-cmd --list-all
sudo dnf install -y dnf-automatic sudo nano /etc/dnf/automatic.conf
apply_updates = yes
sudo systemctl enable --now dnf-automatic-install.timer sudo systemctl status dnf-automatic-install.timer
sudo rpm --import https://packages.wazuh.com/key/GPG-KEY-WAZUH sudo tee /etc/yum.repos.d/wazuh.repo << EOF [wazuh] gpgcheck=1 gpgkey=https://packages.wazuh.com/key/GPG-KEY-WAZUH enabled=1 name=Wazuh repository baseurl=https://packages.wazuh.com/4.x/yum/ protect=1 EOF
sudo dnf install -y wazuh-manager sudo systemctl enable --now wazuh-manager sudo dnf install -y wazuh-indexer wazuh-dashboard
Required if the all-in-one installer was interrupted or run on a system with existing Wazuh components.
curl -sO https://packages.wazuh.com/4.9/wazuh-certs-tool.sh
nodes:
indexer:
- name: node-1
ip: "192.168.1.33"
server:
- name: wazuh-1
ip: "192.168.1.33"
dashboard:
- name: dashboard
ip: "192.168.1.33"
sudo bash wazuh-certs-tool.sh -A ls wazuh-certificates/
sudo mkdir -p /etc/wazuh-indexer/certs sudo cp /home/katato/wazuh-certificates/root-ca.pem /etc/wazuh-indexer/certs/ sudo cp /home/katato/wazuh-certificates/node-1.pem /etc/wazuh-indexer/certs/indexer.pem sudo cp /home/katato/wazuh-certificates/node-1-key.pem /etc/wazuh-indexer/certs/indexer-key.pem sudo cp /home/katato/wazuh-certificates/admin.pem /etc/wazuh-indexer/certs/ sudo cp /home/katato/wazuh-certificates/admin-key.pem /etc/wazuh-indexer/certs/ sudo chown -R wazuh-indexer:wazuh-indexer /etc/wazuh-indexer/certs/ sudo chmod 500 /etc/wazuh-indexer/certs/ sudo chmod 400 /etc/wazuh-indexer/certs/*
sudo mkdir -p /etc/wazuh-dashboard/certs sudo cp /home/katato/wazuh-certificates/root-ca.pem /etc/wazuh-dashboard/certs/ sudo cp /home/katato/wazuh-certificates/dashboard.pem /etc/wazuh-dashboard/certs/ sudo cp /home/katato/wazuh-certificates/dashboard-key.pem /etc/wazuh-dashboard/certs/ sudo chown -R wazuh-dashboard:wazuh-dashboard /etc/wazuh-dashboard/certs/ sudo chmod 500 /etc/wazuh-dashboard/certs/ sudo chmod 400 /etc/wazuh-dashboard/certs/*
sudo mkdir -p /etc/filebeat/certs sudo cp /home/katato/wazuh-certificates/root-ca.pem /etc/filebeat/certs/ sudo cp /home/katato/wazuh-certificates/wazuh-1.pem /etc/filebeat/certs/filebeat.pem sudo cp /home/katato/wazuh-certificates/wazuh-1-key.pem /etc/filebeat/certs/filebeat-key.pem sudo chown -R root:root /etc/filebeat/certs/ sudo chmod 500 /etc/filebeat/certs/ sudo chmod 400 /etc/filebeat/certs/*
Start in this exact order — each service depends on the previous:
# 1 — Indexer first sudo systemctl enable --now wazuh-indexer sudo systemctl status wazuh-indexer --no-pager | grep Active # Wait 30 seconds then initialize security sudo /usr/share/wazuh-indexer/bin/indexer-security-init.sh # 2 — Manager sudo systemctl restart wazuh-manager sleep 20 sudo systemctl status wazuh-manager --no-pager | grep Active # 3 — Dashboard last sudo systemctl restart wazuh-dashboard sleep 20 sudo systemctl status wazuh-dashboard --no-pager | grep Active
https://192.168.1.33 in your browser. Accept the self-signed certificate warning — Chrome: Advanced → Proceed · Firefox: Advanced → Accept the Risk
Run this on the ThinkPad, not the NUC:
sudo rpm --import https://packages.wazuh.com/key/GPG-KEY-WAZUH sudo tee /etc/yum.repos.d/wazuh.repo << EOF [wazuh] gpgcheck=1 gpgkey=https://packages.wazuh.com/key/GPG-KEY-WAZUH enabled=1 name=Wazuh repository baseurl=https://packages.wazuh.com/4.x/yum/ protect=1 EOF sudo WAZUH_MANAGER="192.168.1.33" dnf install -y wazuh-agent sudo systemctl enable --now wazuh-agent
sudo /var/ossec/bin/agent_control -l
Filebeat ships Wazuh alerts from log files into OpenSearch.
sudo dnf install -y filebeat sudo curl -so /etc/filebeat/filebeat.yml \ https://packages.wazuh.com/4.9/tpl/wazuh/filebeat/filebeat.yml sudo curl -so /etc/filebeat/wazuh-template.json \ https://raw.githubusercontent.com/wazuh/wazuh/v4.9.2/extensions/elasticsearch/7.x/wazuh-template.json
output.elasticsearch:
hosts: ["192.168.1.33:9200"]
protocol: https
username: "admin"
password: "your_password_here"
ssl.certificate_authorities:
- /etc/filebeat/certs/root-ca.pem
ssl.certificate: "/etc/filebeat/certs/filebeat.pem"
ssl.key: "/etc/filebeat/certs/filebeat-key.pem"
sudo systemctl enable --now filebeat
# Verify alerts are flowing
curl -s -k -u admin:admin \
"https://192.168.1.33:9200/_cat/indices?v" | grep wazuh-alerts
Run this any time to verify all core services are healthy:
echo "=== SERVICES ===" && \ sudo systemctl status wazuh-manager wazuh-indexer wazuh-dashboard \ filebeat --no-pager | grep -E "●|Active" && \ echo "" && \ echo "=== CLUSTER HEALTH ===" && \ curl -s -k -u admin:admin \ "https://192.168.1.33:9200/_cluster/health?pretty" | grep -E "status|number_of_nodes" && \ echo "" && \ echo "=== ALERTS IN OPENSEARCH ===" && \ curl -s -k -u admin:admin \ "https://192.168.1.33:9200/_cat/indices?v" | grep wazuh-alerts && \ echo "" && \ echo "=== AGENT STATUS ===" && \ sudo /var/ossec/bin/agent_control -l
| Service | Expected Status |
|---|---|
| wazuh-manager | active (running) |
| wazuh-indexer | active (running) |
| wazuh-dashboard | active (running) |
| filebeat | active (running) |
| OpenSearch cluster | green or yellow |
| wazuh-alerts index | doc count > 0 |
| ThinkPad T14 agent | Active |
The Wazuh all-in-one installer assumes a clean system. If any Wazuh component is already installed it exits early without generating or placing SSL certificates. The fix is to run wazuh-certs-tool.sh manually and copy each cert file to its correct directory with correct ownership and permissions.
sudo cp -r /etc/wazuh-indexer/certs /etc/wazuh-indexer/certs.bak
The manager config file can become corrupted if edited incorrectly. Always validate XML before restarting. Back up the config before every edit.
sudo python3 -c "
import xml.etree.ElementTree as ET
try:
ET.parse('/var/ossec/etc/ossec.conf')
print('XML is valid')
except ET.ParseError as e:
print(f'XML error: {e}')
"
sudo cp /var/ossec/etc/ossec.conf /var/ossec/etc/ossec.conf.bak
Filebeat failed with x509: certificate is valid for 192.168.1.33, not 127.0.0.1 because the config used 127.0.0.1 as the host but the cert was generated for 192.168.1.33. Always use the actual server IP in Filebeat's output config — never localhost or 127.0.0.1.
Single-node clusters show yellow status because there's no second node to hold replicas. Fix by setting replicas to zero — this turns the index green immediately.
curl -s -k -u admin:admin -X PUT \
"https://192.168.1.33:9200/wazuh-alerts-*/_settings" \
-H 'Content-Type: application/json' \
-d '{"number_of_replicas": 0}'