haadi@portfolio:~$ cat wazuh-alert-notifications-shuffle.md
Security research · Detection engineering
Automating Wazuh Alert Notifications Using ShuffleSOAR
A hands-on SIEM and SOAR integration lab: Wazuh detects a real SSH attack, forwards the alert to Shuffle, and an automated email notification fires within seconds: no manual dashboard monitoring required.
A hands-on SIEM and SOAR integration lab: Wazuh detects a real SSH attack, forwards the alert to Shuffle, and an automated email notification fires within seconds: no manual dashboard monitoring required.
Type: Personal Security Lab Project Platform: Azure VM (Ubuntu 22.04) + Docker Submitted: 19 July 2025 | Reference: ARZ-2026-JX9C
📋 Project Overview
Security Information and Event Management (SIEM) tools detect threats but do not act on them automatically. This project bridges that gap by connecting Wazuh (SIEM) to Shuffle (SOAR) through a webhook, so that high-severity alerts trigger automated responses without anyone watching a dashboard.
The working example used throughout is Wazuh Rule 5710: SSH login attempt using a non-existent username: elevated to severity level 10 via a custom local rule and routed through an automated email notification pipeline.
🏗️ Architecture
SSH Attack Attempt
↓
Wazuh Agent (Ubuntu)
detects auth failure
↓
Wazuh Manager
generates Rule 5710 alert (level 10)
↓
Webhook → Shuffle SOAR
↓
Extract rule.id + rule.level
↓
IF rule.level > 9
┌─────┴──────┐
YES NO
↓ ↓
Send Email Ignore
(Gmail SMTP)
🛠️ Environment
| Component | Details |
|---|---|
| Host | Azure VM: Ubuntu Server 22.04 (Standard B2s) |
| SIEM | Wazuh Manager 4.14.6 (Docker) |
| SOAR | Shuffle (Docker: backend, frontend, worker, orborus) |
| Notification | Gmail SMTP via App Password |
| Runtime | Docker + Docker Compose |
Both Wazuh and Shuffle run as Docker containers on the same VM. Wazuh forwards alerts to Shuffle's webhook trigger URL.
⚙️ Shuffle Workflow
The workflow has four stages:
Webhook Trigger
↓
Extract Fields (rule.id, rule.level)
↓
IF rule.level larger than 9
↓
[YES] Send Email via Gmail SMTP
[NO] Drop — no action
Why threshold 10? Low-severity alerts (levels 1 to 9) are operational noise in most environments. Only level 10+ alerts: indicating genuine threats or policy violations: reach an analyst's inbox. This prevents alert fatigue while ensuring critical detections are never missed.
🔔 Alert Used for Testing
| Property | Value |
|---|---|
| Rule ID | 5710 (custom override: 100100) |
| Alert Name | SSH: Attempt to login using a non-existent user |
| Default Level | 5 |
| Custom Level | 10 (via local_rules.xml override) |
| MITRE ATT&CK | T1110.001 (Password Guessing), T1021.004 (Remote Services: SSH) |
| Trigger Command | ssh nonexistentuser@<host-ip> |
Rule 5710 defaults to severity level 5, which would not pass the workflow's
IF condition. A local rule override in /var/ossec/etc/rules/local_rules.xml
raises this specific rule to level 10, allowing the full pipeline to be tested
without changing the workflow logic.
📂 Repository Structure
wazuh-shuffle-soar/
├── README.md
├── config/
│ └── local_rules.xml ← Wazuh custom rule override (level 5 → 10)
├── workflow/
│ └── wazuh-soar-workflow.json ← Exported Shuffle workflow (import-ready)
├── sample-data/
│ └── wazuh-alert-sample.json ← Sample alert JSON payload from Wazuh
└── screenshots/
├── 01-wazuh-endpoint-status.png
├── 02-shuffle-dashboard.png
├── 03-docker-containers-running.png
├── 04-rule-5710-alert-level-10.png
├── 05-complete-shuffle-workflow.png
├── 06-ifelse-routing-condition.png
├── 07-email-notification-received.png
└── 08-successful-workflow-execution.png
🚀 How to Replicate This Lab
Prerequisites
- Ubuntu 22.04 VM (Azure, AWS, local: any works)
- Docker and Docker Compose installed
- A Gmail account with 2FA enabled (needed for App Password)
Step 1: Deploy Wazuh via Docker
git clone https://github.com/wazuh/wazuh-docker.git -b v4.14.6
cd wazuh-docker/single-node
docker-compose up -d
Access the Wazuh dashboard at https://<your-vm-ip> (default credentials
in the Wazuh Docker documentation).
Step 2: Deploy Shuffle via Docker
git clone https://github.com/Shuffle/Shuffle
cd Shuffle
docker-compose up -d
Access Shuffle at http://<your-vm-ip>:3001.
Step 3: Configure Wazuh to Forward Alerts to Shuffle
Add the following to /var/ossec/etc/ossec.conf on the Wazuh manager,
replacing <SHUFFLE_WEBHOOK_URL> with your Shuffle webhook trigger URL:
<integration>
<name>shuffle</name>
<hook_url><SHUFFLE_WEBHOOK_URL></hook_url>
<level>10</level>
<alert_format>json</alert_format>
</integration>
Restart the Wazuh manager:
systemctl restart wazuh-manager
# or inside Docker:
docker restart single-node-wazuh.manager-1
Step 4: Apply the Custom Rule Override
Copy config/local_rules.xml to /var/ossec/etc/rules/local_rules.xml
on the Wazuh manager and restart. This raises Rule 5710 from level 5 to
level 10 so it passes the workflow's severity threshold.
Step 5: Import the Shuffle Workflow
In Shuffle: Workflows → Import → upload workflow/wazuh-soar-workflow.json.
Configure the Email node with your Gmail credentials (use an App Password:
see Step 6).
Step 6: Configure Gmail App Password
Gmail rejects normal account passwords over SMTP. To generate an App Password:
- Google Account → Security → 2-Step Verification → App Passwords
- Generate a password for "Mail" and "Other"
- Use this 16-character password in Shuffle's Email node (not your normal Gmail password)
SMTP settings:
- Host:
smtp.gmail.com - Port:
587 - SSL: enabled
Step 7: Test the Pipeline
Trigger a Rule 5710 alert by attempting SSH with a non-existent username:
ssh nonexistentuser@<your-vm-ip>
Within a few seconds: Wazuh detects → webhook fires → Shuffle evaluates level → email arrives in Gmail inbox.
🔧 Challenges and How They Were Resolved
1. Gmail SMTP rejecting credentials
Initial email tests failed with error 535, 5.7.8 Username and Password not accepted.
Diagnosed by testing SMTP independently outside Shuffle using a Python smtplib
script. Confirmed the issue was Gmail rejecting the normal account password,
not a Shuffle configuration error. Resolved by switching to a Gmail App Password.
2. Rule 5710 default severity too low for the workflow threshold
The default severity of level 5 did not pass the IF condition (level > 9).
Rather than lowering the workflow threshold (which would have made it too noisy
for real use), a local Wazuh rule override was written to raise this specific
rule to level 10. This kept the workflow logic realistic and the test reproducible.
3. Shuffle backend API not immediately reachable after container start
The Shuffle backend container needed a manual restart before its API became
accessible. Resolved with docker restart <container-id>. Subsequent startups
were stable.
📊 Results
| Test | Outcome |
|---|---|
| SSH invalid user attempt detected by Wazuh | ✅ |
| Alert forwarded to Shuffle via webhook | ✅ |
rule.id and rule.level extracted correctly | ✅ |
| IF condition (level > 9) evaluated correctly | ✅ |
| Email notification delivered to Gmail inbox | ✅ |
| End-to-end latency (SSH attempt → email received) | ~5 seconds |
| Workflow execution log: all nodes successful | ✅ |
💡 Key Takeaways
SIEM without SOAR requires constant human attention. Wazuh can detect thousands of events per day. Without automated triage, every alert requires someone to be watching the dashboard. Shuffle removes that dependency for well-understood alert types.
Severity thresholds prevent alert fatigue. The level 10 filter means only genuinely high-priority alerts reach an inbox. Low-level operational noise is silently dropped. This is the foundation of any scalable alert pipeline.
Test components in isolation when debugging. When the email step failed, testing SMTP independently with a Python script immediately isolated the issue to Gmail authentication, not the workflow. Isolating components is faster than debugging the full pipeline end-to-end every time.
Custom Wazuh rules extend built-in detection without modifying core files.
The local_rules.xml override raises a specific rule's severity without
touching Wazuh's default ruleset. This is the correct, upgrade-safe way to
customize Wazuh detection behavior.
🔗 Related Portfolio Repositories
| Repository | Description |
|---|---|
| home-lab-setup | Home lab environment: Kali, Metasploitable, Splunk |
| siem-detection-lab | Splunk detection scenarios and alert analysis |
| security-tools | Hands-on notes for security tools used across labs |
👤 Author
Muhammad Abdul Hadi BS Computer Science: Air University, Islamabad, Pakistan Blue Team Security | Aspiring SOC Analyst
Originally published on GitHub
view-source