Build a SIEM Home Lab with Wazuh
Deploy a Wazuh SIEM stack, enroll an agent, and detect real attacks.
Introduction
30 Second Summary
Every company with an online presence needs a way to detect hackers before they cause damage. Security Operations Center (SOC) analysts use tools called SIEMs to collect logs from across an organization, spot suspicious patterns, and respond to threats in real time.
In this project, you will build your own SIEM home lab using Wazuh, simulate real attacks against a monitored endpoint, triage the alerts in a security dashboard, and document everything in a professional GitHub repository.
What You'll Build
A fully functional SIEM home lab running Wazuh on your Windows machine via Docker, with a monitored agent generating real security alerts that you can investigate and document.
By the end of this project, you'll have:
- A running Wazuh SIEM stack (Manager, Indexer, and Dashboard) deployed locally with Docker.
- A monitored endpoint enrolled as a Wazuh agent, reporting security events back to your SIEM.
- Real security alerts from a simulated brute-force attack and File Integrity Monitoring detections, triaged in the Wazuh dashboard with MITRE ATT&CK mappings.
- Secret Mission: Write a custom Wazuh detection rule that triggers on a specific event pattern and map it to a MITRE ATT&CK technique.
Are there any prerequisites?
No prior security or Docker experience is needed. You will need a Windows machine with at least 8 GB of RAM. This guide walks you through installing every tool from scratch.
Install WSL 2 and Docker Desktop
To run your Wazuh SIEM stack, you need a Linux environment on your Windows machine. Docker containers run Linux-based services, and on Windows, Docker Desktop relies on WSL 2 (Windows Subsystem for Linux) as its backend engine.
In this step, you will enable WSL 2, install Docker Desktop, and configure the system settings that Wazuh needs to run correctly.
In this step, get ready to:
- Enable WSL 2 on your Windows machine.
- Install Docker Desktop with the WSL 2 backend.
- Configure Docker host settings for the Wazuh indexer.
Enable WSL 2 on Windows
WSL 2 gives you a full Linux kernel running inside Windows. Docker Desktop uses this kernel to run Linux containers natively on your machine.
- Press the Windows key to open your search bar.
- Type PowerShell and select Run as administrator from the right side.
- Install WSL 2 by running this command:
wsl --install
What does this command do?
The wsl --install command enables the WSL 2 feature and installs the default Ubuntu distribution on your Windows machine. It handles all the background configuration automatically.
- When the command finishes, restart your computer as prompted.
- After your computer restarts, Ubuntu may open a terminal window asking you to create a username and password. Enter a username and password of your choice. You will use these credentials when running commands with sudo later.
Remember your Ubuntu password
The password you create here is your Linux user password inside WSL 2. You will need it any time you run sudo commands in the upcoming steps.
- Open Windows Terminal by pressing the Windows key, typing Windows Terminal, and pressing Enter.
- Verify WSL 2 is working by running this command:
wsl --version
✔️ I see version information
You should see output showing the WSL version, kernel version, and WSLg version. WSL 2 is ready.
ⓧ I see an error or no output
If you see an error or the command is not recognized, try these fixes:
- Make sure you restarted your computer after running wsl --install.
- Open PowerShell as Administrator and run wsl --install again.
- If you see a message about enabling virtualization, restart your computer and enter BIOS/UEFI settings to enable hardware virtualization (often labeled Intel VT-x or AMD-V).
Install Docker Desktop for Windows
Docker Desktop provides the container runtime that will host all four Wazuh components. It includes Docker Compose, which you will use to start the multi-container Wazuh stack.
- Open your browser and navigate to the Docker Desktop download page:
- https://docs.docker.com/desktop/setup/install/windows-install/
- Click Docker Desktop for Windows - x86_64 to download the installer.
- Double-click Docker Desktop Installer.exe to run the installer.
- When prompted on the Configuration page, ensure Use WSL 2 instead of Hyper-V is checked.
- Follow the remaining prompts and click Close when installation completes.
Why WSL 2 instead of Hyper-V?
WSL 2 uses less memory and starts faster than a full Hyper-V virtual machine. It gives Docker direct access to a real Linux kernel, which is exactly what the Wazuh containers expect.
- Press the Windows key, type Docker Desktop, and press Enter to open it.
- If prompted with the Docker Subscription Service Agreement, click Accept to continue.
- Wait until the bottom-left corner of Docker Desktop shows Engine running (a green indicator). This may take 30-60 seconds on first launch.
Now verify Docker is accessible from your terminal.
- Switch to your Windows Terminal and run these two commands to verify Docker and Docker Compose:
docker --version
docker compose version
✔️ I see version numbers for both
You should see output like Docker version 28.x.x and Docker Compose version v2.x.x. Docker Desktop is ready to go.
ⓧ Command not found or error
If the commands are not recognized, try these fixes:
- Make sure Docker Desktop is open and showing Engine running.
- Close and reopen Windows Terminal so it picks up the new PATH entries Docker added during installation.
- In Docker Desktop, go to Settings then General and confirm Use the WSL 2 based engine is enabled.
Configure the Docker host for Wazuh
The Wazuh indexer (which stores all your security data) needs extra virtual memory mappings to function. Without this setting, the indexer container will crash on startup.
- In Windows Terminal, enter the WSL 2 environment by running:
wsl
Your terminal prompt changes to a Linux-style prompt (e.g. username@DESKTOP:). You are now inside your Ubuntu installation.
- Increase the virtual memory map count by running this command:
sudo sysctl -w vm.max_map_count=262144
What does this setting do?
The vm.max_map_count setting controls how many memory-mapped areas a process can create. The Wazuh indexer maps data files directly into memory for fast searching. The default Linux limit of 65530 is too low, so you raise it to 262144.
This setting resets on WSL restart
The sysctl change does not persist if you restart WSL. If you reboot your machine later and the Wazuh indexer fails to start, run sudo sysctl -w vm.max_map_count=262144 again inside WSL.
- Verify the setting took effect by running:
sysctl vm.max_map_count
You should see vm.max_map_count = 262144 in the output.
- Now install Git inside WSL 2 by running these commands:
sudo apt update && sudo apt install -y git
Why install Git inside WSL 2?
You will clone the Wazuh Docker repository from inside the WSL 2 environment in the next step. Git needs to be installed in this Linux environment, not just on your Windows side.
- Verify Git is installed by running:
git --version
You should see a version number like git version 2.x.x in the output.
Seeing permission denied errors?
If sudo asks for a password, enter the password you created when Ubuntu first launched after the WSL install. If apt update fails with a network error, check that your internet connection is active and try again.
Help me troubleshoot WSL 2 permission or network issues.
Your environment is ready. Next up, you will deploy the full Wazuh SIEM stack using Docker Compose.
Deploy the Wazuh SIEM Stack
Your environment is primed and ready. Now you'll deploy Wazuh, an open-source SIEM platform that monitors endpoints for security threats.
Wazuh runs as three Docker containers working together. The Manager processes security events, the Indexer stores and searches log data, and the Dashboard gives you a visual interface to investigate alerts.
In this step, get ready to:
- Clone the Wazuh Docker repository.
- Generate SSL certificates for secure communication between components.
- Start the Wazuh stack and verify all three containers are healthy.
Clone the Wazuh Docker repository
Wazuh provides an official Docker deployment repository with pre-configured compose files for a single-node stack. You'll clone it at the stable v4.14.5 branch.
- In your WSL 2 terminal, navigate to your home directory and clone the Wazuh Docker repository by running these commands:
cd ~
git clone https://github.com/wazuh/wazuh-docker.git -b v4.14.5
cd wazuh-docker/single-node/
What do these commands do?
- cd ~ moves you to your home directory so the repo lands at ~/wazuh-docker.
- git clone -b v4.14.5 downloads the repository at the stable v4.14.5 release branch. This ensures you get a tested, production-ready version.
- cd wazuh-docker/single-node/ moves into the single-node deployment directory where all the compose files live.
- Confirm you're in the right directory by running:
ls
You should see docker-compose.yml and generate-indexer-certs.yml listed in the output.
Not seeing the expected files?
- Make sure the clone command completed without errors. If you see a "fatal: repository not found" message, check your internet connection and try again.
- Confirm you typed the branch flag correctly: -b v4.14.5 with a lowercase v.
- Verify you ran cd wazuh-docker/single-node/ after cloning. If you're still in ~, the ls output will look different.
Still stuck? Help me troubleshoot the Wazuh Docker clone command failing in WSL 2.
Generate SSL certificates
The Wazuh components communicate over encrypted channels. Before starting the stack, you need to generate self-signed SSL certificates that each container uses to verify the others.
- Generate the SSL certificates by running this command:
docker compose -f generate-indexer-certs.yml run --rm generator
What does this command do?
This spins up a temporary container using the wazuh/wazuh-certs-generator image. It creates certificates for the Manager, Indexer, and Dashboard, then removes itself (--rm).
The certificates land in config/wazuh_indexer_ssl_certs/ inside your current directory. Each Wazuh container mounts these certificates at startup to establish trusted, encrypted connections.
- Confirm the certificates were created by running:
ls config/wazuh_indexer_ssl_certs/
You should see several .pem files listed, including root-ca.pem, wazuh.indexer.pem, and wazuh.manager.pem.
No certificates appeared?
- Make sure Docker Desktop is running. If the engine isn't active, the command can't pull or start containers.
- Check that you're inside the ~/wazuh-docker/single-node/ directory. The command needs generate-indexer-certs.yml in the current folder.
- If you see a permissions error, try running the command with sudo prepended.
Need more help? Help me figure out why the Wazuh certificate generation command failed.
Start the Wazuh stack
With certificates in place, you're ready to launch all three Wazuh containers. Docker Compose will pull the images, create the containers, and wire them together automatically.
- Start the entire Wazuh stack by running:
docker compose up -d
What does this command do?
The -d flag runs the containers in detached mode, meaning they run in the background and free up your terminal. Docker Compose reads the docker-compose.yml file and starts three services: wazuh.manager, wazuh.indexer, and wazuh.dashboard.
The first run pulls several Docker images, which may take a few minutes depending on your internet speed.
- Wait about 1-2 minutes for the containers to initialize, then verify they're running:
docker compose ps
You should see three containers with a status of running:
- single-node-wazuh.manager-1 (the security event processor).
- single-node-wazuh.indexer-1 (the log data store).
- single-node-wazuh.dashboard-1 (the web interface).
- Open your web browser and navigate to https://localhost.
- Your browser will show a security warning about the self-signed certificate. Click **Advanced** and then **Proceed** (or **Accept the Risk** depending on your browser) to continue.
- Log in with username admin and password SecretPassword.
Why the security warning?
The certificates you generated are self-signed, meaning they weren't issued by a publicly trusted authority. Your browser doesn't recognize them and warns you. This is completely normal for a local lab environment.
Dashboard not loading?
- The dashboard depends on the indexer being fully healthy first. If you get a connection error, wait another minute and try again.
- Run docker compose ps and check that all three containers show running status. If the indexer shows starting or unhealthy, it needs more time.
- Verify Docker Desktop is set to use the WSL 2 based engine in **Settings** then **General**.
Still can't access the dashboard? Help me troubleshoot the Wazuh dashboard not loading at https://localhost.
Your SIEM stack is live and monitoring-ready. Next up, you'll enroll an agent so Wazuh has an endpoint to watch over.
Enroll a Wazuh Agent
Your Wazuh SIEM stack is running and ready to receive data. But a SIEM without monitored endpoints is like a security camera with no footage.
In this step, you will deploy a Wazuh agent as a Docker container and connect it to your manager. The agent is the component that lives on a monitored system, collects logs, and reports security events back to the manager for analysis.
In this step, get ready to:
- Deploy the Wazuh agent as a Docker container.
- Verify the agent enrolls and appears as Active in the dashboard.
Find your Docker host IP address
The Wazuh agent needs to know where the manager is. Since both containers run on the same Docker host (your WSL 2 environment), you need the host's internal IP address to connect them.
- Find your WSL 2 host IP address by running this command in your WSL 2 terminal:
hostname -I
What does this command do?
`hostname -I` prints all IP addresses assigned to your WSL 2 instance. The first address in the output is typically the one Docker containers use to communicate with the host.
Write down the first IP address shown (it will look something like `172.x.x.x`). You will use it in the next step.
Configure and deploy the Wazuh agent container
The Wazuh Docker repository includes a pre-built agent deployment in the wazuh-agent/ directory. You need to edit its docker-compose.yml to point the agent at your manager's IP address.
- Navigate to the agent directory by running:
cd ~/wazuh-docker/wazuh-agent/
- Open the docker-compose.yml file in a text editor by running:
nano docker-compose.yml
You should see the following content:
# Wazuh App Copyright (C) 2017, Wazuh Inc. (License GPLv2)
services:
wazuh.agent:
image: wazuh/wazuh-agent:4.14.5
restart: always
environment:
- WAZUH_MANAGER_SERVER=
volumes:
- ./config/wazuh-agent-conf:/wazuh-config-mount/etc/ossec.conf
- Find the line that says WAZUH_MANAGER_SERVER= and add the IP address you noted from hostname -I after the equals sign.
- Your edited line should look like this (with your actual IP):
- WAZUH_MANAGER_SERVER=[[WAZUH_HOST_IP="your WSL IP from hostname -I, e.g. 172.21.0.1"]]
What is WAZUH_MANAGER_SERVER?
This environment variable tells the agent container which IP address to use when connecting to the Wazuh manager. The agent uses this to register itself and start sending security event data.
Since both the manager and agent run as Docker containers on the same WSL 2 host, the host's internal IP lets them communicate over Docker's network.
- Save the file by pressing Ctrl+O then Enter.
- Exit nano by pressing Ctrl+X.
- Start the Wazuh agent container by running:
docker compose up -d
What does this command do?
This pulls the wazuh/wazuh-agent:4.14.5 image (if not already cached) and starts the agent container in detached mode. The agent automatically registers with the manager using the IP you configured.
- Verify the agent container is running:
docker compose ps
You should see one container listed with a status of "Up" or "running".
Container not starting?
- Check that you replaced the blank value after WAZUH_MANAGER_SERVER= with your actual IP address. A blank value means the agent cannot find the manager.
- Confirm your single-node stack is still running. Switch back to the single-node directory with cd ~/wazuh-docker/single-node/ and run docker compose ps to check.
- Make sure you are running docker compose up -d from inside the ~/wazuh-docker/wazuh-agent/ directory, not the single-node directory.
Help me troubleshoot my Wazuh agent container not starting. I edited the docker-compose.yml in the wazuh-agent directory and set WAZUH_MANAGER_SERVER but the container is not running.
Verify agent enrollment in the dashboard
The agent needs a minute or two to register with the manager and start reporting. Now you will confirm it appears in the Wazuh dashboard.
- Open your browser and navigate to https://localhost.
- Accept the self-signed certificate warning if prompted.
- Log in with username admin and password SecretPassword.
- In the left sidebar, click Agent management.
- Click Summary.
- Confirm your agent appears in the list with a status of Active.
What does Active mean?
An Active status means the agent has successfully registered with the manager and is sending data. The manager accepts the agent's enrollment, assigns it an ID, and begins receiving security events from it.
Agent not showing as Active?
- Wait 1-2 minutes after starting the agent container. Registration is not instant.
- Refresh the Agent management > Summary page in your browser.
- Verify the IP address in docker-compose.yml matches the first address output by hostname -I. A mismatched IP means the agent cannot reach the manager.
My Wazuh agent is not showing as Active in the dashboard. How do I debug the connection between the agent and manager containers?
Why is the agent running as a container?
In production, Wazuh agents are typically installed directly on servers, laptops, or VMs so they can monitor the host operating system. For this lab, deploying the agent as a container is faster and keeps everything self-contained.
The tradeoff is that a containerized agent cannot directly access or monitor the host system. It only sees files and processes inside its own container. This is fine for learning SIEM concepts like enrollment, alerting, and FIM.
Your SIEM now has eyes on an endpoint. Next up, you will simulate real attacks against this agent and watch the alerts light up in the dashboard.
Simulate an Attack and Observe Alerts
Your Wazuh agent is enrolled and reporting to the manager. Now it is time to put your SIEM to the test.
In this step, you will simulate two real attack techniques against your monitored agent: file tampering and brute-force authentication. You will then triage the resulting alerts in the Wazuh dashboard and capture evidence for your GitHub documentation.
In this step, get ready to:
- Trigger File Integrity Monitoring (FIM) alerts by modifying files inside the agent container.
- Simulate a brute-force authentication attack that generates repeated failure alerts.
- Triage alerts in the Wazuh dashboard and capture screenshots for your portfolio.
Trigger File Integrity Monitoring (FIM) alerts
File Integrity Monitoring watches critical directories for unauthorized changes. The Wazuh agent's default configuration monitors /etc, /usr/bin, and /usr/sbin using scheduled scans every 12 hours.
To see results quickly, you will create files in a monitored directory and then restart the agent to trigger an immediate scan.
- First, find your agent container's name by running this command in your WSL 2 terminal:
docker ps --filter "ancestor=wazuh/wazuh-agent:4.14.5" --format "{{.Names}}"
What does this command do?
The --filter flag narrows docker ps output to only your Wazuh agent container. The --format flag outputs just the container name, which you will use in the next commands.
- Copy the container name from the output. You will use it in the next commands.
- Open a shell inside the agent container by running this command (replace the container name with yours):
docker exec -it [[AGENT_CONTAINER="your-agent-container-name"]] bash
- Create and modify test files in the monitored /etc/ directory by running these commands inside the container:
# Create a new file in the monitored /etc/ directory
touch /etc/fim-test-file.txt
# Write content to simulate a file modification
echo "This file was tampered with" > /etc/fim-test-file.txt
# Modify an existing file to trigger a modification alert
echo "# unauthorized change" >> /etc/hostname
What does this do?
You are simulating what an attacker might do after gaining access to a system. Creating new files and modifying existing ones in /etc/ is a common technique for establishing persistence or altering system configuration.
The FIM module detects these changes by comparing file checksums against a stored baseline. When the checksums differ, it generates an alert.
- Restart the Wazuh agent service inside the container to trigger an immediate FIM scan:
# Restart the agent to trigger a scan_on_start FIM scan
/var/ossec/bin/wazuh-control restart
Why restart the agent?
The default FIM scan interval is 12 hours. Restarting the agent triggers a fresh scan immediately because scan_on_start is enabled by default. This means you do not have to wait hours to see your alerts.
- Wait about 30 seconds for the scan to complete, then type exit to leave the container shell.
exit
- Switch to your browser and return to the Wazuh dashboard at https://localhost.
- Click on your agent name in the dashboard, then navigate to the File Integrity Monitoring section.
- You should see alerts for new file creation and file modification in the /etc/ directory.
Not seeing FIM alerts yet?
- Give the scan up to 60 seconds to complete and synchronize with the manager.
- Make sure the agent shows as Active in the dashboard. If it shows Disconnected after the restart, wait a few more seconds for it to reconnect.
- Refresh the dashboard page and check again.
Help me troubleshoot missing FIM alerts in my Wazuh dashboard after restarting the agent.
Simulate a brute-force authentication attack
Brute-force attacks are one of the most common threats in the real world. Attackers try many passwords in rapid succession hoping to guess the right one.
Wazuh detects brute-force attempts by correlating multiple authentication failure events. You will simulate this by injecting failed login entries into the agent's authentication log.
- Open a shell inside the agent container again by running:
docker exec -it [[AGENT_CONTAINER="your-agent-container-name"]] bash
- Generate simulated failed SSH login entries by running this script inside the container:
# Simulate 10 failed SSH login attempts from a fake attacker IP
for i in $(seq 1 10); do
echo "$(date '+%b %d %H:%M:%S') localhost sshd[$$]: Failed password for invalid user admin from 192.168.1.100 port 22 ssh2" >> /var/log/auth.log
done
What does this script do?
This loop writes 10 log entries to /var/log/auth.log in the standard syslog format for failed SSH logins. Each entry looks like a different failed attempt from the IP 192.168.1.100.
Wazuh's log collector monitors this file and forwards entries to the manager. The manager's built-in rules (rule group authentication_failures) correlate multiple failures and generate a brute-force alert.
- Wait about 10 seconds for the log collector to pick up the entries, then exit the container:
exit
- Return to the Wazuh dashboard in your browser.
- Navigate to Security events in the left menu.
- You should see authentication failure alerts appearing within a few seconds. Look for alerts mentioning rule IDs like 5710 (login attempt with a non-existent user) or 5712 (brute-force attack detected).
Not seeing brute-force alerts?
- Make sure you ran the script inside the agent container, not in your WSL 2 terminal directly.
- Check that the agent is still Active in the dashboard. If it disconnected during the FIM restart, wait for it to reconnect.
- Try refreshing the Security events page. Log collection happens in near real-time, but the dashboard may need a manual refresh.
Help me debug why brute-force alerts are not showing up in Wazuh after writing to auth.log.
Triage the alerts in the Wazuh dashboard
A real SOC analyst does not just generate alerts. They triage them by severity, investigate the details, and map them to known attack techniques.
- In the Security events view, use the severity filter to show only high-severity alerts (level 10 and above).
- Click on one of the brute-force alerts to expand its details.
- Look for the MITRE ATT&CK section in the alert details. You should see technique T1110 (Brute Force) mapped to this alert.
What is MITRE ATT&CK?
MITRE ATT&CK is a knowledge base of adversary tactics and techniques based on real-world observations. Wazuh automatically maps its alerts to ATT&CK technique IDs, which helps analysts quickly understand what type of attack is happening.
T1110 (Brute Force) means an attacker is trying to gain access by systematically guessing credentials. Seeing this mapping instantly tells you the nature of the threat without reading every log line.
- Take a screenshot of the alert details showing the MITRE ATT&CK mapping (T1110).
- Navigate back to the FIM alerts view and take a screenshot of the file integrity alerts you triggered earlier.
- Take one more screenshot showing the event details of a FIM alert (click to expand one).
Save screenshots for Step 5
Save these screenshots to a folder on your Desktop. You will upload them to your GitHub repository in the next step as evidence of your detection capabilities.
- Confirm you have captured at least three screenshots: FIM alerts, brute-force alerts with MITRE mapping, and an expanded event detail view.
You now have real security alerts with full forensic details and MITRE ATT&CK context. Next up, you will package all of this evidence into a professional GitHub repository that showcases your security operations skills.
Document Your Lab on GitHub
You've generated real security alerts from simulated attacks and captured the evidence in screenshots. Your Wazuh SIEM is detecting threats exactly like a production security operations center would.
Now it's time to turn this hands-on experience into a professional portfolio piece. A well-documented GitHub repository proves to employers that you can deploy, configure, and operate security monitoring tools.
In this step, get ready to:
- Create a GitHub repository for your SIEM home lab.
- Write a README with architecture details and detection evidence.
- Push your documentation to GitHub.
Create a new GitHub repository
You need a public repository on GitHub to showcase your SIEM home lab work. You will create the repository on GitHub's website, then clone it to your WSL environment where you can write the documentation.
- Open your browser and go to github.com.
- Sign in to your GitHub account (or create a free account if you do not have one yet).
- Click the + icon in the top-right corner.
- Select New repository.
- Enter siem-homelab-wazuh as the repository name.
- Add a description: SIEM home lab using Wazuh on Docker with attack simulation and detection evidence.
- Select Public visibility.
- Do NOT check Add a README file. You will create one locally.
- Click Create repository.
Why skip the README checkbox?
Creating the README locally instead of on GitHub avoids merge conflicts when you push. GitHub's Quick Setup page will show you the remote URL you need in the next step.
GitHub will display a Quick Setup page with your repository URL. Keep this page open.
- Switch back to your WSL terminal.
- Create a project folder and initialize it as a Git repository by running these commands:
cd ~
mkdir siem-homelab-wazuh
cd siem-homelab-wazuh
git init -b main
What do these commands do?
- cd ~ moves you to your home directory in WSL.
- mkdir siem-homelab-wazuh creates the folder for your documentation repository.
- git init -b main initializes a new Git repository with main as the default branch name.
- Confirm the folder was created by running:
ls
You should see the siem-homelab-wazuh directory listed.
Git command not found?
If you see an error when running git init, Git may not be installed in your WSL environment. Install it by running sudo apt update && sudo apt install -y git and try again.
Help me troubleshoot my Git installation in WSL.
Write the README with architecture and detection evidence
Your README is the centerpiece of your portfolio repository. It needs to communicate your architecture, the attacks you simulated, and the evidence that your SIEM detected them.
- Create and open the README file by running:
nano README.md
- Paste the following content into the file:
# SIEM Home Lab with Wazuh
## Overview
A fully functional Security Information and Event Management (SIEM) home lab built using Wazuh 4.14.5 on Docker. This project demonstrates core security operations skills including SIEM deployment, endpoint monitoring, attack simulation, and alert triage with MITRE ATT&CK mapping.
## Architecture
The lab runs four Docker containers on Windows via WSL 2:
```
+-----------------------------------------------------+
| Docker Host (WSL 2) |
| |
| +-------------+ +--------------+ +------------+ |
| | Wazuh | | Wazuh | | Wazuh | |
| | Manager |<-| Indexer |<-| Dashboard | |
| | (1514/TCP) | | (9200/TCP) | | (443/HTTPS)| |
| +------^------+ +--------------+ +------------+ |
| | |
| +------+------+ |
| | Wazuh | |
| | Agent | |
| | (Monitored) | |
| +-------------+ |
+-----------------------------------------------------+
```
**Components:**
- **Wazuh Manager** (Port 1514/TCP): Receives and processes events from enrolled agents. Runs detection rules and triggers alerts.
- **Wazuh Indexer** (Port 9200/TCP): Stores and indexes security events for search and analysis.
- **Wazuh Dashboard** (Port 443/HTTPS): Web interface for alert visualization, triage, and MITRE ATT&CK mapping.
- **Wazuh Agent** (Monitored endpoint): Collects logs and system events, reports to the Manager.
## Setup Steps
1. Installed WSL 2 and Docker Desktop on Windows
2. Configured `vm.max_map_count=262144` for the Wazuh Indexer
3. Cloned the Wazuh Docker repository (v4.14.5)
4. Generated SSL certificates for inter-component communication
5. Deployed the single-node stack with `docker compose up -d`
6. Enrolled a Wazuh agent container for endpoint monitoring
## Detection Evidence
### File Integrity Monitoring (FIM)
Triggered FIM alerts by creating and modifying files inside the monitored agent container. The Wazuh dashboard showed real-time alerts for file changes in monitored directories.
### Brute-Force Authentication Attack
Simulated repeated failed authentication attempts. Wazuh detected the pattern using built-in rules for authentication failures and generated alerts mapped to MITRE ATT&CK technique T1110 (Brute Force).
### MITRE ATT&CK Mapping
| Technique ID | Technique Name | Detection Method |
|---|---|---|
| T1110 | Brute Force | Authentication failure pattern detection |
| T1565.001 | Stored Data Manipulation | File Integrity Monitoring |
*Screenshots of alerts and MITRE ATT&CK mappings are available in the screenshots/ directory.*
What does this README cover?
- The Overview section summarizes what you built and why.
- The Architecture section includes a text-based diagram showing how the four containers connect.
- The Setup Steps section lists the key deployment actions you performed.
- The Detection Evidence section documents the attacks you simulated and the MITRE ATT&CK techniques Wazuh mapped them to.
- Save the file by pressing Ctrl+O, then Enter, then Ctrl+X to exit nano.
- Verify the file was created by running:
ls
You should see README.md listed in the output.
Add your screenshots
Create a screenshots/ directory in your repo and add the alert screenshots you captured in the previous step. You can copy them from your Windows filesystem into WSL using the /mnt/c/ path (e.g. cp /mnt/c/Users/YourName/Desktop/screenshot.png screenshots/).
Nano not responding to paste?
Right-click in the Windows Terminal window to paste content into nano. If the formatting looks broken, make sure you copied all lines from the code block above.
Help me paste content into nano in WSL.
Add Skills Demonstrated and push to GitHub
The final section of your README highlights the specific security operations skills this lab demonstrates. This is what hiring managers scan for when reviewing portfolio repositories.
- Reopen the README file by running:
nano README.md
- Scroll to the bottom of the file and add the following section after the Detection Evidence content:
## Skills Demonstrated
- SIEM deployment and configuration (Wazuh 4.14.5 on Docker)
- Endpoint agent enrollment and management
- Log ingestion and analysis
- Attack simulation (brute-force authentication, file tampering)
- Alert triage and investigation
- File Integrity Monitoring (FIM)
- MITRE ATT&CK mapping and technique identification
## License
MIT
Why include a Skills Demonstrated section?
Recruiters and hiring managers often skim README files quickly. A dedicated skills list makes it immediately clear what security operations capabilities you have proven through this project.
- Save and exit nano (Ctrl+O, Enter, Ctrl+X).
- Configure your Git identity by running these commands:
git config user.name "Your Name"
git config user.email "your-email@example.com"
- Replace the name and email with the ones associated with your GitHub account.
- Stage and commit your README by running:
git add .
git commit -m "Add SIEM home lab documentation"
- Connect your local repository to GitHub by adding the remote URL. Copy the HTTPS URL from the Quick Setup page on GitHub, then run:
git remote add origin [[REPO_URL="https://github.com/YOUR-USERNAME/siem-homelab-wazuh.git"]]
- Push your code to GitHub by running:
git push -u origin main
What does this push command do?
- git add . stages all files in the repository.
- git commit saves a snapshot of your staged changes with a message.
- git remote add origin connects your local repo to the GitHub repository.
- git push -u origin main uploads your committed files to GitHub and sets origin/main as the default upstream branch.
Git will prompt you to authenticate. Enter your GitHub username and a personal access token (not your password) when prompted.
Generate a personal access token
GitHub no longer accepts passwords for Git operations over HTTPS. Go to github.com/settings/tokens, click Generate new token (classic), select the repo scope, and use the generated token as your password.
- Open your browser and navigate to your repository at github.com/YOUR-USERNAME/siem-homelab-wazuh.
- Verify that your README renders with the architecture diagram, detection evidence table, and Skills Demonstrated section.
Push rejected or authentication failed?
Make sure you are using a personal access token, not your GitHub password. If the push is rejected because the remote contains work you do not have locally, you may have accidentally initialized the repo with a README on GitHub. Delete the repository on GitHub and recreate it without the README checkbox.
Help me fix my Git push authentication issue.
Secret mission
Write a Custom Detection Rule
You have a working SIEM that detects known attack patterns. But what about threats specific to your environment? In this secret mission, you will write your own custom Wazuh detection rule from scratch, map it to the MITRE ATT&CK framework, and document it in your GitHub repository.
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely on your local machine using Docker containers. There are no ongoing cloud costs. However, the running containers do consume RAM while active, so decide whether to keep them running, pause them, or delete them entirely.
Resources you used:
- Docker containers (Wazuh Manager, Indexer, Dashboard, Agent) running locally.
- Docker volumes storing indexed security data and configuration.
- Cloned repository at ~/wazuh-docker.
- GitHub repository siem-homelab-wazuh.
Keep everything running
No action needed. Choose this if you are still actively experimenting with your SIEM lab, writing more custom rules, or simulating additional attacks.
- Your Wazuh stack continues running and collecting events.
- Docker Desktop must stay open for the containers to remain active.
- The containers consume several GB of RAM while running. Close other heavy applications if your machine feels slow.
Pause - I'll come back to this later
Stop your containers to free up RAM while keeping all data intact in Docker volumes. You can restart anytime.
- Open Windows Terminal and enter the WSL environment by typing wsl.
- Stop the agent container by running these commands:
cd ~/wazuh-docker/wazuh-agent/
docker compose down
- Stop the Wazuh stack containers by running these commands:
cd ~/wazuh-docker/single-node/
docker compose down
Your data persists in Docker volumes. To restart later, run docker compose up -d from each directory.
Delete - I don't want to use this again
Remove all project containers, volumes, and local files. This is permanent and deletes all indexed security data.
- Open Windows Terminal and enter the WSL environment by typing wsl.
- Stop and remove the agent container and its volumes:
cd ~/wazuh-docker/wazuh-agent/
docker compose down -v
- Stop and remove the Wazuh stack containers and all indexed data:
cd ~/wazuh-docker/single-node/
docker compose down -v
- Delete the cloned repository from your local machine:
rm -rf ~/wazuh-docker
- To delete your GitHub repository, go to your siem-homelab-wazuh repository on GitHub.
- Click the Settings tab.
- Scroll down to the Danger Zone section and click Delete this repository.
- Follow the prompts and type the repository name to confirm deletion.
Keep your GitHub repo
Consider keeping the GitHub repository even if you delete everything else. It serves as portfolio evidence of your SIEM skills and costs nothing to host on GitHub.
Nice Work!
Nice Work!
You just built a fully functional SIEM home lab that detects real attacks and documented it professionally on GitHub. That is the core skill set for SOC analyst and security engineer roles.
Here's what you learned:
- Deployed a complete Wazuh SIEM stack (Manager, Indexer, Dashboard) via Docker and enrolled a monitored endpoint as a Wazuh agent.
- Simulated real attacks (brute-force authentication and File Integrity Monitoring tampering), triaged security alerts, and explored MITRE ATT&CK mappings in the dashboard.
- Created a professional GitHub repository documenting your security operations skills with architecture details, detection evidence, and a skills summary.
- Wrote a custom detection rule mapped to a MITRE ATT&CK technique and documented it in your repository.
Ready to quiz yourself?