Setting up secure SIEM stack containers
A ready-to-use, hardened SIEM stack for shelters and crisis centres: Monitors network and endpoints for intrusions, stalkerware, and other abuseware — with pre‑built dashboards and daily threat intel updates.
Features
- Wazuh + Elasticsearch + Kibana SIEM stack
- Zeek & Suricata network monitoring with custom stalkerware rules
- VPN‑only access (WireGuard)
- TLS between all services
- Pre‑set RBAC accounts (admin, viewer)
- Daily rule and intel updates
- Encrypted nightly backups to local 500 GB disk
- Pre‑built Kibana dashboards for:
- Threat overview
- Stalkerware watchlist
- Network anomalies
- High‑risk devices
Requirements
Host system:
- Linux server (Debian 12, Ubuntu 22.04 LTS, Rocky Linux 9 tested)
- Docker + Docker Compose v2
- Minimum:
- CPU: 4 cores (8+ recommended)
- RAM: 8 GB (16 GB recommended)
- Storage: 200 GB SSD for data + separate 500 GB disk for backups
- Dedicated sniffing NIC:
- A second network interface card connected to the network you want to monitor
- Must not have an IP address assigned
- Example:
eth1
on Linux - Can be a USB 3.0 Gigabit Ethernet adapter if no free PCIe slot
- Internet connection (for rule updates, unless using offline feed)
Client devices (for VPN access):
- WireGuard client installed (Windows, macOS, Linux, iOS, or Android)
First‑time setup
1. Clone the repository
git clone https://github.com/ninabarzh/secure-shelter-siem-stack.git
cd secure-shelter-siem-stack
2. Copy and edit environment variables
cp .env.example .env
nano .env
Set secure passwords for:
ELASTIC_PASSWORD
KIBANA_PASSWORD
WAZUH_PASSWORD
3. Start the WireGuard VPN (required)
All access to Kibana, Elasticsearch, and Wazuh is through the VPN — nothing is exposed to the public internet.
From the repo root:
docker-compose up -d vpn
The VPN server listens on UDP/51820.
The default VPN subnet gateway is 10.13.13.1
.
4. Add VPN peers (staff, responders, remote agents)
To add a new peer:
./vpn/add-peer.sh <peer-name>
Example:
./vpn/add-peer.sh alice
This will:
- Create a WireGuard peer named
alice
- Assign it an IP in the VPN subnet
- Save the configuration to
vpn/alice.conf
Send alice.conf
securely to the user — they can import it into the WireGuard client on Windows, macOS, Linux, Android, or iOS.
5. Generate TLS certificates for Elasticsearch
Run:
./scripts/gen-certs.sh
Creates:
config/elasticsearch/certs/elastic-stack-ca.p12
config/elasticsearch/certs/elastic-certificates.p12
Password is set in .env
— change it if you wish.
6. Update detection rules
Fetch latest Suricata rules:
./scripts/update-rules.sh
Sources:
- Emerging Threats (v7.0.3)
- AbuseCH SSL blacklist
- Local
custom.rules
for stalkerware detection
7. Deploy the SIEM stack
./scripts/deploy.sh
Starts:
- Elasticsearch with TLS
- Kibana (imports dashboards from
config/dashboards/
) - Wazuh Manager
- Suricata & Zeek
- Filebeat with TLS to Elasticsearch
8. Access dashboards (via VPN)
Connect to the VPN with your peer config, then open:
http://10.13.13.1:5601
Login:
- Username:
kibana_system
(from.env
) - Password: your
KIBANA_PASSWORD
Dashboards available:
- Threat Overview: alerts across all sources
- High Risk Devices: endpoints with repeated detections
- Network Anomalies: suspicious traffic patterns
- Stalkerware Watchlist: detections for BadBox, mFly, FlexiSpy, Spynger
9. Deploy Wazuh agents
On a monitored endpoint (inside VPN or local network):
curl -so wazuh-agent.deb https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent_4.12.0-1_amd64.deb \
&& sudo WAZUH_MANAGER='10.13.13.1' dpkg -i ./wazuh-agent.deb \
&& sudo systemctl enable wazuh-agent --now
10. Network interface requirements
If using Suricata/Zeek in packet capture mode:
- Set
SNIFFING_INTERFACE
in.env
(e.g.,eth1
) - Put interface in promiscuous mode:
sudo ip link set eth1 promisc on
Ready to monitor, detect, and defend.
Dashboards
After first login, you will see:
- Threat Overview: Summary of all alerts
- Stalkerware Watchlist: Detections for BadBox, BadBox2, mFly, FlexiSpy, Spynger, and others
- Network Anomalies: Suricata/Zeek events outside normal patterns
- High‑risk Devices: Endpoints with multiple stalkerware indicators
Backups
- Run nightly at 02:00
- Encrypted with GPG
- Stored on
/mnt/secure-backup
(500 GB disk) - On first run, generates
config/backup/backup-key.gpg
- Copy the key to a USB stick and lock it away — without it, backups cannot be restored
Restore
gpg --import config/backup/backup-key.gpg
gpg --decrypt /mnt/secure-backup/shelter-siem-YYYY-MM-DD_HH-MM.tar.gz.gpg | tar -xz -C data/
Maintenance
- Stop stack:
./scripts/stop.sh
- Backup data: runs nightly to
/mnt/secure-backup
- Restore backup:
./scripts/restore-backup.sh
Update rules manually
./scripts/update-rules.sh
docker compose restart suricata zeek
Update stack
docker compose pull && docker compose up -d
Security notes
- Change all default passwords in
.env
before deployment - Store VPN peer configs securely
- Keep Elasticsearch TLS certs private
- Monitor disk usage (
./data/elasticsearch
) — prune old indices when needed - All access is via VPN — never expose ports 9200, 5601, 55000 to the internet
- Keep the backup disk physically secure
- Regularly test VPN configs and backups